2 * A rewrite of the original Debian's start-stop-daemon Perl script
3 * in C (faster - it is executed many times during system startup).
5 * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
6 * public domain. Based conceptually on start-stop-daemon.pl, by Ian
7 * Jackson <ijackson@gnu.ai.mit.edu>. May be used and distributed
8 * freely for any purpose. Changes by Christian Schwarz
9 * <schwarz@monet.m.isar.de>, to make output conform to the Debian
10 * Console Message Standard, also placed in public domain. Minor
11 * changes by Klee Dienes <klee@debian.org>, also placed in the Public
14 * Changes by Ben Collins <bcollins@debian.org>, added --chuid, --background
15 * and --make-pidfile options, placed in public domain as well.
17 * Port to OpenBSD by Sontri Tomo Huynh <huynh.29@osu.edu>
18 * and Andreas Schuldei <andreas@schuldei.org>
20 * Changes by Ian Jackson: added --retry (and associated rearrangements).
26 #include <dpkg/macros.h>
30 #elif defined(__GNU__)
34 #elif defined(OPENBSD) || defined(__OpenBSD__)
38 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
40 #elif defined(__NetBSD__)
42 #elif defined(__DragonFly__)
43 # define OSDragonFlyBSD
45 # error Unknown architecture - cannot build start-stop-daemon
48 #ifdef HAVE_SYS_PARAM_H
49 #include <sys/param.h>
51 #ifdef HAVE_SYS_SYSCALL_H
52 #include <sys/syscall.h>
54 #ifdef HAVE_SYS_SYSCTL_H
55 #include <sys/sysctl.h>
57 #ifdef HAVE_SYS_PROC_H
60 #ifdef HAVE_SYS_USER_H
63 #ifdef HAVE_SYS_PSTAT_H
64 #include <sys/pstat.h>
66 #include <sys/types.h>
70 #include <sys/select.h>
71 #include <sys/ioctl.h>
108 #if defined(OSFreeBSD)
109 #define KVM_MEMFILE "/dev/null"
111 #define KVM_MEMFILE NULL
115 #ifdef _POSIX_PRIORITY_SCHEDULING
118 #define SCHED_OTHER -1
119 #define SCHED_FIFO -1
124 /* This comes from TASK_COMM_LEN defined in Linux' include/linux/sched.h. */
125 #define PROCESS_NAME_SIZE 15
126 #elif defined(OSsunos)
127 #define PROCESS_NAME_SIZE 15
128 #elif defined(OSDarwin)
129 #define PROCESS_NAME_SIZE 16
130 #elif defined(OSNetBSD)
131 #define PROCESS_NAME_SIZE 16
132 #elif defined(OSOpenBSD)
133 #define PROCESS_NAME_SIZE 16
134 #elif defined(OSFreeBSD)
135 #define PROCESS_NAME_SIZE 19
136 #elif defined(OSDragonFlyBSD)
137 /* On DragonFlyBSD MAXCOMLEN expands to 16. */
138 #define PROCESS_NAME_SIZE MAXCOMLEN
141 #if defined(SYS_ioprio_set) && defined(linux)
142 #define HAVE_IOPRIO_SET
145 #define IOPRIO_CLASS_SHIFT 13
146 #define IOPRIO_PRIO_VALUE(class, prio) (((class) << IOPRIO_CLASS_SHIFT) | (prio))
147 #define IO_SCHED_PRIO_MIN 0
148 #define IO_SCHED_PRIO_MAX 7
151 IOPRIO_WHO_PROCESS
= 1,
170 /* Time conversion constants. */
172 NANOSEC_IN_SEC
= 1000000000L,
173 NANOSEC_IN_MILLISEC
= 1000000L,
174 NANOSEC_IN_MICROSEC
= 1000L,
177 /* The minimum polling interval, 20ms. */
178 static const long MIN_POLL_INTERVAL
= 20 * NANOSEC_IN_MILLISEC
;
180 static enum action_code action
;
181 static bool testmode
= false;
182 static int quietmode
= 0;
183 static int exitnodo
= 1;
184 static bool background
= false;
185 static bool close_io
= true;
186 static bool mpidfile
= false;
187 static bool rpidfile
= false;
188 static int signal_nr
= SIGTERM
;
189 static int user_id
= -1;
190 static int runas_uid
= -1;
191 static int runas_gid
= -1;
192 static const char *userspec
= NULL
;
193 static char *changeuser
= NULL
;
194 static const char *changegroup
= NULL
;
195 static char *changeroot
= NULL
;
196 static const char *changedir
= "/";
197 static const char *cmdname
= NULL
;
198 static char *execname
= NULL
;
199 static char *startas
= NULL
;
200 static pid_t match_pid
= -1;
201 static pid_t match_ppid
= -1;
202 static const char *pidfile
= NULL
;
203 static char what_stop
[1024];
204 static const char *progname
= "";
205 static int nicelevel
= 0;
206 static int umask_value
= -1;
208 static struct stat exec_stat
;
210 static struct proc_stat_list
*procset
= NULL
;
213 /* LSB Init Script process status exit codes. */
216 STATUS_DEAD_PIDFILE
= 1,
217 STATUS_DEAD_LOCKFILE
= 2,
223 struct pid_list
*next
;
227 static struct pid_list
*found
= NULL
;
228 static struct pid_list
*killed
= NULL
;
230 /* Resource scheduling policy. */
231 struct res_schedule
{
232 const char *policy_name
;
237 struct schedule_item
{
242 /* Only seen within parse_schedule and callees. */
245 /* Seconds, signal no., or index into array. */
249 static struct res_schedule
*proc_sched
= NULL
;
250 static struct res_schedule
*io_sched
= NULL
;
252 static int schedule_length
;
253 static struct schedule_item
*schedule
= NULL
;
256 static void DPKG_ATTR_PRINTF(1)
257 warning(const char *format
, ...)
261 fprintf(stderr
, "%s: warning: ", progname
);
262 va_start(arglist
, format
);
263 vfprintf(stderr
, format
, arglist
);
267 static void DPKG_ATTR_NORET
DPKG_ATTR_PRINTF(1)
268 fatal(const char *format
, ...)
271 int errno_fatal
= errno
;
273 fprintf(stderr
, "%s: ", progname
);
274 va_start(arglist
, format
);
275 vfprintf(stderr
, format
, arglist
);
278 fprintf(stderr
, " (%s)\n", strerror(errno_fatal
));
280 fprintf(stderr
, "\n");
282 if (action
== ACTION_STATUS
)
283 exit(STATUS_UNKNOWN
);
296 fatal("malloc(%d) failed", size
);
300 xstrndup(const char *str
, size_t n
)
304 new_str
= strndup(str
, n
);
307 fatal("strndup(%s, %zu) failed", str
, n
);
311 timespec_gettime(struct timespec
*ts
)
313 #if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && \
314 defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK > 0
315 if (clock_gettime(CLOCK_MONOTONIC
, ts
) < 0)
316 fatal("clock_gettime failed");
320 if (gettimeofday(&tv
, NULL
) != 0)
321 fatal("gettimeofday failed");
323 ts
->tv_sec
= tv
.tv_sec
;
324 ts
->tv_nsec
= tv
.tv_usec
* NANOSEC_IN_MICROSEC
;
328 #define timespec_cmp(a, b, OP) \
329 (((a)->tv_sec == (b)->tv_sec) ? \
330 ((a)->tv_nsec OP (b)->tv_nsec) : \
331 ((a)->tv_sec OP (b)->tv_sec))
334 timespec_sub(struct timespec
*a
, struct timespec
*b
, struct timespec
*res
)
336 res
->tv_sec
= a
->tv_sec
- b
->tv_sec
;
337 res
->tv_nsec
= a
->tv_nsec
- b
->tv_nsec
;
338 if (res
->tv_nsec
< 0) {
340 res
->tv_nsec
+= NANOSEC_IN_SEC
;
345 timespec_mul(struct timespec
*a
, int b
)
347 long nsec
= a
->tv_nsec
* b
;
350 a
->tv_sec
+= nsec
/ NANOSEC_IN_SEC
;
351 a
->tv_nsec
= nsec
% NANOSEC_IN_SEC
;
355 newpath(const char *dirname
, const char *filename
)
360 path_len
= strlen(dirname
) + 1 + strlen(filename
) + 1;
361 path
= xmalloc(path_len
);
362 snprintf(path
, path_len
, "%s/%s", dirname
, filename
);
368 get_open_fd_max(void)
370 #ifdef HAVE_GETDTABLESIZE
371 return getdtablesize();
373 return sysconf(_SC_OPEN_MAX
);
379 detach_controlling_tty(void)
381 #ifdef HAVE_TIOCNOTTY
384 tty_fd
= open("/dev/tty", O_RDWR
);
386 /* The current process does not have a controlling tty. */
390 if (ioctl(tty_fd
, TIOCNOTTY
, 0) != 0)
391 fatal("unable to detach controlling tty");
400 if (setpgid(0, 0) < 0)
403 detach_controlling_tty();
410 wait_for_child(pid_t pid
)
416 child
= waitpid(pid
, &status
, 0);
417 } while (child
== -1 && errno
== EINTR
);
420 fatal("error waiting for child");
422 if (WIFEXITED(status
)) {
423 int err
= WEXITSTATUS(status
);
426 fatal("child returned error exit status %d", err
);
427 } else if (WIFSIGNALED(status
)) {
428 int signo
= WTERMSIG(status
);
430 fatal("child was killed by signal %d", signo
);
432 fatal("unexpected status %d waiting for child", status
);
437 write_pidfile(const char *filename
, pid_t pid
)
442 fd
= open(filename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_NOFOLLOW
, 0666);
446 fp
= fdopen(fd
, "w");
449 fatal("unable to open pidfile '%s' for writing", filename
);
451 fprintf(fp
, "%d\n", pid
);
454 fatal("unable to close pidfile '%s'", filename
);
458 remove_pidfile(const char *filename
)
460 if (unlink(filename
) < 0 && errno
!= ENOENT
)
461 fatal("cannot remove pidfile '%s'", filename
);
472 printf("Detaching to start %s...", startas
);
474 /* Block SIGCHLD to allow waiting for the child process while it is
475 * performing actions, such as creating a pidfile. */
477 sigaddset(&mask
, SIGCHLD
);
478 if (sigprocmask(SIG_BLOCK
, &mask
, &oldmask
) == -1)
479 fatal("cannot block SIGCHLD");
483 fatal("unable to do first fork");
484 else if (pid
) { /* First Parent. */
485 /* Wait for the second parent to exit, so that if we need to
486 * perform any actions there, like creating a pidfile, we do
487 * not suffer from race conditions on return. */
493 /* Create a new session. */
495 fatal("cannot set session ID");
499 fatal("unable to do second fork");
500 else if (pid
) { /* Second parent. */
501 /* Set a default umask for dumb programs, which might get
502 * overridden by the --umask option later on, so that we get
503 * a defined umask when creating the pidfille. */
506 if (mpidfile
&& pidfile
!= NULL
)
507 /* User wants _us_ to make the pidfile. */
508 write_pidfile(pidfile
, pid
);
513 if (sigprocmask(SIG_SETMASK
, &oldmask
, NULL
) == -1)
514 fatal("cannot restore signal mask");
521 pid_list_push(struct pid_list
**list
, pid_t pid
)
525 p
= xmalloc(sizeof(*p
));
532 pid_list_free(struct pid_list
**list
)
534 struct pid_list
*here
, *next
;
536 for (here
= *list
; here
!= NULL
; here
= next
) {
548 "Usage: start-stop-daemon [<option> ...] <command>\n"
551 " -S|--start -- <argument> ... start a program and pass <arguments> to it\n"
552 " -K|--stop stop a program\n"
553 " -T|--status get the program status\n"
554 " -H|--help print help information\n"
555 " -V|--version print version\n"
557 "Matching options (at least one is required):\n"
558 " --pid <pid> pid to check\n"
559 " --ppid <ppid> parent pid to check\n"
560 " -p|--pidfile <pid-file> pid file to check\n"
561 " -x|--exec <executable> program to start/check if it is running\n"
562 " -n|--name <process-name> process name to check\n"
563 " -u|--user <username|uid> process owner to check\n"
566 " -g|--group <group|gid> run process as this group\n"
567 " -c|--chuid <name|uid[:group|gid]>\n"
568 " change to this user/group before starting\n"
570 " -s|--signal <signal> signal to send (default TERM)\n"
571 " -a|--startas <pathname> program to start (default is <executable>)\n"
572 " -r|--chroot <directory> chroot to <directory> before starting\n"
573 " -d|--chdir <directory> change to <directory> (default is /)\n"
574 " -N|--nicelevel <incr> add incr to the process' nice level\n"
575 " -P|--procsched <policy[:prio]>\n"
576 " use <policy> with <prio> for the kernel\n"
577 " process scheduler (default prio is 0)\n"
578 " -I|--iosched <class[:prio]> use <class> with <prio> to set the IO\n"
579 " scheduler (default prio is 4)\n"
580 " -k|--umask <mask> change the umask to <mask> before starting\n"
581 " -b|--background force the process to detach\n"
582 " -C|--no-close do not close any file descriptor\n"
583 " -m|--make-pidfile create the pidfile before starting\n"
584 " |--remove-pidfile delete the pidfile after stopping\n"
585 " -R|--retry <schedule> check whether processes die, and retry\n"
586 " -t|--test test mode, don't do anything\n"
587 " -o|--oknodo exit status 0 (not 1) if nothing done\n"
588 " -q|--quiet be more quiet\n"
589 " -v|--verbose be more verbose\n"
591 "Retry <schedule> is <item>|/<item>/... where <item> is one of\n"
592 " -<signal-num>|[-]<signal-name> send that signal\n"
593 " <timeout> wait that many seconds\n"
594 " forever repeat remainder forever\n"
595 "or <schedule> may be just <timeout>, meaning <signal>/<timeout>/KILL/<timeout>\n"
597 "The process scheduler <policy> can be one of:\n"
598 " other, fifo or rr\n"
600 "The IO scheduler <class> can be one of:\n"
601 " real-time, best-effort or idle\n"
605 " 1 = nothing done (=> 0 if --oknodo)\n"
606 " 2 = with --retry, processes would not die\n"
608 "Exit status with --status:\n"
609 " 0 = program is running\n"
610 " 1 = program is not running and the pid file exists\n"
611 " 3 = program is not running\n"
612 " 4 = unable to determine status\n");
618 printf("start-stop-daemon %s for Debian\n\n", VERSION
);
620 printf("Written by Marek Michalkiewicz, public domain.\n");
623 static void DPKG_ATTR_NORET
624 badusage(const char *msg
)
627 fprintf(stderr
, "%s: %s\n", progname
, msg
);
628 fprintf(stderr
, "Try '%s --help' for more information.\n", progname
);
630 if (action
== ACTION_STATUS
)
631 exit(STATUS_UNKNOWN
);
641 static const struct sigpair siglist
[] = {
664 parse_unsigned(const char *string
, int base
, int *value_r
)
673 value
= strtol(string
, &endptr
, base
);
674 if (string
== endptr
|| *endptr
!= '\0' || errno
!= 0)
676 if (value
< 0 || value
> INT_MAX
)
684 parse_pid(const char *pid_str
, int *pid_num
)
686 if (parse_unsigned(pid_str
, 10, pid_num
) != 0)
695 parse_signal(const char *sig_str
, int *sig_num
)
699 if (parse_unsigned(sig_str
, 10, sig_num
) == 0)
702 for (i
= 0; i
< array_count(siglist
); i
++) {
703 if (strcmp(sig_str
, siglist
[i
].name
) == 0) {
704 *sig_num
= siglist
[i
].signal
;
712 parse_umask(const char *string
, int *value_r
)
714 return parse_unsigned(string
, 0, value_r
);
718 validate_proc_schedule(void)
720 #ifdef _POSIX_PRIORITY_SCHEDULING
721 int prio_min
, prio_max
;
723 prio_min
= sched_get_priority_min(proc_sched
->policy
);
724 prio_max
= sched_get_priority_max(proc_sched
->policy
);
726 if (proc_sched
->priority
< prio_min
)
727 badusage("process scheduler priority less than min");
728 if (proc_sched
->priority
> prio_max
)
729 badusage("process scheduler priority greater than max");
734 parse_proc_schedule(const char *string
)
740 policy_len
= strcspn(string
, ":");
741 policy_str
= xstrndup(string
, policy_len
);
743 if (string
[policy_len
] == ':' &&
744 parse_unsigned(string
+ policy_len
+ 1, 10, &prio
) != 0)
745 fatal("invalid process scheduler priority");
747 proc_sched
= xmalloc(sizeof(*proc_sched
));
748 proc_sched
->policy_name
= policy_str
;
750 if (strcmp(policy_str
, "other") == 0) {
751 proc_sched
->policy
= SCHED_OTHER
;
752 proc_sched
->priority
= 0;
753 } else if (strcmp(policy_str
, "fifo") == 0) {
754 proc_sched
->policy
= SCHED_FIFO
;
755 proc_sched
->priority
= prio
;
756 } else if (strcmp(policy_str
, "rr") == 0) {
757 proc_sched
->policy
= SCHED_RR
;
758 proc_sched
->priority
= prio
;
760 badusage("invalid process scheduler policy");
762 validate_proc_schedule();
766 parse_io_schedule(const char *string
)
772 class_len
= strcspn(string
, ":");
773 class_str
= xstrndup(string
, class_len
);
775 if (string
[class_len
] == ':' &&
776 parse_unsigned(string
+ class_len
+ 1, 10, &prio
) != 0)
777 fatal("invalid IO scheduler priority");
779 io_sched
= xmalloc(sizeof(*io_sched
));
780 io_sched
->policy_name
= class_str
;
782 if (strcmp(class_str
, "real-time") == 0) {
783 io_sched
->policy
= IOPRIO_CLASS_RT
;
784 io_sched
->priority
= prio
;
785 } else if (strcmp(class_str
, "best-effort") == 0) {
786 io_sched
->policy
= IOPRIO_CLASS_BE
;
787 io_sched
->priority
= prio
;
788 } else if (strcmp(class_str
, "idle") == 0) {
789 io_sched
->policy
= IOPRIO_CLASS_IDLE
;
790 io_sched
->priority
= 7;
792 badusage("invalid IO scheduler policy");
794 if (io_sched
->priority
< IO_SCHED_PRIO_MIN
)
795 badusage("IO scheduler priority less than min");
796 if (io_sched
->priority
> IO_SCHED_PRIO_MAX
)
797 badusage("IO scheduler priority greater than max");
801 set_proc_schedule(struct res_schedule
*sched
)
803 #ifdef _POSIX_PRIORITY_SCHEDULING
804 struct sched_param param
;
806 param
.sched_priority
= sched
->priority
;
808 if (sched_setscheduler(getpid(), sched
->policy
, ¶m
) == -1)
809 fatal("unable to set process scheduler");
813 #ifdef HAVE_IOPRIO_SET
815 ioprio_set(int which
, int who
, int ioprio
)
817 return syscall(SYS_ioprio_set
, which
, who
, ioprio
);
822 set_io_schedule(struct res_schedule
*sched
)
824 #ifdef HAVE_IOPRIO_SET
827 io_sched_mask
= IOPRIO_PRIO_VALUE(sched
->policy
, sched
->priority
);
828 if (ioprio_set(IOPRIO_WHO_PROCESS
, getpid(), io_sched_mask
) == -1)
829 warning("unable to alter IO priority to mask %i (%s)\n",
830 io_sched_mask
, strerror(errno
));
835 parse_schedule_item(const char *string
, struct schedule_item
*item
)
837 const char *after_hyph
;
839 if (strcmp(string
, "forever") == 0) {
840 item
->type
= sched_forever
;
841 } else if (isdigit(string
[0])) {
842 item
->type
= sched_timeout
;
843 if (parse_unsigned(string
, 10, &item
->value
) != 0)
844 badusage("invalid timeout value in schedule");
845 } else if ((after_hyph
= string
+ (string
[0] == '-')) &&
846 parse_signal(after_hyph
, &item
->value
) == 0) {
847 item
->type
= sched_signal
;
849 badusage("invalid schedule item (must be [-]<signal-name>, "
850 "-<signal-number>, <timeout> or 'forever'");
855 parse_schedule(const char *schedule_str
)
863 for (slash
= schedule_str
; *slash
; slash
++)
867 schedule_length
= (count
== 0) ? 4 : count
+ 1;
868 schedule
= xmalloc(sizeof(*schedule
) * schedule_length
);
871 schedule
[0].type
= sched_signal
;
872 schedule
[0].value
= signal_nr
;
873 parse_schedule_item(schedule_str
, &schedule
[1]);
874 if (schedule
[1].type
!= sched_timeout
) {
875 badusage("--retry takes timeout, or schedule list"
876 " of at least two items");
878 schedule
[2].type
= sched_signal
;
879 schedule
[2].value
= SIGKILL
;
880 schedule
[3] = schedule
[1];
884 while (schedule_str
!= NULL
) {
885 slash
= strchr(schedule_str
, '/');
886 str_len
= slash
? (size_t)(slash
- schedule_str
) : strlen(schedule_str
);
887 if (str_len
>= sizeof(item_buf
))
888 badusage("invalid schedule item: far too long"
889 " (you must delimit items with slashes)");
890 memcpy(item_buf
, schedule_str
, str_len
);
891 item_buf
[str_len
] = '\0';
892 schedule_str
= slash
? slash
+ 1 : NULL
;
894 parse_schedule_item(item_buf
, &schedule
[count
]);
895 if (schedule
[count
].type
== sched_forever
) {
897 badusage("invalid schedule: 'forever'"
898 " appears more than once");
904 if (repeatat
== count
)
905 badusage("invalid schedule: 'forever' appears last, "
906 "nothing to repeat");
908 schedule
[count
].type
= sched_goto
;
909 schedule
[count
].value
= repeatat
;
912 assert(count
== schedule_length
);
917 set_action(enum action_code new_action
)
919 if (action
== new_action
)
922 if (action
!= ACTION_NONE
)
923 badusage("only one command can be specified");
930 #define OPT_RM_PIDFILE 502
933 parse_options(int argc
, char * const *argv
)
935 static struct option longopts
[] = {
936 { "help", 0, NULL
, 'H'},
937 { "stop", 0, NULL
, 'K'},
938 { "start", 0, NULL
, 'S'},
939 { "status", 0, NULL
, 'T'},
940 { "version", 0, NULL
, 'V'},
941 { "startas", 1, NULL
, 'a'},
942 { "name", 1, NULL
, 'n'},
943 { "oknodo", 0, NULL
, 'o'},
944 { "pid", 1, NULL
, OPT_PID
},
945 { "ppid", 1, NULL
, OPT_PPID
},
946 { "pidfile", 1, NULL
, 'p'},
947 { "quiet", 0, NULL
, 'q'},
948 { "signal", 1, NULL
, 's'},
949 { "test", 0, NULL
, 't'},
950 { "user", 1, NULL
, 'u'},
951 { "group", 1, NULL
, 'g'},
952 { "chroot", 1, NULL
, 'r'},
953 { "verbose", 0, NULL
, 'v'},
954 { "exec", 1, NULL
, 'x'},
955 { "chuid", 1, NULL
, 'c'},
956 { "nicelevel", 1, NULL
, 'N'},
957 { "procsched", 1, NULL
, 'P'},
958 { "iosched", 1, NULL
, 'I'},
959 { "umask", 1, NULL
, 'k'},
960 { "background", 0, NULL
, 'b'},
961 { "no-close", 0, NULL
, 'C'},
962 { "make-pidfile", 0, NULL
, 'm'},
963 { "remove-pidfile", 0, NULL
, OPT_RM_PIDFILE
},
964 { "retry", 1, NULL
, 'R'},
965 { "chdir", 1, NULL
, 'd'},
968 const char *pid_str
= NULL
;
969 const char *ppid_str
= NULL
;
970 const char *umask_str
= NULL
;
971 const char *signal_str
= NULL
;
972 const char *schedule_str
= NULL
;
973 const char *proc_schedule_str
= NULL
;
974 const char *io_schedule_str
= NULL
;
975 size_t changeuser_len
;
979 c
= getopt_long(argc
, argv
,
980 "HKSVTa:n:op:qr:s:tu:vx:c:N:P:I:k:bCmR:g:d:",
985 case 'H': /* --help */
988 case 'K': /* --stop */
989 set_action(ACTION_STOP
);
991 case 'S': /* --start */
992 set_action(ACTION_START
);
994 case 'T': /* --status */
995 set_action(ACTION_STATUS
);
997 case 'V': /* --version */
1000 case 'a': /* --startas <pathname> */
1003 case 'n': /* --name <process-name> */
1006 case 'o': /* --oknodo */
1009 case OPT_PID
: /* --pid <pid> */
1012 case OPT_PPID
: /* --ppid <ppid> */
1015 case 'p': /* --pidfile <pid-file> */
1018 case 'q': /* --quiet */
1021 case 's': /* --signal <signal> */
1022 signal_str
= optarg
;
1024 case 't': /* --test */
1027 case 'u': /* --user <username>|<uid> */
1030 case 'v': /* --verbose */
1033 case 'x': /* --exec <executable> */
1036 case 'c': /* --chuid <username>|<uid> */
1037 /* We copy the string just in case we need the
1038 * argument later. */
1039 changeuser_len
= strcspn(optarg
, ":");
1040 changeuser
= xstrndup(optarg
, changeuser_len
);
1041 if (optarg
[changeuser_len
] == ':') {
1042 if (optarg
[changeuser_len
+ 1] == '\0')
1043 fatal("missing group name");
1044 changegroup
= optarg
+ changeuser_len
+ 1;
1047 case 'g': /* --group <group>|<gid> */
1048 changegroup
= optarg
;
1050 case 'r': /* --chroot /new/root */
1051 changeroot
= optarg
;
1053 case 'N': /* --nice */
1054 nicelevel
= atoi(optarg
);
1056 case 'P': /* --procsched */
1057 proc_schedule_str
= optarg
;
1059 case 'I': /* --iosched */
1060 io_schedule_str
= optarg
;
1062 case 'k': /* --umask <mask> */
1065 case 'b': /* --background */
1068 case 'C': /* --no-close */
1071 case 'm': /* --make-pidfile */
1074 case OPT_RM_PIDFILE
: /* --remove-pidfile */
1077 case 'R': /* --retry <schedule>|<timeout> */
1078 schedule_str
= optarg
;
1080 case 'd': /* --chdir /new/dir */
1084 /* Message printed by getopt. */
1089 if (pid_str
!= NULL
) {
1090 if (parse_pid(pid_str
, &match_pid
) != 0)
1091 badusage("pid value must be a number greater than 0");
1094 if (ppid_str
!= NULL
) {
1095 if (parse_pid(ppid_str
, &match_ppid
) != 0)
1096 badusage("ppid value must be a number greater than 0");
1099 if (signal_str
!= NULL
) {
1100 if (parse_signal(signal_str
, &signal_nr
) != 0)
1101 badusage("signal value must be numeric or name"
1102 " of signal (KILL, INT, ...)");
1105 if (schedule_str
!= NULL
) {
1106 parse_schedule(schedule_str
);
1109 if (proc_schedule_str
!= NULL
)
1110 parse_proc_schedule(proc_schedule_str
);
1112 if (io_schedule_str
!= NULL
)
1113 parse_io_schedule(io_schedule_str
);
1115 if (umask_str
!= NULL
) {
1116 if (parse_umask(umask_str
, &umask_value
) != 0)
1117 badusage("umask value must be a positive number");
1120 if (action
== ACTION_NONE
)
1121 badusage("need one of --start or --stop or --status");
1123 if (!execname
&& !pid_str
&& !ppid_str
&& !pidfile
&& !userspec
&&
1125 badusage("need at least one of --exec, --pid, --ppid, --pidfile, --user or --name");
1127 #ifdef PROCESS_NAME_SIZE
1128 if (cmdname
&& strlen(cmdname
) > PROCESS_NAME_SIZE
)
1129 warning("this system is not able to track process names\n"
1130 "longer than %d characters, please use --exec "
1131 "instead of --name.\n", PROCESS_NAME_SIZE
);
1137 if (action
== ACTION_START
&& !startas
)
1138 badusage("--start needs --exec or --startas");
1140 if (mpidfile
&& pidfile
== NULL
)
1141 badusage("--make-pidfile requires --pidfile");
1142 if (rpidfile
&& pidfile
== NULL
)
1143 badusage("--remove-pidfile requires --pidfile");
1145 if (pid_str
&& pidfile
)
1146 badusage("need either --pid of --pidfile, not both");
1148 if (background
&& action
!= ACTION_START
)
1149 badusage("--background is only relevant with --start");
1151 if (!close_io
&& !background
)
1152 badusage("--no-close is only relevant with --background");
1161 /* If it's a relative path, normalize it. */
1162 if (execname
[0] != '/')
1163 execname
= newpath(changedir
, execname
);
1166 fullexecname
= newpath(changeroot
, execname
);
1168 fullexecname
= execname
;
1170 if (stat(fullexecname
, &exec_stat
))
1171 fatal("unable to stat %s", fullexecname
);
1173 if (fullexecname
!= execname
)
1177 if (userspec
&& sscanf(userspec
, "%d", &user_id
) != 1) {
1180 pw
= getpwnam(userspec
);
1182 fatal("user '%s' not found", userspec
);
1184 user_id
= pw
->pw_uid
;
1187 if (changegroup
&& sscanf(changegroup
, "%d", &runas_gid
) != 1) {
1190 gr
= getgrnam(changegroup
);
1192 fatal("group '%s' not found", changegroup
);
1193 changegroup
= gr
->gr_name
;
1194 runas_gid
= gr
->gr_gid
;
1200 if (sscanf(changeuser
, "%d", &runas_uid
) == 1)
1201 pw
= getpwuid(runas_uid
);
1203 pw
= getpwnam(changeuser
);
1205 fatal("user '%s' not found", changeuser
);
1206 changeuser
= pw
->pw_name
;
1207 runas_uid
= pw
->pw_uid
;
1208 if (changegroup
== NULL
) {
1209 /* Pass the default group of this user. */
1210 changegroup
= ""; /* Just empty. */
1211 runas_gid
= pw
->pw_gid
;
1213 if (stat(pw
->pw_dir
, &st
) == 0)
1214 setenv("HOME", pw
->pw_dir
, 1);
1218 #if defined(OSLinux)
1220 proc_status_field(pid_t pid
, const char *field
)
1222 static char *line
= NULL
;
1223 static size_t line_size
= 0;
1229 size_t field_len
= strlen(field
);
1231 sprintf(filename
, "/proc/%d/status", pid
);
1232 fp
= fopen(filename
, "r");
1235 while ((line_len
= getline(&line
, &line_size
, fp
)) >= 0) {
1236 if (strncasecmp(line
, field
, field_len
) == 0) {
1237 line
[line_len
- 1] = '\0';
1239 value
= line
+ field_len
;
1240 while (isspace(*value
))
1256 struct ps_context
*context
;
1259 err
= ps_context_create(getproc(), &context
);
1261 error(1, err
, "ps_context_create");
1263 err
= proc_stat_list_create(context
, &procset
);
1265 error(1, err
, "proc_stat_list_create");
1267 err
= proc_stat_list_add_all(procset
, 0, 0);
1269 error(1, err
, "proc_stat_list_add_all");
1272 static struct proc_stat
*
1273 get_proc_stat(pid_t pid
, ps_flags_t flags
)
1275 struct proc_stat
*ps
;
1276 ps_flags_t wanted_flags
= PSTAT_PID
| flags
;
1281 ps
= proc_stat_list_pid_proc_stat(procset
, pid
);
1284 if (proc_stat_set_flags(ps
, wanted_flags
))
1286 if ((proc_stat_flags(ps
) & wanted_flags
) != wanted_flags
)
1291 #elif defined(HAVE_KVM_H)
1296 char errbuf
[_POSIX2_LINE_MAX
];
1298 kd
= kvm_openfiles(NULL
, KVM_MEMFILE
, NULL
, O_RDONLY
, errbuf
);
1300 errx(1, "%s", errbuf
);
1305 static struct kinfo_proc
*
1306 ssd_kvm_get_procs(kvm_t
*kd
, int op
, int arg
, int *count
)
1308 struct kinfo_proc
*kp
;
1315 kp
= kvm_getprocs(kd
, op
, arg
, count
);
1316 if (kp
== NULL
&& errno
!= ESRCH
)
1317 errx(1, "%s", kvm_geterr(kd
));
1323 #if defined(OSLinux)
1325 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1328 char lcontents
[_POSIX_PATH_MAX
+ 1];
1330 const char deleted
[] = " (deleted)";
1334 sprintf(lname
, "/proc/%d/exe", pid
);
1335 nread
= readlink(lname
, lcontents
, sizeof(lcontents
) - 1);
1339 filename
= lcontents
;
1340 filename
[nread
] = '\0';
1342 /* OpenVZ kernels contain a bogus patch that instead of appending,
1343 * prepends the deleted marker. Workaround those. Otherwise handle
1344 * the normal appended marker. */
1345 if (strncmp(filename
, deleted
, strlen(deleted
)) == 0)
1346 filename
+= strlen(deleted
);
1347 else if (strcmp(filename
+ nread
- strlen(deleted
), deleted
) == 0)
1348 filename
[nread
- strlen(deleted
)] = '\0';
1350 if (stat(filename
, &sb
) != 0)
1353 return (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1355 #elif defined(OSHurd)
1357 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1359 struct proc_stat
*ps
;
1361 const char *filename
;
1363 ps
= get_proc_stat(pid
, PSTAT_ARGS
);
1367 filename
= proc_stat_args(ps
);
1369 if (stat(filename
, &sb
) != 0)
1372 return (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1374 #elif defined(OShpux)
1376 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1378 struct pst_status pst
;
1380 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
1382 return ((dev_t
)pst
.pst_text
.psf_fsid
.psfs_id
== esb
->st_dev
&&
1383 (ino_t
)pst
.pst_text
.psf_fileid
== esb
->st_ino
);
1385 #elif defined(OSFreeBSD)
1387 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1392 char pathname
[PATH_MAX
];
1395 name
[1] = KERN_PROC
;
1396 name
[2] = KERN_PROC_PATHNAME
;
1398 len
= sizeof(pathname
);
1400 error
= sysctl(name
, 4, pathname
, &len
, NULL
, 0);
1401 if (error
!= 0 && errno
!= ESRCH
)
1406 if (stat(pathname
, &sb
) != 0)
1409 return (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1411 #elif defined(HAVE_KVM_H)
1413 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1417 struct kinfo_proc
*kp
;
1419 char buf
[_POSIX2_LINE_MAX
];
1421 char *start_argv_0_p
, *end_argv_0_p
;
1424 kd
= ssd_kvm_open();
1425 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
1429 pid_argv_p
= kvm_getargv(kd
, kp
, argv_len
);
1430 if (pid_argv_p
== NULL
)
1431 errx(1, "%s", kvm_geterr(kd
));
1433 /* Find and compare string. */
1434 start_argv_0_p
= *pid_argv_p
;
1436 /* Find end of argv[0] then copy and cut of str there. */
1437 end_argv_0_p
= strchr(*pid_argv_p
, ' ');
1438 if (end_argv_0_p
== NULL
)
1439 /* There seems to be no space, so we have the command
1440 * already in its desired form. */
1441 start_argv_0_p
= *pid_argv_p
;
1443 /* Tests indicate that this never happens, since
1444 * kvm_getargv itself cuts of tailing stuff. This is
1445 * not what the manpage says, however. */
1446 strncpy(buf
, *pid_argv_p
, (end_argv_0_p
- start_argv_0_p
));
1447 buf
[(end_argv_0_p
- start_argv_0_p
) + 1] = '\0';
1448 start_argv_0_p
= buf
;
1451 if (stat(start_argv_0_p
, &sb
) != 0)
1454 res
= (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1463 #if defined(OSLinux)
1465 pid_is_child(pid_t pid
, pid_t ppid
)
1467 const char *ppid_str
;
1471 ppid_str
= proc_status_field(pid
, "PPid:");
1472 if (ppid_str
== NULL
)
1475 rc
= parse_pid(ppid_str
, &proc_ppid
);
1479 return proc_ppid
== ppid
;
1481 #elif defined(OSHurd)
1483 pid_is_child(pid_t pid
, pid_t ppid
)
1485 struct proc_stat
*ps
;
1486 struct procinfo
*pi
;
1488 ps
= get_proc_stat(pid
, PSTAT_PROC_INFO
);
1492 pi
= proc_stat_proc_info(ps
);
1494 return pi
->ppid
== ppid
;
1496 #elif defined(OShpux)
1498 pid_is_child(pid_t pid
, pid_t ppid
)
1500 struct pst_status pst
;
1502 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
1505 return pst
.pst_ppid
== ppid
;
1507 #elif defined(HAVE_KVM_H)
1509 pid_is_child(pid_t pid
, pid_t ppid
)
1512 struct kinfo_proc
*kp
;
1516 kd
= ssd_kvm_open();
1517 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
1521 #if defined(OSFreeBSD)
1522 proc_ppid
= kp
->ki_ppid
;
1523 #elif defined(OSOpenBSD)
1524 proc_ppid
= kp
->p_ppid
;
1525 #elif defined(OSDragonFlyBSD)
1526 proc_ppid
= kp
->kp_ppid
;
1528 proc_ppid
= kp
->kp_proc
.p_ppid
;
1531 res
= (proc_ppid
== ppid
);
1540 #if defined(OSLinux)
1542 pid_is_user(pid_t pid
, uid_t uid
)
1547 sprintf(buf
, "/proc/%d", pid
);
1548 if (stat(buf
, &sb
) != 0)
1550 return (sb
.st_uid
== uid
);
1552 #elif defined(OSHurd)
1554 pid_is_user(pid_t pid
, uid_t uid
)
1556 struct proc_stat
*ps
;
1558 ps
= get_proc_stat(pid
, PSTAT_OWNER_UID
);
1559 return ps
&& (uid_t
)proc_stat_owner_uid(ps
) == uid
;
1561 #elif defined(OShpux)
1563 pid_is_user(pid_t pid
, uid_t uid
)
1565 struct pst_status pst
;
1567 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
1569 return ((uid_t
)pst
.pst_uid
== uid
);
1571 #elif defined(HAVE_KVM_H)
1573 pid_is_user(pid_t pid
, uid_t uid
)
1577 struct kinfo_proc
*kp
;
1580 kd
= ssd_kvm_open();
1581 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
1585 #if defined(OSFreeBSD)
1586 proc_uid
= kp
->ki_ruid
;
1587 #elif defined(OSOpenBSD)
1588 proc_uid
= kp
->p_ruid
;
1589 #elif defined(OSDragonFlyBSD)
1590 proc_uid
= kp
->kp_ruid
;
1592 if (kp
->kp_proc
.p_cred
)
1593 kvm_read(kd
, (u_long
)&(kp
->kp_proc
.p_cred
->p_ruid
),
1594 &proc_uid
, sizeof(uid_t
));
1599 res
= (proc_uid
== (uid_t
)uid
);
1608 #if defined(OSLinux)
1610 pid_is_cmd(pid_t pid
, const char *name
)
1614 comm
= proc_status_field(pid
, "Name:");
1618 return strcmp(comm
, name
) == 0;
1620 #elif defined(OSHurd)
1622 pid_is_cmd(pid_t pid
, const char *name
)
1624 struct proc_stat
*ps
;
1627 const char *binary_name
;
1629 ps
= get_proc_stat(pid
, PSTAT_ARGS
);
1633 argv0
= proc_stat_args(ps
);
1634 argv0_len
= strlen(argv0
) + 1;
1636 binary_name
= basename(argv0
);
1637 if (strcmp(binary_name
, name
) == 0)
1640 /* XXX: This is all kinds of ugly, but on the Hurd there's no way to
1641 * know the command name of a process, so we have to try to match
1642 * also on argv[1] for the case of an interpreted script. */
1643 if (proc_stat_args_len(ps
) > argv0_len
) {
1644 const char *script_name
= basename(argv0
+ argv0_len
);
1646 return strcmp(script_name
, name
) == 0;
1651 #elif defined(OShpux)
1653 pid_is_cmd(pid_t pid
, const char *name
)
1655 struct pst_status pst
;
1657 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
1659 return (strcmp(pst
.pst_ucomm
, name
) == 0);
1661 #elif defined(HAVE_KVM_H)
1663 pid_is_cmd(pid_t pid
, const char *name
)
1666 struct kinfo_proc
*kp
;
1670 kd
= ssd_kvm_open();
1671 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
1675 #if defined(OSFreeBSD)
1676 process_name
= kp
->ki_comm
;
1677 #elif defined(OSOpenBSD)
1678 process_name
= kp
->p_comm
;
1679 #elif defined(OSDragonFlyBSD)
1680 process_name
= kp
->kp_comm
;
1682 process_name
= kp
->kp_proc
.p_comm
;
1685 res
= (strcmp(name
, process_name
) == 0);
1696 pid_is_running(pid_t pid
)
1698 return get_proc_stat(pid
, 0) != NULL
;
1702 pid_is_running(pid_t pid
)
1704 if (kill(pid
, 0) == 0 || errno
== EPERM
)
1706 else if (errno
== ESRCH
)
1709 fatal("error checking pid %u status", pid
);
1713 static enum status_code
1714 pid_check(pid_t pid
)
1716 if (execname
&& !pid_is_exec(pid
, &exec_stat
))
1718 if (match_ppid
> 0 && !pid_is_child(pid
, match_ppid
))
1720 if (userspec
&& !pid_is_user(pid
, user_id
))
1722 if (cmdname
&& !pid_is_cmd(pid
, cmdname
))
1724 if (action
!= ACTION_STOP
&& !pid_is_running(pid
))
1727 pid_list_push(&found
, pid
);
1732 static enum status_code
1733 do_pidfile(const char *name
)
1736 static pid_t pid
= 0;
1739 return pid_check(pid
);
1741 f
= fopen(name
, "r");
1743 enum status_code pid_status
;
1745 if (fscanf(f
, "%d", &pid
) == 1)
1746 pid_status
= pid_check(pid
);
1748 pid_status
= STATUS_UNKNOWN
;
1751 if (pid_status
== STATUS_DEAD
)
1752 return STATUS_DEAD_PIDFILE
;
1755 } else if (errno
== ENOENT
)
1758 fatal("unable to open pidfile %s", name
);
1761 #if defined(OSLinux) || defined (OSsunos)
1762 static enum status_code
1766 struct dirent
*entry
;
1769 enum status_code prog_status
= STATUS_DEAD
;
1771 procdir
= opendir("/proc");
1773 fatal("unable to opendir /proc");
1776 while ((entry
= readdir(procdir
)) != NULL
) {
1777 enum status_code pid_status
;
1779 if (sscanf(entry
->d_name
, "%d", &pid
) != 1)
1783 pid_status
= pid_check(pid
);
1784 if (pid_status
< prog_status
)
1785 prog_status
= pid_status
;
1789 fatal("nothing in /proc - not mounted?");
1793 #elif defined(OSHurd)
1795 check_proc_stat(struct proc_stat
*ps
)
1801 static enum status_code
1807 proc_stat_list_for_each(procset
, check_proc_stat
);
1814 #elif defined(OShpux)
1815 static enum status_code
1818 struct pst_status pst
[10];
1821 enum status_code prog_status
= STATUS_DEAD
;
1823 while ((count
= pstat_getproc(pst
, sizeof(pst
[0]), 10, idx
)) > 0) {
1824 enum status_code pid_status
;
1826 for (i
= 0; i
< count
; i
++) {
1827 pid_status
= pid_check(pst
[i
].pst_pid
);
1828 if (pid_status
< prog_status
)
1829 prog_status
= pid_status
;
1831 idx
= pst
[count
- 1].pst_idx
+ 1;
1836 #elif defined(HAVE_KVM_H)
1837 static enum status_code
1842 struct kinfo_proc
*kp
;
1843 enum status_code prog_status
= STATUS_DEAD
;
1845 kd
= ssd_kvm_open();
1846 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_ALL
, 0, &nentries
);
1848 for (i
= 0; i
< nentries
; i
++) {
1849 enum status_code pid_status
;
1852 #if defined(OSFreeBSD)
1854 #elif defined(OSOpenBSD)
1856 #elif defined(OSDragonFlyBSD)
1859 pid
= kp
[i
].kp_proc
.p_pid
;
1862 pid_status
= pid_check(pid
);
1863 if (pid_status
< prog_status
)
1864 prog_status
= pid_status
;
1873 static enum status_code
1876 pid_list_free(&found
);
1879 return pid_check(match_pid
);
1881 return do_pidfile(pidfile
);
1883 return do_procinit();
1887 do_start(int argc
, char **argv
)
1889 int devnull_fd
= -1;
1897 printf("%s already running.\n", execname
? execname
: "process");
1900 if (testmode
&& quietmode
<= 0) {
1901 printf("Would start %s ", startas
);
1903 printf("%s ", *argv
++);
1904 if (changeuser
!= NULL
) {
1905 printf(" (as user %s[%d]", changeuser
, runas_uid
);
1906 if (changegroup
!= NULL
)
1907 printf(", and group %s[%d])", changegroup
, runas_gid
);
1911 if (changeroot
!= NULL
)
1912 printf(" in directory %s", changeroot
);
1914 printf(", and add %i to the priority", nicelevel
);
1916 printf(", with scheduling policy %s with priority %i",
1917 proc_sched
->policy_name
, proc_sched
->priority
);
1919 printf(", with IO scheduling class %s with priority %i",
1920 io_sched
->policy_name
, io_sched
->priority
);
1926 printf("Starting %s...\n", startas
);
1929 /* Ok, we need to detach this process. */
1931 else if (mpidfile
&& pidfile
!= NULL
)
1932 /* User wants _us_ to make the pidfile, but detach themself! */
1933 write_pidfile(pidfile
, getpid());
1934 if (background
&& close_io
) {
1935 devnull_fd
= open("/dev/null", O_RDWR
);
1937 fatal("unable to open '%s'", "/dev/null");
1941 if ((nice(nicelevel
) == -1) && (errno
!= 0))
1942 fatal("unable to alter nice level by %i", nicelevel
);
1945 set_proc_schedule(proc_sched
);
1947 set_io_schedule(io_sched
);
1948 if (umask_value
>= 0)
1950 if (changeroot
!= NULL
) {
1951 if (chdir(changeroot
) < 0)
1952 fatal("unable to chdir() to %s", changeroot
);
1953 if (chroot(changeroot
) < 0)
1954 fatal("unable to chroot() to %s", changeroot
);
1956 if (chdir(changedir
) < 0)
1957 fatal("unable to chdir() to %s", changedir
);
1961 if (changegroup
!= NULL
) {
1962 if (rgid
!= (gid_t
)runas_gid
)
1963 if (setgid(runas_gid
))
1964 fatal("unable to set gid to %d", runas_gid
);
1966 if (changeuser
!= NULL
) {
1967 /* We assume that if our real user and group are the same as
1968 * the ones we should switch to, the supplementary groups
1969 * will be already in place. */
1970 if (rgid
!= (gid_t
)runas_gid
|| ruid
!= (uid_t
)runas_uid
)
1971 if (initgroups(changeuser
, runas_gid
))
1972 fatal("unable to set initgroups() with gid %d",
1975 if (ruid
!= (uid_t
)runas_uid
)
1976 if (setuid(runas_uid
))
1977 fatal("unable to set uid to %s", changeuser
);
1980 if (background
&& close_io
) {
1983 dup2(devnull_fd
, 0); /* stdin */
1984 dup2(devnull_fd
, 1); /* stdout */
1985 dup2(devnull_fd
, 2); /* stderr */
1987 /* Now close all extra fds. */
1988 for (i
= get_open_fd_max() - 1; i
>= 3; --i
)
1991 execv(startas
, argv
);
1992 fatal("unable to start %s", startas
);
1996 do_stop(int sig_num
, int *n_killed
, int *n_notkilled
)
2008 pid_list_free(&killed
);
2010 for (p
= found
; p
; p
= p
->next
) {
2013 printf("Would send signal %d to %d.\n",
2016 } else if (kill(p
->pid
, sig_num
) == 0) {
2017 pid_list_push(&killed
, p
->pid
);
2021 warning("failed to kill %d: %s\n",
2022 p
->pid
, strerror(errno
));
2029 do_stop_summary(int retry_nr
)
2033 if (quietmode
>= 0 || !killed
)
2036 printf("Stopped %s (pid", what_stop
);
2037 for (p
= killed
; p
; p
= p
->next
)
2038 printf(" %d", p
->pid
);
2041 printf(", retry #%d", retry_nr
);
2046 set_what_stop(const char *str
)
2048 strncpy(what_stop
, str
, sizeof(what_stop
));
2049 what_stop
[sizeof(what_stop
) - 1] = '\0';
2053 * We want to keep polling for the processes, to see if they've exited, or
2054 * until the timeout expires.
2056 * This is a somewhat complicated algorithm to try to ensure that we notice
2057 * reasonably quickly when all the processes have exited, but don't spend
2058 * too much CPU time polling. In particular, on a fast machine with
2059 * quick-exiting daemons we don't want to delay system shutdown too much,
2060 * whereas on a slow one, or where processes are taking some time to exit,
2061 * we want to increase the polling interval.
2063 * The algorithm is as follows: we measure the elapsed time it takes to do
2064 * one poll(), and wait a multiple of this time for the next poll. However,
2065 * if that would put us past the end of the timeout period we wait only as
2066 * long as the timeout period, but in any case we always wait at least
2067 * MIN_POLL_INTERVAL (20ms). The multiple (‘ratio’) starts out as 2, and
2068 * increases by 1 for each poll to a maximum of 10; so we use up to between
2069 * 30% and 10% of the machine's resources (assuming a few reasonable things
2070 * about system performance).
2073 do_stop_timeout(int timeout
, int *n_killed
, int *n_notkilled
)
2075 struct timespec stopat
, before
, after
, interval
, maxinterval
;
2078 timespec_gettime(&stopat
);
2079 stopat
.tv_sec
+= timeout
;
2082 timespec_gettime(&before
);
2083 if (timespec_cmp(&before
, &stopat
, >))
2086 do_stop(0, n_killed
, n_notkilled
);
2090 timespec_gettime(&after
);
2092 if (!timespec_cmp(&after
, &stopat
, <))
2098 timespec_sub(&stopat
, &after
, &maxinterval
);
2099 timespec_sub(&after
, &before
, &interval
);
2100 timespec_mul(&interval
, ratio
);
2102 if (interval
.tv_sec
< 0 || interval
.tv_nsec
< 0)
2103 interval
.tv_sec
= interval
.tv_nsec
= 0;
2105 if (timespec_cmp(&interval
, &maxinterval
, >))
2106 interval
= maxinterval
;
2108 if (interval
.tv_sec
== 0 &&
2109 interval
.tv_nsec
<= MIN_POLL_INTERVAL
)
2110 interval
.tv_nsec
= MIN_POLL_INTERVAL
;
2112 rc
= pselect(0, NULL
, NULL
, NULL
, &interval
, NULL
);
2113 if (rc
< 0 && errno
!= EINTR
)
2114 fatal("select() failed for pause");
2119 finish_stop_schedule(bool anykilled
)
2121 if (rpidfile
&& pidfile
&& !testmode
)
2122 remove_pidfile(pidfile
);
2128 printf("No %s found running; none killed.\n", what_stop
);
2134 run_stop_schedule(void)
2136 int position
, n_killed
, n_notkilled
, value
, retry_nr
;
2140 if (schedule
!= NULL
) {
2142 printf("Ignoring --retry in test mode\n");
2148 set_what_stop(cmdname
);
2150 set_what_stop(execname
);
2152 sprintf(what_stop
, "process in pidfile '%.200s'", pidfile
);
2153 else if (match_pid
> 0)
2154 sprintf(what_stop
, "process with pid %d", match_pid
);
2155 else if (match_ppid
> 0)
2156 sprintf(what_stop
, "process(es) with parent pid %d", match_ppid
);
2158 sprintf(what_stop
, "process(es) owned by '%.200s'", userspec
);
2160 fatal("internal error, no match option, please report");
2165 if (schedule
== NULL
) {
2166 do_stop(signal_nr
, &n_killed
, &n_notkilled
);
2168 if (n_notkilled
> 0 && quietmode
<= 0)
2169 printf("%d pids were not killed\n", n_notkilled
);
2172 return finish_stop_schedule(anykilled
);
2175 for (position
= 0; position
< schedule_length
; position
++) {
2177 value
= schedule
[position
].value
;
2180 switch (schedule
[position
].type
) {
2185 do_stop(value
, &n_killed
, &n_notkilled
);
2186 do_stop_summary(retry_nr
++);
2188 return finish_stop_schedule(anykilled
);
2193 if (do_stop_timeout(value
, &n_killed
, &n_notkilled
))
2194 return finish_stop_schedule(anykilled
);
2198 assert(!"schedule[].type value must be valid");
2203 printf("Program %s, %d process(es), refused to die.\n",
2204 what_stop
, n_killed
);
2210 main(int argc
, char **argv
)
2214 parse_options(argc
, argv
);
2220 if (action
== ACTION_START
)
2221 do_start(argc
, argv
);
2223 if (action
== ACTION_STOP
) {
2224 int i
= run_stop_schedule();
2228 if (action
== ACTION_STATUS
) {
2229 enum status_code prog_status
;
2231 prog_status
= do_findprocs();