#include <cstring>
+#include <cstdlib>
#include <sys/un.h>
#include <sys/socket.h>
event_loop.get_time(restart_interval_time, clock_type::MONOTONIC);
restart_interval_count = 0;
- if (start_ps_process(exec_arg_parts, onstart_flags.starts_on_console)) {
+ if (start_ps_process(exec_arg_parts,
+ onstart_flags.starts_on_console || onstart_flags.shares_console)) {
// Note: we don't set a start timeout for PROCESS services.
if (start_timeout != time_val(0,0) && get_type() != service_type_t::PROCESS) {
restart_timer.arm_timer_rel(event_loop, start_timeout);
}
if (forkpid == 0) {
- run_child_proc(cmd.data(), logfile, on_console, pipefd[1], control_socket[1], socket_fd,
- run_as_uid, run_as_gid);
+ const char * working_dir_c = nullptr;
+ if (! working_dir.empty()) working_dir_c = working_dir.c_str();
+ run_child_proc(cmd.data(), working_dir_c, logfile, on_console, pipefd[1], control_socket[1],
+ socket_fd, run_as_uid, run_as_gid);
}
else {
// Parent process
base_process_service::base_process_service(service_set *sset, string name,
service_type_t service_type_p, string &&command,
- std::list<std::pair<unsigned,unsigned>> &command_offsets,
+ const std::list<std::pair<unsigned,unsigned>> &command_offsets,
const std::list<prelim_dep> &deplist_p)
: service_record(sset, name, service_type_p, deplist_p), child_listener(this),
child_status_listener(this), restart_timer(this)
reserved_child_watch = false;
tracking_child = false;
stop_timer_armed = false;
- start_is_interruptible = false;
}
void base_process_service::do_restart() noexcept
}
}
- if (! start_ps_process(exec_arg_parts, have_console)) {
+ if (! start_ps_process(exec_arg_parts, have_console || onstart_flags.shares_console)) {
restarting = false;
if (service_state == service_state_t::STARTING) {
failed_to_start();
else {
log(loglevel_t::WARN, "Interrupting start of service ", get_name(), " with pid ", pid, " (with SIGINT).");
kill_pg(SIGINT);
+
if (stop_timeout != time_val(0,0)) {
restart_timer.arm_timer_rel(event_loop, stop_timeout);
stop_timer_armed = true;
restart_timer.stop_timer(event_loop);
stop_timer_armed = false;
}
+
set_state(service_state_t::STOPPING);
- notify_listeners(service_event_t::STARTCANCELLED);
return false;
}
}
void base_process_service::kill_pg(int signo) noexcept
{
- pid_t pgid = bp_sys::getpgid(pid);
- if (pgid == -1) {
- // only should happen if pid is invalid, which should never happen...
- log(loglevel_t::ERROR, get_name(), ": can't signal process: ", strerror(errno));
- return;
+ if (onstart_flags.signal_process_only) {
+ bp_sys::kill(pid, signo);
+ }
+ else {
+ pid_t pgid = bp_sys::getpgid(pid);
+ if (pgid == -1) {
+ // only should happen if pid is invalid, which should never happen...
+ log(loglevel_t::ERROR, get_name(), ": can't signal process: ", strerror(errno));
+ return;
+ }
+ bp_sys::kill(-pgid, signo);
}
- bp_sys::kill(-pgid, signo);
}
void base_process_service::timer_expired() noexcept
}
else if (pid != -1) {
// Starting, start timed out.
- stop_dependents();
- if (start_explicit) {
- start_explicit = false;
- release();
- }
+ log(loglevel_t::WARN, "Service ", get_name(), " with pid ", pid, " exceeded allowed start time; cancelling.");
interrupt_start();
+ stop_reason = stopped_reason_t::TIMEDOUT;
+ failed_to_start(false, false);
}
else {
// STARTING / STARTED, and we have a pid: must be restarting (smooth recovery if STARTED)
}
forced_stop();
stop_dependents();
- stopped();
}
void base_process_service::becoming_inactive() noexcept