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>
28 #if defined(__linux__)
30 #elif defined(__GNU__)
32 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
34 #elif defined(__NetBSD__)
36 #elif defined(__OpenBSD__)
38 #elif defined(__DragonFly__)
39 # define OS_DragonFlyBSD
40 #elif defined(__APPLE__) && defined(__MACH__)
49 # error Unknown architecture - cannot build start-stop-daemon
52 /* NetBSD needs this to expose struct proc. */
55 #ifdef HAVE_SYS_PARAM_H
56 #include <sys/param.h>
58 #ifdef HAVE_SYS_SYSCALL_H
59 #include <sys/syscall.h>
61 #ifdef HAVE_SYS_SYSCTL_H
62 #include <sys/sysctl.h>
64 #ifdef HAVE_SYS_PROCFS_H
65 #include <sys/procfs.h>
67 #ifdef HAVE_SYS_PROC_H
70 #ifdef HAVE_SYS_USER_H
73 #ifdef HAVE_SYS_PSTAT_H
74 #include <sys/pstat.h>
76 #include <sys/types.h>
80 #include <sys/select.h>
81 #include <sys/ioctl.h>
82 #include <sys/socket.h>
117 #if defined(OS_Darwin)
123 #if defined(OS_FreeBSD)
124 #define KVM_MEMFILE "/dev/null"
126 #define KVM_MEMFILE NULL
130 #if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING > 0
133 #define SCHED_OTHER -1
134 #define SCHED_FIFO -1
138 /* At least macOS and AIX do not define this. */
139 #ifndef SOCK_NONBLOCK
140 #define SOCK_NONBLOCK 0
143 #if defined(OS_Linux)
144 /* This comes from TASK_COMM_LEN defined in Linux' include/linux/sched.h. */
145 #define PROCESS_NAME_SIZE 15
146 #elif defined(OS_Solaris)
147 #define PROCESS_NAME_SIZE 15
148 #elif defined(OS_Darwin)
149 #define PROCESS_NAME_SIZE 16
150 #elif defined(OS_AIX)
151 /* This comes from PRFNSZ defined in AIX's <sys/procfs.h>. */
152 #define PROCESS_NAME_SIZE 16
153 #elif defined(OS_NetBSD)
154 #define PROCESS_NAME_SIZE 16
155 #elif defined(OS_OpenBSD)
156 #define PROCESS_NAME_SIZE 16
157 #elif defined(OS_FreeBSD)
158 #define PROCESS_NAME_SIZE 19
159 #elif defined(OS_DragonFlyBSD)
160 /* On DragonFlyBSD MAXCOMLEN expands to 16. */
161 #define PROCESS_NAME_SIZE MAXCOMLEN
164 #if defined(SYS_ioprio_set) && defined(linux)
165 #define HAVE_IOPRIO_SET
168 #define IOPRIO_CLASS_SHIFT 13
169 #define IOPRIO_PRIO_VALUE(class, prio) (((class) << IOPRIO_CLASS_SHIFT) | (prio))
170 #define IO_SCHED_PRIO_MIN 0
171 #define IO_SCHED_PRIO_MAX 7
174 IOPRIO_WHO_PROCESS
= 1,
193 enum LIBCOMPAT_ATTR_ENUM_FLAGS match_code
{
197 MATCH_PIDFILE
= 1 << 2,
203 /* Time conversion constants. */
205 NANOSEC_IN_SEC
= 1000000000L,
206 NANOSEC_IN_MILLISEC
= 1000000L,
207 NANOSEC_IN_MICROSEC
= 1000L,
210 /* The minimum polling interval, 20ms. */
211 static const long MIN_POLL_INTERVAL
= 20L * NANOSEC_IN_MILLISEC
;
213 static enum action_code action
;
214 static enum match_code match_mode
;
215 static bool testmode
= false;
216 static int quietmode
= 0;
217 static int exitnodo
= 1;
218 static bool background
= false;
219 static bool close_io
= true;
220 static const char *output_io
;
221 static bool notify_await
= false;
222 static int notify_timeout
= 60;
223 static char *notify_sockdir
;
224 static char *notify_socket
;
225 static bool mpidfile
= false;
226 static bool rpidfile
= false;
227 static int signal_nr
= SIGTERM
;
228 static int user_id
= -1;
229 static int runas_uid
= -1;
230 static int runas_gid
= -1;
231 static const char *userspec
= NULL
;
232 static char *changeuser
= NULL
;
233 static const char *changegroup
= NULL
;
234 static char *changeroot
= NULL
;
235 static const char *changedir
= "/";
236 static const char *cmdname
= NULL
;
237 static char *execname
= NULL
;
238 static char *startas
= NULL
;
239 static pid_t match_pid
= -1;
240 static pid_t match_ppid
= -1;
241 static const char *pidfile
= NULL
;
242 static char *what_stop
= NULL
;
243 static const char *progname
= "";
244 static int nicelevel
= 0;
245 static int umask_value
= -1;
247 static struct stat exec_stat
;
249 static struct proc_stat_list
*procset
= NULL
;
252 /* LSB Init Script process status exit codes. */
255 STATUS_DEAD_PIDFILE
= 1,
256 STATUS_DEAD_LOCKFILE
= 2,
262 struct pid_list
*next
;
266 static struct pid_list
*found
= NULL
;
267 static struct pid_list
*killed
= NULL
;
269 /* Resource scheduling policy. */
270 struct res_schedule
{
271 const char *policy_name
;
276 struct schedule_item
{
281 /* Only seen within parse_schedule and callees. */
284 /* Seconds, signal no., or index into array. */
288 static struct res_schedule
*proc_sched
= NULL
;
289 static struct res_schedule
*io_sched
= NULL
;
291 static int schedule_length
;
292 static struct schedule_item
*schedule
= NULL
;
295 static void LIBCOMPAT_ATTR_PRINTF(1)
296 debug(const char *format
, ...)
303 va_start(arglist
, format
);
304 vprintf(format
, arglist
);
308 static void LIBCOMPAT_ATTR_PRINTF(1)
309 info(const char *format
, ...)
316 va_start(arglist
, format
);
317 vprintf(format
, arglist
);
321 static void LIBCOMPAT_ATTR_PRINTF(1)
322 warning(const char *format
, ...)
326 fprintf(stderr
, "%s: warning: ", progname
);
327 va_start(arglist
, format
);
328 vfprintf(stderr
, format
, arglist
);
332 static void LIBCOMPAT_ATTR_NORET
LIBCOMPAT_ATTR_VPRINTF(2)
333 fatalv(int errno_fatal
, const char *format
, va_list args
)
337 fprintf(stderr
, "%s: ", progname
);
338 va_copy(args_copy
, args
);
339 vfprintf(stderr
, format
, args_copy
);
342 fprintf(stderr
, " (%s)\n", strerror(errno_fatal
));
344 fprintf(stderr
, "\n");
346 if (action
== ACTION_STATUS
)
347 exit(STATUS_UNKNOWN
);
352 static void LIBCOMPAT_ATTR_NORET
LIBCOMPAT_ATTR_PRINTF(1)
353 fatal(const char *format
, ...)
357 va_start(args
, format
);
358 fatalv(0, format
, args
);
361 static void LIBCOMPAT_ATTR_NORET
LIBCOMPAT_ATTR_PRINTF(1)
362 fatale(const char *format
, ...)
366 va_start(args
, format
);
367 fatalv(errno
, format
, args
);
370 #define BUG(...) bug(__FILE__, __LINE__, __func__, __VA_ARGS__)
372 static void LIBCOMPAT_ATTR_NORET
LIBCOMPAT_ATTR_PRINTF(4)
373 bug(const char *file
, int line
, const char *func
, const char *format
, ...)
377 fprintf(stderr
, "%s:%s:%d:%s: internal error: ",
378 progname
, file
, line
, func
);
379 va_start(arglist
, format
);
380 vfprintf(stderr
, format
, arglist
);
383 if (action
== ACTION_STATUS
)
384 exit(STATUS_UNKNOWN
);
397 fatale("malloc(%d) failed", size
);
401 xstrndup(const char *str
, size_t n
)
405 new_str
= strndup(str
, n
);
408 fatale("strndup(%s, %zu) failed", str
, n
);
412 timespec_gettime(struct timespec
*ts
)
414 #if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && \
415 defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK > 0
416 if (clock_gettime(CLOCK_MONOTONIC
, ts
) < 0)
417 fatale("clock_gettime failed");
421 if (gettimeofday(&tv
, NULL
) != 0)
422 fatale("gettimeofday failed");
424 ts
->tv_sec
= tv
.tv_sec
;
425 ts
->tv_nsec
= tv
.tv_usec
* NANOSEC_IN_MICROSEC
;
429 #define timespec_cmp(a, b, OP) \
430 (((a)->tv_sec == (b)->tv_sec) ? \
431 ((a)->tv_nsec OP (b)->tv_nsec) : \
432 ((a)->tv_sec OP (b)->tv_sec))
435 timespec_sub(struct timespec
*a
, struct timespec
*b
, struct timespec
*res
)
437 res
->tv_sec
= a
->tv_sec
- b
->tv_sec
;
438 res
->tv_nsec
= a
->tv_nsec
- b
->tv_nsec
;
439 if (res
->tv_nsec
< 0) {
441 res
->tv_nsec
+= NANOSEC_IN_SEC
;
446 timespec_mul(struct timespec
*a
, int b
)
448 long nsec
= a
->tv_nsec
* b
;
451 a
->tv_sec
+= nsec
/ NANOSEC_IN_SEC
;
452 a
->tv_nsec
= nsec
% NANOSEC_IN_SEC
;
456 newpath(const char *dirname
, const char *filename
)
461 path_len
= strlen(dirname
) + 1 + strlen(filename
) + 1;
462 path
= xmalloc(path_len
);
463 snprintf(path
, path_len
, "%s/%s", dirname
, filename
);
469 parse_unsigned(const char *string
, int base
, int *value_r
)
478 value
= strtol(string
, &endptr
, base
);
479 if (string
== endptr
|| *endptr
!= '\0' || errno
!= 0)
481 if (value
< 0 || value
> INT_MAX
)
489 get_open_fd_max(void)
491 #ifdef HAVE_GETDTABLESIZE
492 return getdtablesize();
494 return sysconf(_SC_OPEN_MAX
);
500 detach_controlling_tty(void)
502 #ifdef HAVE_TIOCNOTTY
505 tty_fd
= open("/dev/tty", O_RDWR
);
507 /* The current process does not have a controlling tty. */
511 if (ioctl(tty_fd
, TIOCNOTTY
, 0) != 0)
512 fatale("unable to detach controlling tty");
521 if (setpgid(0, 0) < 0)
524 detach_controlling_tty();
531 wait_for_child(pid_t pid
)
537 child
= waitpid(pid
, &status
, 0);
538 } while (child
== -1 && errno
== EINTR
);
541 fatal("error waiting for child");
543 if (WIFEXITED(status
)) {
544 int ret
= WEXITSTATUS(status
);
547 fatal("child returned error exit status %d", ret
);
548 } else if (WIFSIGNALED(status
)) {
549 int signo
= WTERMSIG(status
);
551 fatal("child was killed by signal %d", signo
);
553 fatal("unexpected status %d waiting for child", status
);
558 cleanup_socket_dir(void)
560 (void)unlink(notify_socket
);
561 (void)rmdir(notify_sockdir
);
565 setup_socket_name(const char *suffix
)
569 if (getuid() == 0 && access(RUNSTATEDIR
, F_OK
) == 0) {
570 basedir
= RUNSTATEDIR
;
572 basedir
= getenv("TMPDIR");
577 if (asprintf(¬ify_sockdir
, "%s/%s.XXXXXX", basedir
, suffix
) < 0)
578 fatale("cannot allocate socket directory name");
580 if (mkdtemp(notify_sockdir
) == NULL
)
581 fatale("cannot create socket directory %s", notify_sockdir
);
583 atexit(cleanup_socket_dir
);
585 if (chown(notify_sockdir
, runas_uid
, runas_gid
))
586 fatale("cannot change socket directory ownership");
588 if (asprintf(¬ify_socket
, "%s/notify", notify_sockdir
) < 0)
589 fatale("cannot allocate socket name");
591 setenv("NOTIFY_SOCKET", notify_socket
, 1);
593 return notify_socket
;
597 set_socket_passcred(int fd
)
600 static const int enable
= 1;
602 (void)setsockopt(fd
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
));
607 create_notify_socket(void)
609 const char *sockname
;
610 struct sockaddr_un su
;
613 /* Create notification socket. */
614 fd
= socket(AF_UNIX
, SOCK_DGRAM
| SOCK_NONBLOCK
, 0);
616 fatale("cannot create notification socket");
618 /* We could set SOCK_CLOEXEC instead, but then we would need to
619 * check whether the socket call failed, try and then do this anyway,
620 * when we have no threading problems to worry about. */
621 flags
= fcntl(fd
, F_GETFD
);
623 fatale("cannot read fd flags for notification socket");
624 if (fcntl(fd
, F_SETFD
, flags
| FD_CLOEXEC
) < 0)
625 fatale("cannot set close-on-exec flag for notification socket");
627 sockname
= setup_socket_name(".s-s-d-notify");
629 /* Bind to a socket in a temporary directory, selected based on
631 memset(&su
, 0, sizeof(su
));
632 su
.sun_family
= AF_UNIX
;
633 strncpy(su
.sun_path
, sockname
, sizeof(su
.sun_path
) - 1);
635 rc
= bind(fd
, (struct sockaddr
*)&su
, sizeof(su
));
637 fatale("cannot bind to notification socket");
639 rc
= chmod(su
.sun_path
, 0660);
641 fatale("cannot change notification socket permissions");
643 rc
= chown(su
.sun_path
, runas_uid
, runas_gid
);
645 fatale("cannot change notification socket ownership");
647 /* XXX: Verify we are talking to an expected child? Although it is not
648 * clear whether this is feasible given the knowledge we have got. */
649 set_socket_passcred(fd
);
655 wait_for_notify(int fd
)
657 struct timespec startat
, now
, elapsed
, timeout
, timeout_orig
;
661 timeout
.tv_sec
= notify_timeout
;
663 timeout_orig
= timeout
;
665 timespec_gettime(&startat
);
667 while (timeout
.tv_sec
>= 0 && timeout
.tv_nsec
>= 0) {
671 /* Wait for input. */
672 debug("Waiting for notifications... (timeout %lusec %lunsec)\n",
673 timeout
.tv_sec
, timeout
.tv_nsec
);
674 rc
= pselect(fd
+ 1, &fdrs
, NULL
, NULL
, &timeout
, NULL
);
676 /* Catch non-restartable errors, that is, not signals nor
677 * kernel out of resources. */
678 if (rc
< 0 && (errno
!= EINTR
&& errno
!= EAGAIN
))
679 fatale("cannot monitor notification socket for activity");
683 fatal("timed out waiting for a notification");
685 /* Update the timeout, as should not rely on pselect() having
686 * done that for us, which is an unportable assumption. */
687 timespec_gettime(&now
);
688 timespec_sub(&now
, &startat
, &elapsed
);
689 timespec_sub(&timeout_orig
, &elapsed
, &timeout
);
691 /* Restartable error, a signal or kernel out of resources. */
695 /* Parse it and check for a supported notification message,
696 * once we get a READY=1, we exit. */
700 char *line
, *line_next
;
702 nrecv
= recv(fd
, buf
, sizeof(buf
), 0);
703 if (nrecv
< 0 && (errno
!= EINTR
&& errno
!= EAGAIN
))
704 fatale("cannot receive notification packet");
710 for (line
= buf
; *line
; line
= line_next
) {
711 line_next
= strchrnul(line
, '\n');
712 if (*line_next
== '\n')
715 debug("Child sent some notification...\n");
716 if (strncmp(line
, "EXTEND_TIMEOUT_USEC=", 20) == 0) {
719 if (parse_unsigned(line
+ 20, 10, &extend_usec
) != 0)
720 fatale("cannot parse extended timeout notification %s", line
);
722 /* Reset the current timeout. */
723 timeout
.tv_sec
= extend_usec
/ 1000L;
724 timeout
.tv_nsec
= (extend_usec
% 1000L) *
726 timeout_orig
= timeout
;
728 timespec_gettime(&startat
);
729 } else if (strncmp(line
, "ERRNO=", 6) == 0) {
732 if (parse_unsigned(line
+ 6, 10, &suberrno
) != 0)
733 fatale("cannot parse errno notification %s", line
);
735 fatale("program failed to initialize");
736 } else if (strcmp(line
, "READY=1") == 0) {
737 debug("-> Notification => ready for service.\n");
740 debug("-> Notification line '%s' received\n", line
);
748 write_pidfile(const char *filename
, pid_t pid
)
753 fd
= open(filename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_NOFOLLOW
, 0666);
757 fp
= fdopen(fd
, "w");
760 fatale("unable to open pidfile '%s' for writing", filename
);
762 fprintf(fp
, "%d\n", pid
);
765 fatale("unable to close pidfile '%s'", filename
);
769 remove_pidfile(const char *filename
)
771 if (unlink(filename
) < 0 && errno
!= ENOENT
)
772 fatale("cannot remove pidfile '%s'", filename
);
783 debug("Detaching to start %s...\n", startas
);
785 /* Block SIGCHLD to allow waiting for the child process while it is
786 * performing actions, such as creating a pidfile. */
788 sigaddset(&mask
, SIGCHLD
);
789 if (sigprocmask(SIG_BLOCK
, &mask
, &oldmask
) == -1)
790 fatale("cannot block SIGCHLD");
793 notify_fd
= create_notify_socket();
797 fatale("unable to do first fork");
798 else if (pid
) { /* First Parent. */
799 /* Wait for the second parent to exit, so that if we need to
800 * perform any actions there, like creating a pidfile, we do
801 * not suffer from race conditions on return. */
805 /* Wait for a readiness notification from the second
806 * child, so that we can safely exit when the service
808 wait_for_notify(notify_fd
);
810 cleanup_socket_dir();
816 /* Close the notification socket, even though it is close-on-exec. */
820 /* Create a new session. */
822 fatale("cannot set session ID");
826 fatale("unable to do second fork");
827 else if (pid
) { /* Second parent. */
828 /* Set a default umask for dumb programs, which might get
829 * overridden by the --umask option later on, so that we get
830 * a defined umask when creating the pidfile. */
833 if (mpidfile
&& pidfile
!= NULL
)
834 /* User wants _us_ to make the pidfile. */
835 write_pidfile(pidfile
, pid
);
840 if (sigprocmask(SIG_SETMASK
, &oldmask
, NULL
) == -1)
841 fatale("cannot restore signal mask");
843 debug("Detaching complete...\n");
847 pid_list_push(struct pid_list
**list
, pid_t pid
)
851 p
= xmalloc(sizeof(*p
));
858 pid_list_free(struct pid_list
**list
)
860 struct pid_list
*here
, *next
;
862 for (here
= *list
; here
!= NULL
; here
= next
) {
874 "Usage: start-stop-daemon [<option>...] <command>\n"
879 " -S, --start -- <argument>... start a program and pass <arguments> to it\n"
880 " -K, --stop stop a program\n"
881 " -T, --status get the program status\n"
882 " -H, --help print help information\n"
883 " -V, --version print version\n"
887 "Matching options (at least one is required):\n"
888 " --pid <pid> pid to check\n"
889 " --ppid <ppid> parent pid to check\n"
890 " -p, --pidfile <pid-file> pid file to check\n"
891 " -x, --exec <executable> program to start/check if it is running\n"
892 " -n, --name <process-name> process name to check\n"
893 " -u, --user <username|uid> process owner to check\n"
898 " -g, --group <group|gid> run process as this group\n"
899 " -c, --chuid <name|uid[:group|gid]>\n"
900 " change to this user/group before starting\n"
902 " -s, --signal <signal> signal to send (default TERM)\n"
903 " -a, --startas <pathname> program to start (default is <executable>)\n"
904 " -r, --chroot <directory> chroot to <directory> before starting\n"
905 " -d, --chdir <directory> change to <directory> (default is /)\n"
906 " -N, --nicelevel <incr> add incr to the process' nice level\n"
907 " -P, --procsched <policy[:prio]>\n"
908 " use <policy> with <prio> for the kernel\n"
909 " process scheduler (default prio is 0)\n"
910 " -I, --iosched <class[:prio]> use <class> with <prio> to set the IO\n"
911 " scheduler (default prio is 4)\n"
912 " -k, --umask <mask> change the umask to <mask> before starting\n"
913 " -b, --background force the process to detach\n"
914 " --notify-await wait for a readiness notification\n"
915 " --notify-timeout <int> timeout after <int> seconds of notify wait\n"
916 " -C, --no-close do not close any file descriptor\n"
917 " -O, --output <filename> send stdout and stderr to <filename>\n"
918 " -m, --make-pidfile create the pidfile before starting\n"
919 " --remove-pidfile delete the pidfile after stopping\n"
920 " -R, --retry <schedule> check whether processes die, and retry\n"
921 " -t, --test test mode, don't do anything\n"
922 " -o, --oknodo exit status 0 (not 1) if nothing done\n"
923 " -q, --quiet be more quiet\n"
924 " -v, --verbose be more verbose\n"
928 "Retry <schedule> is <item>|/<item>/... where <item> is one of\n"
929 " -<signal-num>|[-]<signal-name> send that signal\n"
930 " <timeout> wait that many seconds\n"
931 " forever repeat remainder forever\n"
932 "or <schedule> may be just <timeout>, meaning <signal>/<timeout>/KILL/<timeout>\n"
936 "The process scheduler <policy> can be one of:\n"
937 " other, fifo or rr\n"
941 "The IO scheduler <class> can be one of:\n"
942 " real-time, best-effort or idle\n"
948 " 1 = nothing done (=> 0 if --oknodo)\n"
949 " 2 = with --retry, processes would not die\n"
951 "Exit status with --status:\n"
952 " 0 = program is running\n"
953 " 1 = program is not running and the pid file exists\n"
954 " 3 = program is not running\n"
955 " 4 = unable to determine status\n");
961 printf("start-stop-daemon %s for Debian\n\n", VERSION
);
963 printf("Written by Marek Michalkiewicz, public domain.\n");
966 static void LIBCOMPAT_ATTR_NORET
967 badusage(const char *msg
)
970 fprintf(stderr
, "%s: %s\n", progname
, msg
);
971 fprintf(stderr
, "Try '%s --help' for more information.\n", progname
);
973 if (action
== ACTION_STATUS
)
974 exit(STATUS_UNKNOWN
);
984 static const struct sigpair siglist
[] = {
1000 { "STOP", SIGSTOP
},
1001 { "TSTP", SIGTSTP
},
1002 { "TTIN", SIGTTIN
},
1007 parse_pid(const char *pid_str
, int *pid_num
)
1009 if (parse_unsigned(pid_str
, 10, pid_num
) != 0)
1018 parse_signal(const char *sig_str
, int *sig_num
)
1022 if (parse_unsigned(sig_str
, 10, sig_num
) == 0)
1025 for (i
= 0; i
< array_count(siglist
); i
++) {
1026 if (strcmp(sig_str
, siglist
[i
].name
) == 0) {
1027 *sig_num
= siglist
[i
].signal
;
1035 parse_umask(const char *string
, int *value_r
)
1037 return parse_unsigned(string
, 0, value_r
);
1041 validate_proc_schedule(void)
1043 #if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING > 0
1044 int prio_min
, prio_max
;
1046 prio_min
= sched_get_priority_min(proc_sched
->policy
);
1047 prio_max
= sched_get_priority_max(proc_sched
->policy
);
1049 if (proc_sched
->priority
< prio_min
)
1050 badusage("process scheduler priority less than min");
1051 if (proc_sched
->priority
> prio_max
)
1052 badusage("process scheduler priority greater than max");
1057 parse_proc_schedule(const char *string
)
1063 policy_len
= strcspn(string
, ":");
1064 policy_str
= xstrndup(string
, policy_len
);
1066 if (string
[policy_len
] == ':' &&
1067 parse_unsigned(string
+ policy_len
+ 1, 10, &prio
) != 0)
1068 fatale("invalid process scheduler priority");
1070 proc_sched
= xmalloc(sizeof(*proc_sched
));
1071 proc_sched
->policy_name
= policy_str
;
1073 if (strcmp(policy_str
, "other") == 0) {
1074 proc_sched
->policy
= SCHED_OTHER
;
1075 proc_sched
->priority
= 0;
1076 } else if (strcmp(policy_str
, "fifo") == 0) {
1077 proc_sched
->policy
= SCHED_FIFO
;
1078 proc_sched
->priority
= prio
;
1079 } else if (strcmp(policy_str
, "rr") == 0) {
1080 proc_sched
->policy
= SCHED_RR
;
1081 proc_sched
->priority
= prio
;
1083 badusage("invalid process scheduler policy");
1085 validate_proc_schedule();
1089 parse_io_schedule(const char *string
)
1095 class_len
= strcspn(string
, ":");
1096 class_str
= xstrndup(string
, class_len
);
1098 if (string
[class_len
] == ':' &&
1099 parse_unsigned(string
+ class_len
+ 1, 10, &prio
) != 0)
1100 fatale("invalid IO scheduler priority");
1102 io_sched
= xmalloc(sizeof(*io_sched
));
1103 io_sched
->policy_name
= class_str
;
1105 if (strcmp(class_str
, "real-time") == 0) {
1106 io_sched
->policy
= IOPRIO_CLASS_RT
;
1107 io_sched
->priority
= prio
;
1108 } else if (strcmp(class_str
, "best-effort") == 0) {
1109 io_sched
->policy
= IOPRIO_CLASS_BE
;
1110 io_sched
->priority
= prio
;
1111 } else if (strcmp(class_str
, "idle") == 0) {
1112 io_sched
->policy
= IOPRIO_CLASS_IDLE
;
1113 io_sched
->priority
= 7;
1115 badusage("invalid IO scheduler policy");
1117 if (io_sched
->priority
< IO_SCHED_PRIO_MIN
)
1118 badusage("IO scheduler priority less than min");
1119 if (io_sched
->priority
> IO_SCHED_PRIO_MAX
)
1120 badusage("IO scheduler priority greater than max");
1124 set_proc_schedule(struct res_schedule
*sched
)
1126 #if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING > 0
1127 struct sched_param param
;
1129 param
.sched_priority
= sched
->priority
;
1131 if (sched_setscheduler(getpid(), sched
->policy
, ¶m
) == -1)
1132 fatale("unable to set process scheduler");
1136 #ifdef HAVE_IOPRIO_SET
1138 ioprio_set(int which
, int who
, int ioprio
)
1140 return syscall(SYS_ioprio_set
, which
, who
, ioprio
);
1145 set_io_schedule(struct res_schedule
*sched
)
1147 #ifdef HAVE_IOPRIO_SET
1150 io_sched_mask
= IOPRIO_PRIO_VALUE(sched
->policy
, sched
->priority
);
1151 if (ioprio_set(IOPRIO_WHO_PROCESS
, getpid(), io_sched_mask
) == -1)
1152 warning("unable to alter IO priority to mask %i (%s)\n",
1153 io_sched_mask
, strerror(errno
));
1158 parse_schedule_item(const char *string
, struct schedule_item
*item
)
1160 const char *after_hyph
;
1162 if (strcmp(string
, "forever") == 0) {
1163 item
->type
= sched_forever
;
1164 } else if (isdigit(string
[0])) {
1165 item
->type
= sched_timeout
;
1166 if (parse_unsigned(string
, 10, &item
->value
) != 0)
1167 badusage("invalid timeout value in schedule");
1168 } else if ((after_hyph
= string
+ (string
[0] == '-')) &&
1169 parse_signal(after_hyph
, &item
->value
) == 0) {
1170 item
->type
= sched_signal
;
1172 badusage("invalid schedule item (must be [-]<signal-name>, "
1173 "-<signal-number>, <timeout> or 'forever'");
1178 parse_schedule(const char *schedule_str
)
1184 for (slash
= schedule_str
; *slash
; slash
++)
1188 schedule_length
= (count
== 0) ? 4 : count
+ 1;
1189 schedule
= xmalloc(sizeof(*schedule
) * schedule_length
);
1192 schedule
[0].type
= sched_signal
;
1193 schedule
[0].value
= signal_nr
;
1194 parse_schedule_item(schedule_str
, &schedule
[1]);
1195 if (schedule
[1].type
!= sched_timeout
) {
1196 badusage("--retry takes timeout, or schedule list"
1197 " of at least two items");
1199 schedule
[2].type
= sched_signal
;
1200 schedule
[2].value
= SIGKILL
;
1201 schedule
[3] = schedule
[1];
1207 while (*schedule_str
) {
1211 slash
= strchrnul(schedule_str
, '/');
1212 str_len
= (size_t)(slash
- schedule_str
);
1213 if (str_len
>= sizeof(item_buf
))
1214 badusage("invalid schedule item: far too long"
1215 " (you must delimit items with slashes)");
1216 memcpy(item_buf
, schedule_str
, str_len
);
1217 item_buf
[str_len
] = '\0';
1218 schedule_str
= *slash
? slash
+ 1 : slash
;
1220 parse_schedule_item(item_buf
, &schedule
[count
]);
1221 if (schedule
[count
].type
== sched_forever
) {
1223 badusage("invalid schedule: 'forever'"
1224 " appears more than once");
1230 if (repeatat
== count
)
1231 badusage("invalid schedule: 'forever' appears last, "
1232 "nothing to repeat");
1233 if (repeatat
>= 0) {
1234 schedule
[count
].type
= sched_goto
;
1235 schedule
[count
].value
= repeatat
;
1238 if (count
!= schedule_length
)
1239 BUG("count=%d != schedule_length=%d",
1240 count
, schedule_length
);
1245 set_action(enum action_code new_action
)
1247 if (action
== new_action
)
1250 if (action
!= ACTION_NONE
)
1251 badusage("only one command can be specified");
1253 action
= new_action
;
1257 #define OPT_PPID 501
1258 #define OPT_RM_PIDFILE 502
1259 #define OPT_NOTIFY_AWAIT 503
1260 #define OPT_NOTIFY_TIMEOUT 504
1263 parse_options(int argc
, char * const *argv
)
1265 static struct option longopts
[] = {
1266 { "help", 0, NULL
, 'H'},
1267 { "stop", 0, NULL
, 'K'},
1268 { "start", 0, NULL
, 'S'},
1269 { "status", 0, NULL
, 'T'},
1270 { "version", 0, NULL
, 'V'},
1271 { "startas", 1, NULL
, 'a'},
1272 { "name", 1, NULL
, 'n'},
1273 { "oknodo", 0, NULL
, 'o'},
1274 { "pid", 1, NULL
, OPT_PID
},
1275 { "ppid", 1, NULL
, OPT_PPID
},
1276 { "pidfile", 1, NULL
, 'p'},
1277 { "quiet", 0, NULL
, 'q'},
1278 { "signal", 1, NULL
, 's'},
1279 { "test", 0, NULL
, 't'},
1280 { "user", 1, NULL
, 'u'},
1281 { "group", 1, NULL
, 'g'},
1282 { "chroot", 1, NULL
, 'r'},
1283 { "verbose", 0, NULL
, 'v'},
1284 { "exec", 1, NULL
, 'x'},
1285 { "chuid", 1, NULL
, 'c'},
1286 { "nicelevel", 1, NULL
, 'N'},
1287 { "procsched", 1, NULL
, 'P'},
1288 { "iosched", 1, NULL
, 'I'},
1289 { "umask", 1, NULL
, 'k'},
1290 { "background", 0, NULL
, 'b'},
1291 { "notify-await", 0, NULL
, OPT_NOTIFY_AWAIT
},
1292 { "notify-timeout", 1, NULL
, OPT_NOTIFY_TIMEOUT
},
1293 { "no-close", 0, NULL
, 'C'},
1294 { "output", 1, NULL
, 'O'},
1295 { "make-pidfile", 0, NULL
, 'm'},
1296 { "remove-pidfile", 0, NULL
, OPT_RM_PIDFILE
},
1297 { "retry", 1, NULL
, 'R'},
1298 { "chdir", 1, NULL
, 'd'},
1299 { NULL
, 0, NULL
, 0 }
1301 const char *pid_str
= NULL
;
1302 const char *ppid_str
= NULL
;
1303 const char *umask_str
= NULL
;
1304 const char *signal_str
= NULL
;
1305 const char *schedule_str
= NULL
;
1306 const char *proc_schedule_str
= NULL
;
1307 const char *io_schedule_str
= NULL
;
1308 const char *notify_timeout_str
= NULL
;
1309 size_t changeuser_len
;
1313 c
= getopt_long(argc
, argv
,
1314 "HKSVTa:n:op:qr:s:tu:vx:c:N:P:I:k:bCO:mR:g:d:",
1319 case 'H': /* --help */
1322 case 'K': /* --stop */
1323 set_action(ACTION_STOP
);
1325 case 'S': /* --start */
1326 set_action(ACTION_START
);
1328 case 'T': /* --status */
1329 set_action(ACTION_STATUS
);
1331 case 'V': /* --version */
1334 case 'a': /* --startas <pathname> */
1337 case 'n': /* --name <process-name> */
1338 match_mode
|= MATCH_NAME
;
1341 case 'o': /* --oknodo */
1344 case OPT_PID
: /* --pid <pid> */
1345 match_mode
|= MATCH_PID
;
1348 case OPT_PPID
: /* --ppid <ppid> */
1349 match_mode
|= MATCH_PPID
;
1352 case 'p': /* --pidfile <pid-file> */
1353 match_mode
|= MATCH_PIDFILE
;
1356 case 'q': /* --quiet */
1359 case 's': /* --signal <signal> */
1360 signal_str
= optarg
;
1362 case 't': /* --test */
1365 case 'u': /* --user <username>|<uid> */
1366 match_mode
|= MATCH_USER
;
1369 case 'v': /* --verbose */
1372 case 'x': /* --exec <executable> */
1373 match_mode
|= MATCH_EXEC
;
1376 case 'c': /* --chuid <username>|<uid> */
1378 /* We copy the string just in case we need the
1379 * argument later. */
1380 changeuser_len
= strcspn(optarg
, ":");
1381 changeuser
= xstrndup(optarg
, changeuser_len
);
1382 if (optarg
[changeuser_len
] == ':') {
1383 if (optarg
[changeuser_len
+ 1] == '\0')
1384 fatal("missing group name");
1385 changegroup
= optarg
+ changeuser_len
+ 1;
1388 case 'g': /* --group <group>|<gid> */
1389 changegroup
= optarg
;
1391 case 'r': /* --chroot /new/root */
1392 changeroot
= optarg
;
1394 case 'N': /* --nice */
1395 nicelevel
= atoi(optarg
);
1397 case 'P': /* --procsched */
1398 proc_schedule_str
= optarg
;
1400 case 'I': /* --iosched */
1401 io_schedule_str
= optarg
;
1403 case 'k': /* --umask <mask> */
1406 case 'b': /* --background */
1409 case OPT_NOTIFY_AWAIT
:
1410 notify_await
= true;
1412 case OPT_NOTIFY_TIMEOUT
:
1413 notify_timeout_str
= optarg
;
1415 case 'C': /* --no-close */
1418 case 'O': /* --outout <filename> */
1421 case 'm': /* --make-pidfile */
1424 case OPT_RM_PIDFILE
: /* --remove-pidfile */
1427 case 'R': /* --retry <schedule>|<timeout> */
1428 schedule_str
= optarg
;
1430 case 'd': /* --chdir /new/dir */
1434 /* Message printed by getopt. */
1439 if (pid_str
!= NULL
) {
1440 if (parse_pid(pid_str
, &match_pid
) != 0)
1441 badusage("pid value must be a number greater than 0");
1444 if (ppid_str
!= NULL
) {
1445 if (parse_pid(ppid_str
, &match_ppid
) != 0)
1446 badusage("ppid value must be a number greater than 0");
1449 if (signal_str
!= NULL
) {
1450 if (parse_signal(signal_str
, &signal_nr
) != 0)
1451 badusage("signal value must be numeric or name"
1452 " of signal (KILL, INT, ...)");
1455 if (schedule_str
!= NULL
) {
1456 parse_schedule(schedule_str
);
1459 if (proc_schedule_str
!= NULL
)
1460 parse_proc_schedule(proc_schedule_str
);
1462 if (io_schedule_str
!= NULL
)
1463 parse_io_schedule(io_schedule_str
);
1465 if (umask_str
!= NULL
) {
1466 if (parse_umask(umask_str
, &umask_value
) != 0)
1467 badusage("umask value must be a positive number");
1470 if (output_io
!= NULL
&& output_io
[0] != '/')
1471 badusage("--output file needs to be an absolute filename");
1473 if (notify_timeout_str
!= NULL
)
1474 if (parse_unsigned(notify_timeout_str
, 10, ¬ify_timeout
) != 0)
1475 badusage("invalid notify timeout value");
1477 if (action
== ACTION_NONE
)
1478 badusage("need one of --start or --stop or --status");
1480 if (match_mode
== MATCH_NONE
||
1481 (!execname
&& !cmdname
&& !userspec
&&
1482 !pid_str
&& !ppid_str
&& !pidfile
))
1483 badusage("need at least one of --exec, --pid, --ppid, --pidfile, --user or --name");
1485 #ifdef PROCESS_NAME_SIZE
1486 if (cmdname
&& strlen(cmdname
) > PROCESS_NAME_SIZE
)
1487 warning("this system is not able to track process names\n"
1488 "longer than %d characters, please use --exec "
1489 "instead of --name.\n", PROCESS_NAME_SIZE
);
1495 if (action
== ACTION_START
&& !startas
)
1496 badusage("--start needs --exec or --startas");
1498 if (mpidfile
&& pidfile
== NULL
)
1499 badusage("--make-pidfile requires --pidfile");
1500 if (rpidfile
&& pidfile
== NULL
)
1501 badusage("--remove-pidfile requires --pidfile");
1503 if (pid_str
&& pidfile
)
1504 badusage("need either --pid or --pidfile, not both");
1506 if (background
&& action
!= ACTION_START
)
1507 badusage("--background is only relevant with --start");
1509 if (!close_io
&& !background
)
1510 badusage("--no-close is only relevant with --background");
1511 if (output_io
&& !background
)
1512 badusage("--output is only relevant with --background");
1514 if (close_io
&& output_io
== NULL
)
1515 output_io
= "/dev/null";
1524 /* If it's a relative path, normalize it. */
1525 if (execname
[0] != '/')
1526 execname
= newpath(changedir
, execname
);
1529 fullexecname
= newpath(changeroot
, execname
);
1531 fullexecname
= execname
;
1533 if (stat(fullexecname
, &exec_stat
))
1534 fatale("unable to stat %s", fullexecname
);
1536 if (fullexecname
!= execname
)
1540 if (userspec
&& parse_unsigned(userspec
, 10, &user_id
) < 0) {
1543 pw
= getpwnam(userspec
);
1545 fatale("user '%s' not found", userspec
);
1547 user_id
= pw
->pw_uid
;
1550 if (changegroup
&& parse_unsigned(changegroup
, 10, &runas_gid
) < 0) {
1553 gr
= getgrnam(changegroup
);
1555 fatale("group '%s' not found", changegroup
);
1556 changegroup
= gr
->gr_name
;
1557 runas_gid
= gr
->gr_gid
;
1563 if (parse_unsigned(changeuser
, 10, &runas_uid
) == 0)
1564 pw
= getpwuid(runas_uid
);
1566 pw
= getpwnam(changeuser
);
1568 fatale("user '%s' not found", changeuser
);
1569 changeuser
= pw
->pw_name
;
1570 runas_uid
= pw
->pw_uid
;
1571 if (changegroup
== NULL
) {
1572 /* Pass the default group of this user. */
1573 changegroup
= ""; /* Just empty. */
1574 runas_gid
= pw
->pw_gid
;
1576 if (stat(pw
->pw_dir
, &st
) == 0)
1577 setenv("HOME", pw
->pw_dir
, 1);
1581 #if defined(OS_Linux)
1583 proc_status_field(pid_t pid
, const char *field
)
1585 static char *line
= NULL
;
1586 static size_t line_size
= 0;
1592 size_t field_len
= strlen(field
);
1594 sprintf(filename
, "/proc/%d/status", pid
);
1595 fp
= fopen(filename
, "r");
1598 while ((line_len
= getline(&line
, &line_size
, fp
)) >= 0) {
1599 if (strncasecmp(line
, field
, field_len
) == 0) {
1600 line
[line_len
- 1] = '\0';
1602 value
= line
+ field_len
;
1603 while (isspace(*value
))
1613 #elif defined(OS_AIX)
1615 proc_get_psinfo(pid_t pid
, struct psinfo
*psinfo
)
1620 sprintf(filename
, "/proc/%d/psinfo", pid
);
1621 fp
= fopen(filename
, "r");
1624 if (fread(psinfo
, sizeof(*psinfo
), 1, fp
) == 0) {
1637 #elif defined(OS_Hurd)
1641 struct ps_context
*context
;
1644 err
= ps_context_create(getproc(), &context
);
1646 error(1, err
, "ps_context_create");
1648 err
= proc_stat_list_create(context
, &procset
);
1650 error(1, err
, "proc_stat_list_create");
1652 err
= proc_stat_list_add_all(procset
, 0, 0);
1654 error(1, err
, "proc_stat_list_add_all");
1657 static struct proc_stat
*
1658 get_proc_stat(pid_t pid
, ps_flags_t flags
)
1660 struct proc_stat
*ps
;
1661 ps_flags_t wanted_flags
= PSTAT_PID
| flags
;
1666 ps
= proc_stat_list_pid_proc_stat(procset
, pid
);
1669 if (proc_stat_set_flags(ps
, wanted_flags
))
1671 if ((proc_stat_flags(ps
) & wanted_flags
) != wanted_flags
)
1676 #elif defined(HAVE_KVM_H)
1681 char errbuf
[_POSIX2_LINE_MAX
];
1683 kd
= kvm_openfiles(NULL
, KVM_MEMFILE
, NULL
, O_RDONLY
, errbuf
);
1685 errx(1, "%s", errbuf
);
1690 static struct kinfo_proc
*
1691 ssd_kvm_get_procs(kvm_t
*kd
, int op
, int arg
, int *count
)
1693 struct kinfo_proc
*kp
;
1700 #if defined(OS_OpenBSD)
1701 kp
= kvm_getprocs(kd
, op
, arg
, sizeof(*kp
), count
);
1703 kp
= kvm_getprocs(kd
, op
, arg
, count
);
1705 if (kp
== NULL
&& errno
!= ESRCH
)
1706 errx(1, "%s", kvm_geterr(kd
));
1712 #if defined(OS_Linux)
1714 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1717 char lcontents
[_POSIX_PATH_MAX
+ 1];
1719 const char deleted
[] = " (deleted)";
1723 sprintf(lname
, "/proc/%d/exe", pid
);
1724 nread
= readlink(lname
, lcontents
, sizeof(lcontents
) - 1);
1728 filename
= lcontents
;
1729 filename
[nread
] = '\0';
1731 /* OpenVZ kernels contain a bogus patch that instead of appending,
1732 * prepends the deleted marker. Workaround those. Otherwise handle
1733 * the normal appended marker. */
1734 if (strncmp(filename
, deleted
, strlen(deleted
)) == 0)
1735 filename
+= strlen(deleted
);
1736 else if (strcmp(filename
+ nread
- strlen(deleted
), deleted
) == 0)
1737 filename
[nread
- strlen(deleted
)] = '\0';
1739 if (stat(filename
, &sb
) != 0)
1742 return (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1744 #elif defined(OS_AIX)
1746 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1751 sprintf(filename
, "/proc/%d/object/a.out", pid
);
1753 if (stat(filename
, &sb
) != 0)
1756 return sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
;
1758 #elif defined(OS_Hurd)
1760 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1762 struct proc_stat
*ps
;
1764 const char *filename
;
1766 ps
= get_proc_stat(pid
, PSTAT_ARGS
);
1770 /* On old Hurd systems we have to use the argv[0] value, because
1771 * there is nothing better. */
1772 filename
= proc_stat_args(ps
);
1774 /* On new Hurd systems we can use the correct value, as long
1775 * as it's not NULL nor empty, as it was the case on the first
1776 * implementation. */
1777 if (proc_stat_set_flags(ps
, PSTAT_EXE
) == 0 &&
1778 proc_stat_flags(ps
) & PSTAT_EXE
&&
1779 proc_stat_exe(ps
) != NULL
&&
1780 proc_stat_exe(ps
)[0] != '\0')
1781 filename
= proc_stat_exe(ps
);
1784 if (stat(filename
, &sb
) != 0)
1787 return (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1789 #elif defined(OS_Darwin)
1791 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1794 char pathname
[_POSIX_PATH_MAX
];
1796 if (proc_pidpath(pid
, pathname
, sizeof(pathname
)) < 0)
1799 if (stat(pathname
, &sb
) != 0)
1802 return (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1804 #elif defined(OS_HPUX)
1806 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1808 struct pst_status pst
;
1810 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
1812 return ((dev_t
)pst
.pst_text
.psf_fsid
.psfs_id
== esb
->st_dev
&&
1813 (ino_t
)pst
.pst_text
.psf_fileid
== esb
->st_ino
);
1815 #elif defined(OS_FreeBSD)
1817 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1822 char pathname
[PATH_MAX
];
1826 mib
[2] = KERN_PROC_PATHNAME
;
1828 len
= sizeof(pathname
);
1830 error
= sysctl(mib
, 4, pathname
, &len
, NULL
, 0);
1831 if (error
!= 0 && errno
!= ESRCH
)
1836 if (stat(pathname
, &sb
) != 0)
1839 return (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1841 #elif defined(HAVE_KVM_H)
1843 pid_is_exec(pid_t pid
, const struct stat
*esb
)
1847 struct kinfo_proc
*kp
;
1849 char buf
[_POSIX2_LINE_MAX
];
1851 char *start_argv_0_p
, *end_argv_0_p
;
1854 kd
= ssd_kvm_open();
1855 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
1859 pid_argv_p
= kvm_getargv(kd
, kp
, argv_len
);
1860 if (pid_argv_p
== NULL
)
1861 errx(1, "%s", kvm_geterr(kd
));
1863 /* Find and compare string. */
1864 start_argv_0_p
= *pid_argv_p
;
1866 /* Find end of argv[0] then copy and cut of str there. */
1867 end_argv_0_p
= strchr(*pid_argv_p
, ' ');
1868 if (end_argv_0_p
== NULL
)
1869 /* There seems to be no space, so we have the command
1870 * already in its desired form. */
1871 start_argv_0_p
= *pid_argv_p
;
1873 /* Tests indicate that this never happens, since
1874 * kvm_getargv itself cuts of tailing stuff. This is
1875 * not what the manpage says, however. */
1876 strncpy(buf
, *pid_argv_p
, (end_argv_0_p
- start_argv_0_p
));
1877 buf
[(end_argv_0_p
- start_argv_0_p
) + 1] = '\0';
1878 start_argv_0_p
= buf
;
1881 if (stat(start_argv_0_p
, &sb
) != 0)
1884 res
= (sb
.st_dev
== esb
->st_dev
&& sb
.st_ino
== esb
->st_ino
);
1893 #if defined(OS_Linux)
1895 pid_is_child(pid_t pid
, pid_t ppid
)
1897 const char *ppid_str
;
1901 ppid_str
= proc_status_field(pid
, "PPid:");
1902 if (ppid_str
== NULL
)
1905 rc
= parse_pid(ppid_str
, &proc_ppid
);
1909 return proc_ppid
== ppid
;
1911 #elif defined(OS_Hurd)
1913 pid_is_child(pid_t pid
, pid_t ppid
)
1915 struct proc_stat
*ps
;
1916 struct procinfo
*pi
;
1918 ps
= get_proc_stat(pid
, PSTAT_PROC_INFO
);
1922 pi
= proc_stat_proc_info(ps
);
1924 return pi
->ppid
== ppid
;
1926 #elif defined(OS_Darwin)
1928 pid_is_child(pid_t pid
, pid_t ppid
)
1930 struct proc_bsdinfo info
;
1932 if (proc_pidinfo(pid
, PROC_PIDTBSDINFO
, 0, &info
, sizeof(info
)) < 0)
1935 return (pid_t
)info
.pbi_ppid
== ppid
;
1937 #elif defined(OS_AIX)
1939 pid_is_child(pid_t pid
, pid_t ppid
)
1943 if (!proc_get_psinfo(pid
, &psi
))
1946 return (pid_t
)psi
.pr_ppid
== ppid
;
1948 #elif defined(OS_HPUX)
1950 pid_is_child(pid_t pid
, pid_t ppid
)
1952 struct pst_status pst
;
1954 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
1957 return pst
.pst_ppid
== ppid
;
1959 #elif defined(OS_FreeBSD)
1961 pid_is_child(pid_t pid
, pid_t ppid
)
1963 struct kinfo_proc kp
;
1969 mib
[2] = KERN_PROC_PID
;
1973 rc
= sysctl(mib
, 4, &kp
, &len
, NULL
, 0);
1974 if (rc
!= 0 && errno
!= ESRCH
)
1976 if (len
== 0 || len
!= sizeof(kp
))
1979 return kp
.ki_ppid
== ppid
;
1981 #elif defined(HAVE_KVM_H)
1983 pid_is_child(pid_t pid
, pid_t ppid
)
1986 struct kinfo_proc
*kp
;
1990 kd
= ssd_kvm_open();
1991 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
1995 #if defined(OS_FreeBSD)
1996 proc_ppid
= kp
->ki_ppid
;
1997 #elif defined(OS_OpenBSD)
1998 proc_ppid
= kp
->p_ppid
;
1999 #elif defined(OS_DragonFlyBSD)
2000 proc_ppid
= kp
->kp_ppid
;
2002 proc_ppid
= kp
->kp_proc
.p_ppid
;
2005 res
= (proc_ppid
== ppid
);
2014 #if defined(OS_Linux)
2016 pid_is_user(pid_t pid
, uid_t uid
)
2021 sprintf(buf
, "/proc/%d", pid
);
2022 if (stat(buf
, &sb
) != 0)
2024 return (sb
.st_uid
== uid
);
2026 #elif defined(OS_Hurd)
2028 pid_is_user(pid_t pid
, uid_t uid
)
2030 struct proc_stat
*ps
;
2032 ps
= get_proc_stat(pid
, PSTAT_OWNER_UID
);
2033 return ps
&& (uid_t
)proc_stat_owner_uid(ps
) == uid
;
2035 #elif defined(OS_Darwin)
2037 pid_is_user(pid_t pid
, uid_t uid
)
2039 struct proc_bsdinfo info
;
2041 if (proc_pidinfo(pid
, PROC_PIDTBSDINFO
, 0, &info
, sizeof(info
)) < 0)
2044 return info
.pbi_ruid
== uid
;
2046 #elif defined(OS_AIX)
2048 pid_is_user(pid_t pid
, uid_t uid
)
2052 if (!proc_get_psinfo(pid
, &psi
))
2055 return psi
.pr_uid
== uid
;
2057 #elif defined(OS_HPUX)
2059 pid_is_user(pid_t pid
, uid_t uid
)
2061 struct pst_status pst
;
2063 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
2065 return ((uid_t
)pst
.pst_uid
== uid
);
2067 #elif defined(OS_FreeBSD)
2069 pid_is_user(pid_t pid
, uid_t uid
)
2071 struct kinfo_proc kp
;
2077 mib
[2] = KERN_PROC_PID
;
2081 rc
= sysctl(mib
, 4, &kp
, &len
, NULL
, 0);
2082 if (rc
!= 0 && errno
!= ESRCH
)
2084 if (len
== 0 || len
!= sizeof(kp
))
2087 return kp
.ki_ruid
== uid
;
2089 #elif defined(HAVE_KVM_H)
2091 pid_is_user(pid_t pid
, uid_t uid
)
2095 struct kinfo_proc
*kp
;
2098 kd
= ssd_kvm_open();
2099 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
2103 #if defined(OS_FreeBSD)
2104 proc_uid
= kp
->ki_ruid
;
2105 #elif defined(OS_OpenBSD)
2106 proc_uid
= kp
->p_ruid
;
2107 #elif defined(OS_DragonFlyBSD)
2108 proc_uid
= kp
->kp_ruid
;
2109 #elif defined(OS_NetBSD)
2110 proc_uid
= kp
->kp_eproc
.e_pcred
.p_ruid
;
2112 if (kp
->kp_proc
.p_cred
)
2113 kvm_read(kd
, (u_long
)&(kp
->kp_proc
.p_cred
->p_ruid
),
2114 &proc_uid
, sizeof(uid_t
));
2119 res
= (proc_uid
== (uid_t
)uid
);
2128 #if defined(OS_Linux)
2130 pid_is_cmd(pid_t pid
, const char *name
)
2134 comm
= proc_status_field(pid
, "Name:");
2138 return strcmp(comm
, name
) == 0;
2140 #elif defined(OS_Hurd)
2142 pid_is_cmd(pid_t pid
, const char *name
)
2144 struct proc_stat
*ps
;
2147 const char *binary_name
;
2149 ps
= get_proc_stat(pid
, PSTAT_ARGS
);
2153 argv0
= proc_stat_args(ps
);
2154 argv0_len
= strlen(argv0
) + 1;
2156 binary_name
= basename(argv0
);
2157 if (strcmp(binary_name
, name
) == 0)
2160 /* XXX: This is all kinds of ugly, but on the Hurd there's no way to
2161 * know the command name of a process, so we have to try to match
2162 * also on argv[1] for the case of an interpreted script. */
2163 if (proc_stat_args_len(ps
) > argv0_len
) {
2164 const char *script_name
= basename(argv0
+ argv0_len
);
2166 return strcmp(script_name
, name
) == 0;
2171 #elif defined(OS_AIX)
2173 pid_is_cmd(pid_t pid
, const char *name
)
2177 if (!proc_get_psinfo(pid
, &psi
))
2180 return strcmp(psi
.pr_fname
, name
) == 0;
2182 #elif defined(OS_HPUX)
2184 pid_is_cmd(pid_t pid
, const char *name
)
2186 struct pst_status pst
;
2188 if (pstat_getproc(&pst
, sizeof(pst
), (size_t)0, (int)pid
) < 0)
2190 return (strcmp(pst
.pst_ucomm
, name
) == 0);
2192 #elif defined(OS_Darwin)
2194 pid_is_cmd(pid_t pid
, const char *name
)
2196 char pathname
[_POSIX_PATH_MAX
];
2198 if (proc_pidpath(pid
, pathname
, sizeof(pathname
)) < 0)
2201 return strcmp(pathname
, name
) == 0;
2203 #elif defined(OS_FreeBSD)
2205 pid_is_cmd(pid_t pid
, const char *name
)
2207 struct kinfo_proc kp
;
2213 mib
[2] = KERN_PROC_PID
;
2217 rc
= sysctl(mib
, 4, &kp
, &len
, NULL
, 0);
2218 if (rc
!= 0 && errno
!= ESRCH
)
2220 if (len
== 0 || len
!= sizeof(kp
))
2223 return strcmp(kp
.ki_comm
, name
) == 0;
2225 #elif defined(HAVE_KVM_H)
2227 pid_is_cmd(pid_t pid
, const char *name
)
2230 struct kinfo_proc
*kp
;
2234 kd
= ssd_kvm_open();
2235 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_PID
, pid
, NULL
);
2239 #if defined(OS_FreeBSD)
2240 process_name
= kp
->ki_comm
;
2241 #elif defined(OS_OpenBSD)
2242 process_name
= kp
->p_comm
;
2243 #elif defined(OS_DragonFlyBSD)
2244 process_name
= kp
->kp_comm
;
2246 process_name
= kp
->kp_proc
.p_comm
;
2249 res
= (strcmp(name
, process_name
) == 0);
2258 #if defined(OS_Hurd)
2260 pid_is_running(pid_t pid
)
2262 return get_proc_stat(pid
, 0) != NULL
;
2264 #else /* !OS_Hurd */
2266 pid_is_running(pid_t pid
)
2268 if (kill(pid
, 0) == 0 || errno
== EPERM
)
2270 else if (errno
== ESRCH
)
2273 fatale("error checking pid %u status", pid
);
2277 static enum status_code
2278 pid_check(pid_t pid
)
2280 if (execname
&& !pid_is_exec(pid
, &exec_stat
))
2282 if (match_ppid
> 0 && !pid_is_child(pid
, match_ppid
))
2284 if (userspec
&& !pid_is_user(pid
, user_id
))
2286 if (cmdname
&& !pid_is_cmd(pid
, cmdname
))
2288 if (action
!= ACTION_STOP
&& !pid_is_running(pid
))
2291 pid_list_push(&found
, pid
);
2296 static enum status_code
2297 do_pidfile(const char *name
)
2300 static pid_t pid
= 0;
2303 return pid_check(pid
);
2305 f
= fopen(name
, "r");
2307 enum status_code pid_status
;
2309 /* If we are only matching on the pidfile, and it is owned by
2310 * a non-root user, then this is a security risk, and the
2311 * contents cannot be trusted, because the daemon might have
2314 * If the pidfile is world-writable we refuse to parse it.
2316 * If we got /dev/null specified as the pidfile, we ignore the
2317 * checks, as this is being used to run processes no matter
2319 if (strcmp(name
, "/dev/null") != 0) {
2323 if (fstat(fd
, &st
) < 0)
2324 fatale("cannot stat pidfile %s", name
);
2326 if (match_mode
== MATCH_PIDFILE
&&
2327 ((st
.st_uid
!= getuid() && st
.st_uid
!= 0) ||
2328 (st
.st_gid
!= getgid() && st
.st_gid
!= 0)))
2329 fatal("matching only on non-root pidfile %s is insecure", name
);
2330 if (st
.st_mode
& 0002)
2331 fatal("matching on world-writable pidfile %s is insecure", name
);
2334 if (fscanf(f
, "%d", &pid
) == 1)
2335 pid_status
= pid_check(pid
);
2337 pid_status
= STATUS_UNKNOWN
;
2340 if (pid_status
== STATUS_DEAD
)
2341 return STATUS_DEAD_PIDFILE
;
2344 } else if (errno
== ENOENT
)
2347 fatale("unable to open pidfile %s", name
);
2350 #if defined(OS_Linux) || defined(OS_Solaris) || defined(OS_AIX)
2351 static enum status_code
2355 struct dirent
*entry
;
2358 enum status_code prog_status
= STATUS_DEAD
;
2360 procdir
= opendir("/proc");
2362 fatale("unable to opendir /proc");
2365 while ((entry
= readdir(procdir
)) != NULL
) {
2366 enum status_code pid_status
;
2368 if (sscanf(entry
->d_name
, "%d", &pid
) != 1)
2372 pid_status
= pid_check(pid
);
2373 if (pid_status
< prog_status
)
2374 prog_status
= pid_status
;
2378 fatal("nothing in /proc - not mounted?");
2382 #elif defined(OS_Hurd)
2384 check_proc_stat(struct proc_stat
*ps
)
2386 pid_check(proc_stat_pid(ps
));
2390 static enum status_code
2396 proc_stat_list_for_each(procset
, check_proc_stat
);
2403 #elif defined(OS_Darwin)
2404 static enum status_code
2408 int i
, npids
, pid_bufsize
;
2409 enum status_code prog_status
= STATUS_DEAD
;
2411 npids
= proc_listallpids(NULL
, 0);
2413 return STATUS_UNKNOWN
;
2415 /* Try to avoid sudden changes in number of PIDs. */
2417 pid_bufsize
= sizeof(pid_t
) * npids
;
2418 pid_buf
= xmalloc(pid_bufsize
);
2420 npids
= proc_listallpids(pid_buf
, pid_bufsize
);
2422 return STATUS_UNKNOWN
;
2424 for (i
= 0; i
< npids
; i
++) {
2425 enum status_code pid_status
;
2427 pid_status
= pid_check(pid_buf
[i
]);
2428 if (pid_status
< prog_status
)
2429 prog_status
= pid_status
;
2436 #elif defined(OS_HPUX)
2437 static enum status_code
2440 struct pst_status pst
[10];
2443 enum status_code prog_status
= STATUS_DEAD
;
2445 while ((count
= pstat_getproc(pst
, sizeof(pst
[0]), 10, idx
)) > 0) {
2446 enum status_code pid_status
;
2448 for (i
= 0; i
< count
; i
++) {
2449 pid_status
= pid_check(pst
[i
].pst_pid
);
2450 if (pid_status
< prog_status
)
2451 prog_status
= pid_status
;
2453 idx
= pst
[count
- 1].pst_idx
+ 1;
2458 #elif defined(OS_FreeBSD)
2459 static enum status_code
2462 struct kinfo_proc
*kp
;
2466 enum status_code prog_status
= STATUS_DEAD
;
2470 mib
[2] = KERN_PROC_PROC
;
2472 rc
= sysctl(mib
, 3, NULL
, &len
, NULL
, 0);
2473 if (rc
!= 0 && errno
!= ESRCH
)
2474 return STATUS_UNKNOWN
;
2476 return STATUS_UNKNOWN
;
2479 rc
= sysctl(mib
, 3, kp
, &len
, NULL
, 0);
2480 if (rc
!= 0 && errno
!= ESRCH
)
2481 return STATUS_UNKNOWN
;
2483 return STATUS_UNKNOWN
;
2484 nentries
= len
/ sizeof(*kp
);
2486 for (i
= 0; i
< nentries
; i
++) {
2487 enum status_code pid_status
;
2489 pid_status
= pid_check(kp
[i
].ki_pid
);
2490 if (pid_status
< prog_status
)
2491 prog_status
= pid_status
;
2498 #elif defined(HAVE_KVM_H)
2499 static enum status_code
2504 struct kinfo_proc
*kp
;
2505 enum status_code prog_status
= STATUS_DEAD
;
2507 kd
= ssd_kvm_open();
2508 kp
= ssd_kvm_get_procs(kd
, KERN_PROC_ALL
, 0, &nentries
);
2510 for (i
= 0; i
< nentries
; i
++) {
2511 enum status_code pid_status
;
2514 #if defined(OS_FreeBSD)
2516 #elif defined(OS_OpenBSD)
2518 #elif defined(OS_DragonFlyBSD)
2521 pid
= kp
[i
].kp_proc
.p_pid
;
2524 pid_status
= pid_check(pid
);
2525 if (pid_status
< prog_status
)
2526 prog_status
= pid_status
;
2535 static enum status_code
2538 pid_list_free(&found
);
2541 return pid_check(match_pid
);
2543 return do_pidfile(pidfile
);
2545 return do_procinit();
2549 do_start(int argc
, char **argv
)
2551 int devnull_fd
= -1;
2559 info("%s already running.\n", execname
? execname
: "process");
2562 if (testmode
&& quietmode
<= 0) {
2563 printf("Would start %s ", startas
);
2565 printf("%s ", *argv
++);
2566 if (changeuser
!= NULL
) {
2567 printf(" (as user %s[%d]", changeuser
, runas_uid
);
2568 if (changegroup
!= NULL
)
2569 printf(", and group %s[%d])", changegroup
, runas_gid
);
2573 if (changeroot
!= NULL
)
2574 printf(" in directory %s", changeroot
);
2576 printf(", and add %i to the priority", nicelevel
);
2578 printf(", with scheduling policy %s with priority %i",
2579 proc_sched
->policy_name
, proc_sched
->priority
);
2581 printf(", with IO scheduling class %s with priority %i",
2582 io_sched
->policy_name
, io_sched
->priority
);
2587 debug("Starting %s...\n", startas
);
2589 if (umask_value
>= 0)
2592 /* Ok, we need to detach this process. */
2594 else if (mpidfile
&& pidfile
!= NULL
)
2595 /* User wants _us_ to make the pidfile, but detach themself! */
2596 write_pidfile(pidfile
, getpid());
2597 if (background
&& close_io
) {
2598 devnull_fd
= open("/dev/null", O_RDONLY
);
2600 fatale("unable to open '%s'", "/dev/null");
2602 if (background
&& output_io
) {
2603 output_fd
= open(output_io
, O_CREAT
| O_WRONLY
| O_APPEND
, 0664);
2605 fatale("unable to open '%s'", output_io
);
2609 if ((nice(nicelevel
) == -1) && (errno
!= 0))
2610 fatale("unable to alter nice level by %i", nicelevel
);
2613 set_proc_schedule(proc_sched
);
2615 set_io_schedule(io_sched
);
2616 if (changeroot
!= NULL
) {
2617 if (chdir(changeroot
) < 0)
2618 fatale("unable to chdir() to %s", changeroot
);
2619 if (chroot(changeroot
) < 0)
2620 fatale("unable to chroot() to %s", changeroot
);
2622 if (chdir(changedir
) < 0)
2623 fatale("unable to chdir() to %s", changedir
);
2627 if (changegroup
!= NULL
) {
2628 if (rgid
!= (gid_t
)runas_gid
)
2629 if (setgid(runas_gid
))
2630 fatale("unable to set gid to %d", runas_gid
);
2632 if (changeuser
!= NULL
) {
2633 /* We assume that if our real user and group are the same as
2634 * the ones we should switch to, the supplementary groups
2635 * will be already in place. */
2636 if (rgid
!= (gid_t
)runas_gid
|| ruid
!= (uid_t
)runas_uid
)
2637 if (initgroups(changeuser
, runas_gid
))
2638 fatale("unable to set initgroups() with gid %d",
2641 if (ruid
!= (uid_t
)runas_uid
)
2642 if (setuid(runas_uid
))
2643 fatale("unable to set uid to %s", changeuser
);
2646 if (background
&& output_fd
>= 0) {
2647 dup2(output_fd
, 1); /* stdout */
2648 dup2(output_fd
, 2); /* stderr */
2650 if (background
&& close_io
) {
2653 dup2(devnull_fd
, 0); /* stdin */
2655 /* Now close all extra fds. */
2656 for (i
= get_open_fd_max() - 1; i
>= 3; --i
)
2659 execv(startas
, argv
);
2660 fatale("unable to start %s", startas
);
2664 do_stop(int sig_num
, int *n_killed
, int *n_notkilled
)
2676 pid_list_free(&killed
);
2678 for (p
= found
; p
; p
= p
->next
) {
2680 info("Would send signal %d to %d.\n", sig_num
, p
->pid
);
2682 } else if (kill(p
->pid
, sig_num
) == 0) {
2683 pid_list_push(&killed
, p
->pid
);
2687 warning("failed to kill %d: %s\n",
2688 p
->pid
, strerror(errno
));
2695 do_stop_summary(int retry_nr
)
2699 if (quietmode
>= 0 || !killed
)
2702 printf("Stopped %s (pid", what_stop
);
2703 for (p
= killed
; p
; p
= p
->next
)
2704 printf(" %d", p
->pid
);
2707 printf(", retry #%d", retry_nr
);
2711 static void LIBCOMPAT_ATTR_PRINTF(1)
2712 set_what_stop(const char *format
, ...)
2717 va_start(arglist
, format
);
2718 rc
= vasprintf(&what_stop
, format
, arglist
);
2722 fatale("cannot allocate formatted string");
2726 * We want to keep polling for the processes, to see if they've exited, or
2727 * until the timeout expires.
2729 * This is a somewhat complicated algorithm to try to ensure that we notice
2730 * reasonably quickly when all the processes have exited, but don't spend
2731 * too much CPU time polling. In particular, on a fast machine with
2732 * quick-exiting daemons we don't want to delay system shutdown too much,
2733 * whereas on a slow one, or where processes are taking some time to exit,
2734 * we want to increase the polling interval.
2736 * The algorithm is as follows: we measure the elapsed time it takes to do
2737 * one poll(), and wait a multiple of this time for the next poll. However,
2738 * if that would put us past the end of the timeout period we wait only as
2739 * long as the timeout period, but in any case we always wait at least
2740 * MIN_POLL_INTERVAL (20ms). The multiple (‘ratio’) starts out as 2, and
2741 * increases by 1 for each poll to a maximum of 10; so we use up to between
2742 * 30% and 10% of the machine's resources (assuming a few reasonable things
2743 * about system performance).
2746 do_stop_timeout(int timeout
, int *n_killed
, int *n_notkilled
)
2748 struct timespec stopat
, before
, after
, interval
, maxinterval
;
2751 timespec_gettime(&stopat
);
2752 stopat
.tv_sec
+= timeout
;
2755 timespec_gettime(&before
);
2756 if (timespec_cmp(&before
, &stopat
, >))
2759 do_stop(0, n_killed
, n_notkilled
);
2763 timespec_gettime(&after
);
2765 if (!timespec_cmp(&after
, &stopat
, <))
2771 timespec_sub(&stopat
, &after
, &maxinterval
);
2772 timespec_sub(&after
, &before
, &interval
);
2773 timespec_mul(&interval
, ratio
);
2775 if (interval
.tv_sec
< 0 || interval
.tv_nsec
< 0)
2776 interval
.tv_sec
= interval
.tv_nsec
= 0;
2778 if (timespec_cmp(&interval
, &maxinterval
, >))
2779 interval
= maxinterval
;
2781 if (interval
.tv_sec
== 0 &&
2782 interval
.tv_nsec
<= MIN_POLL_INTERVAL
)
2783 interval
.tv_nsec
= MIN_POLL_INTERVAL
;
2785 rc
= pselect(0, NULL
, NULL
, NULL
, &interval
, NULL
);
2786 if (rc
< 0 && errno
!= EINTR
)
2787 fatale("select() failed for pause");
2792 finish_stop_schedule(bool anykilled
)
2794 if (rpidfile
&& pidfile
&& !testmode
)
2795 remove_pidfile(pidfile
);
2800 info("No %s found running; none killed.\n", what_stop
);
2806 run_stop_schedule(void)
2808 int position
, n_killed
, n_notkilled
, value
, retry_nr
;
2812 if (schedule
!= NULL
) {
2813 info("Ignoring --retry in test mode\n");
2819 set_what_stop("%s", cmdname
);
2821 set_what_stop("%s", execname
);
2823 set_what_stop("process in pidfile '%s'", pidfile
);
2824 else if (match_pid
> 0)
2825 set_what_stop("process with pid %d", match_pid
);
2826 else if (match_ppid
> 0)
2827 set_what_stop("process(es) with parent pid %d", match_ppid
);
2829 set_what_stop("process(es) owned by '%s'", userspec
);
2831 BUG("no match option, please report");
2838 if (schedule
== NULL
) {
2839 do_stop(signal_nr
, &n_killed
, &n_notkilled
);
2841 if (n_notkilled
> 0)
2842 info("%d pids were not killed\n", n_notkilled
);
2845 return finish_stop_schedule(anykilled
);
2848 for (position
= 0; position
< schedule_length
; position
++) {
2850 value
= schedule
[position
].value
;
2853 switch (schedule
[position
].type
) {
2858 do_stop(value
, &n_killed
, &n_notkilled
);
2859 do_stop_summary(retry_nr
++);
2861 return finish_stop_schedule(anykilled
);
2866 if (do_stop_timeout(value
, &n_killed
, &n_notkilled
))
2867 return finish_stop_schedule(anykilled
);
2871 BUG("schedule[%d].type value %d is not valid",
2872 position
, schedule
[position
].type
);
2876 info("Program %s, %d process(es), refused to die.\n",
2877 what_stop
, n_killed
);
2883 main(int argc
, char **argv
)
2887 parse_options(argc
, argv
);
2893 if (action
== ACTION_START
)
2894 return do_start(argc
, argv
);
2895 else if (action
== ACTION_STOP
)
2896 return run_stop_schedule();
2897 else if (action
== ACTION_STATUS
)
2898 return do_findprocs();