/[baselayout]/trunk/src/start-stop-daemon.c
Gentoo

Diff of /trunk/src/start-stop-daemon.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2837 Revision 2838
6 6
7 This is essentially a ground up re-write of Debians 7 This is essentially a ground up re-write of Debians
8 start-stop-daemon for cleaner code and to integrate into our RC 8 start-stop-daemon for cleaner code and to integrate into our RC
9 system so we can monitor daemons a little. 9 system so we can monitor daemons a little.
10 */ 10 */
11
12#define APPLET "start-stop-daemon"
11 13
12/* nano seconds */ 14/* nano seconds */
13#define POLL_INTERVAL 20000000 15#define POLL_INTERVAL 20000000
14#define START_WAIT 100000000 16#define START_WAIT 100000000
15#define ONE_SECOND 1000000000 17#define ONE_SECOND 1000000000
61 struct schedulelist *gotolist; 63 struct schedulelist *gotolist;
62 struct schedulelist *next; 64 struct schedulelist *next;
63} schedulelist_t; 65} schedulelist_t;
64static schedulelist_t *schedule; 66static schedulelist_t *schedule;
65 67
66static char *progname; 68static char *applet;
67static char *changeuser; 69static char *changeuser;
68static char **newenv; 70static char **newenv;
69 71
70extern char **environ; 72extern char **environ;
71 73
131 return (-1); 133 return (-1);
132 134
133 if (sscanf (sig, "%u", &i) == 1) { 135 if (sscanf (sig, "%u", &i) == 1) {
134 if (i > 0 && i < sizeof (signallist) / sizeof (signallist[0])) 136 if (i > 0 && i < sizeof (signallist) / sizeof (signallist[0]))
135 return (i); 137 return (i);
136 eerrorx ("%s: `%s' is not a valid signal", progname, sig); 138 eerrorx ("%s: `%s' is not a valid signal", applet, sig);
137 } 139 }
138 140
139 if (strncmp (sig, "SIG", 3) == 0) 141 if (strncmp (sig, "SIG", 3) == 0)
140 s = (char *) sig + 3; 142 s = (char *) sig + 3;
141 else 143 else
144 for (i = 0; i < sizeof (signallist) / sizeof (signallist[0]); i++) 146 for (i = 0; i < sizeof (signallist) / sizeof (signallist[0]); i++)
145 if (strcmp (sig, signallist[i].name) == 0 || 147 if (strcmp (sig, signallist[i].name) == 0 ||
146 (s && strcmp (s, signallist[i].name) == 0)) 148 (s && strcmp (s, signallist[i].name) == 0))
147 return (signallist[i].signal); 149 return (signallist[i].signal);
148 150
149 eerrorx ("%s: `%s' is not a valid signal", progname, sig); 151 eerrorx ("%s: `%s' is not a valid signal", applet, sig);
150} 152}
151 153
152static void parse_schedule_item (schedulelist_t *item, const char *string) 154static void parse_schedule_item (schedulelist_t *item, const char *string)
153{ 155{
154 const char *after_hyph; 156 const char *after_hyph;
158 item->type = schedule_forever; 160 item->type = schedule_forever;
159 else if (isdigit (string[0])) { 161 else if (isdigit (string[0])) {
160 item->type = schedule_timeout; 162 item->type = schedule_timeout;
161 errno = 0; 163 errno = 0;
162 if (sscanf (string, "%d", &item->value) != 1) 164 if (sscanf (string, "%d", &item->value) != 1)
163 eerrorx ("%s: invalid timeout value in schedule `%s'", progname, 165 eerrorx ("%s: invalid timeout value in schedule `%s'", applet,
164 string); 166 string);
165 } else if ((after_hyph = string + (string[0] == '-')) && 167 } else if ((after_hyph = string + (string[0] == '-')) &&
166 ((sig = parse_signal (after_hyph)) != -1)) 168 ((sig = parse_signal (after_hyph)) != -1))
167 { 169 {
168 item->type = schedule_signal; 170 item->type = schedule_signal;
169 item->value = (int) sig; 171 item->value = (int) sig;
170 } 172 }
171 else 173 else
172 eerrorx ("%s: invalid schedule item `%s'", progname, string); 174 eerrorx ("%s: invalid schedule item `%s'", applet, string);
173} 175}
174 176
175static void parse_schedule (const char *string, int default_signal) 177static void parse_schedule (const char *string, int default_signal)
176{ 178{
177 char buffer[20]; 179 char buffer[20];
199 next = schedule->next; 201 next = schedule->next;
200 next->type = schedule_timeout; 202 next->type = schedule_timeout;
201 next->gotolist = NULL; 203 next->gotolist = NULL;
202 if (string) { 204 if (string) {
203 if (sscanf (string, "%d", &next->value) != 1) 205 if (sscanf (string, "%d", &next->value) != 1)
204 eerrorx ("%s: invalid timeout value in schedule", progname); 206 eerrorx ("%s: invalid timeout value in schedule", applet);
205 } 207 }
206 else 208 else
207 next->value = 5; 209 next->value = 5;
208 next->next = NULL; 210 next->next = NULL;
209 211
216 len = slash - string; 218 len = slash - string;
217 else 219 else
218 len = strlen (string); 220 len = strlen (string);
219 221
220 if (len >= (ptrdiff_t) sizeof (buffer)) 222 if (len >= (ptrdiff_t) sizeof (buffer))
221 eerrorx ("%s: invalid schedule item, far too long", progname); 223 eerrorx ("%s: invalid schedule item, far too long", applet);
222 224
223 memcpy (buffer, string, len); 225 memcpy (buffer, string, len);
224 buffer[len] = 0; 226 buffer[len] = 0;
225 string = slash ? slash + 1 : NULL; 227 string = slash ? slash + 1 : NULL;
226 228
227 parse_schedule_item (next, buffer); 229 parse_schedule_item (next, buffer);
228 if (next->type == schedule_forever) { 230 if (next->type == schedule_forever) {
229 if (repeatat) 231 if (repeatat)
230 eerrorx ("%s: invalid schedule, `forever' appears more than once", 232 eerrorx ("%s: invalid schedule, `forever' appears more than once",
231 progname); 233 applet);
232 234
233 repeatat = next; 235 repeatat = next;
234 continue; 236 continue;
235 } 237 }
236 238
261 if (! pidfile) 263 if (! pidfile)
262 return (-1); 264 return (-1);
263 265
264 if ((fp = fopen (pidfile, "r")) == NULL) { 266 if ((fp = fopen (pidfile, "r")) == NULL) {
265 if (! quiet) 267 if (! quiet)
266 eerror ("%s: fopen `%s': %s", progname, pidfile, strerror (errno)); 268 eerror ("%s: fopen `%s': %s", applet, pidfile, strerror (errno));
267 return (-1); 269 return (-1);
268 } 270 }
269 271
270 if (fscanf (fp, "%d", &pid) != 1) { 272 if (fscanf (fp, "%d", &pid) != 1) {
271 if (! quiet) 273 if (! quiet)
272 eerror ("%s: no pid found in `%s'", progname, pidfile); 274 eerror ("%s: no pid found in `%s'", applet, pidfile);
273 fclose (fp); 275 fclose (fp);
274 return (-1); 276 return (-1);
275 } 277 }
276 fclose (fp); 278 fclose (fp);
277 279
309 errno = 0; 311 errno = 0;
310 killed = (kill (pids[i], sig) == 0 || errno == ESRCH ? true : false); 312 killed = (kill (pids[i], sig) == 0 || errno == ESRCH ? true : false);
311 if (! killed) { 313 if (! killed) {
312 if (! quiet) 314 if (! quiet)
313 eerror ("%s: failed to send signal %d to PID %d: %s", 315 eerror ("%s: failed to send signal %d to PID %d: %s",
314 progname, sig, pids[i], strerror (errno)); 316 applet, sig, pids[i], strerror (errno));
315 if (verbose) 317 if (verbose)
316 eend (1, NULL); 318 eend (1, NULL);
317 nkilled = -1; 319 nkilled = -1;
318 } else { 320 } else {
319 if (verbose) 321 if (verbose)
360 nkilled = do_stop (exec, cmd, pidfile, uid, item->value, 362 nkilled = do_stop (exec, cmd, pidfile, uid, item->value,
361 quiet, verbose, test); 363 quiet, verbose, test);
362 if (nkilled == 0) { 364 if (nkilled == 0) {
363 if (tkilled == 0) { 365 if (tkilled == 0) {
364 if (! quiet) 366 if (! quiet)
365 eerror ("%s: no matching processes found", progname); 367 eerror ("%s: no matching processes found", applet);
366 } 368 }
367 return (tkilled); 369 return (tkilled);
368 } 370 }
369 else if (nkilled == -1) 371 else if (nkilled == -1)
370 return (0); 372 return (0);
386 uid, 0, true, false, true)) == 0) 388 uid, 0, true, false, true)) == 0)
387 return (true); 389 return (true);
388 390
389 if (nanosleep (&ts, NULL) == -1) { 391 if (nanosleep (&ts, NULL) == -1) {
390 if (errno == EINTR) 392 if (errno == EINTR)
391 eerror ("%s: caught an interupt", progname); 393 eerror ("%s: caught an interupt", applet);
392 else { 394 else {
393 eerror ("%s: nanosleep: %s", progname, strerror (errno)); 395 eerror ("%s: nanosleep: %s", applet, strerror (errno));
394 return (0); 396 return (0);
395 } 397 }
396 } 398 }
397 nloops --; 399 nloops --;
398 } 400 }
399 break; 401 break;
400 402
401 default: 403 default:
402 eerror ("%s: invalid schedule item `%d'", progname, item->type); 404 eerror ("%s: invalid schedule item `%d'", applet, item->type);
403 return (0); 405 return (0);
404 } 406 }
405 407
406 if (item) 408 if (item)
407 item = item->next; 409 item = item->next;
410 if (test || (tkilled > 0 && nrunning == 0)) 412 if (test || (tkilled > 0 && nrunning == 0))
411 return (nkilled); 413 return (nkilled);
412 414
413 if (! quiet) { 415 if (! quiet) {
414 if (nrunning == 1) 416 if (nrunning == 1)
415 eerror ("%s: %d process refused to stop", progname, nrunning); 417 eerror ("%s: %d process refused to stop", applet, nrunning);
416 else 418 else
417 eerror ("%s: %d process(es) refused to stop", progname, nrunning); 419 eerror ("%s: %d process(es) refused to stop", applet, nrunning);
418 } 420 }
419 421
420 return (-nrunning); 422 return (-nrunning);
421} 423}
422 424
435 if (! signame[0]) 437 if (! signame[0])
436 snprintf (signame, sizeof (signame), "SIGTERM"); 438 snprintf (signame, sizeof (signame), "SIGTERM");
437 case SIGQUIT: 439 case SIGQUIT:
438 if (! signame[0]) 440 if (! signame[0])
439 snprintf (signame, sizeof (signame), "SIGQUIT"); 441 snprintf (signame, sizeof (signame), "SIGQUIT");
440 eerrorx ("%s: caught %s, aborting", progname, signame); 442 eerrorx ("%s: caught %s, aborting", applet, signame);
441 443
442 case SIGCHLD: 444 case SIGCHLD:
443 while (1) { 445 while (1) {
444 if ((pid = waitpid (-1, &status, WNOHANG)) < 0) { 446 if ((pid = waitpid (-1, &status, WNOHANG)) < 0) {
445 if (errno != ECHILD) 447 if (errno != ECHILD)
446 eerror ("%s: waitpid: %s", progname, strerror (errno)); 448 eerror ("%s: waitpid: %s", applet, strerror (errno));
447 break; 449 break;
448 } 450 }
449 } 451 }
450 break; 452 break;
451 453
452 default: 454 default:
453 eerror ("%s: caught unknown signal %d", progname, sig); 455 eerror ("%s: caught unknown signal %d", applet, sig);
454 } 456 }
455 457
456 /* Restore errno */ 458 /* Restore errno */
457 errno = serrno; 459 errno = serrno;
458} 460}
459 461
462
463#include "_usage.h"
464#define getoptstring "KN:R:Sbc:d:g:mn:op:qs:tu:r:vx:1:2:" getoptstring_COMMON
465static struct option longopts[] = {
466 { "stop", 0, NULL, 'K'},
467 { "nicelevel", 1, NULL, 'N'},
468 { "retry", 1, NULL, 'R'},
469 { "start", 0, NULL, 'S'},
470 { "startas", 1, NULL, 'a'},
471 { "background", 0, NULL, 'b'},
472 { "chuid", 1, NULL, 'c'},
473 { "chdir", 1, NULL, 'd'},
474 { "group", 1, NULL, 'g'},
475 { "make-pidfile", 0, NULL, 'm'},
476 { "name", 1, NULL, 'n'},
477 { "oknodo", 0, NULL, 'o'},
478 { "pidfile", 1, NULL, 'p'},
479 { "quiet", 0, NULL, 'q'},
480 { "signal", 1, NULL, 's'},
481 { "test", 0, NULL, 't'},
482 { "user", 1, NULL, 'u'},
483 { "chroot", 1, NULL, 'r'},
484 { "verbose", 0, NULL, 'v'},
485 { "exec", 1, NULL, 'x'},
486 { "stdout", 1, NULL, '1'},
487 { "stderr", 1, NULL, '2'},
488 longopts_COMMON
489 { NULL, 0, NULL, 0}
490};
491#include "_usage.c"
492
460int start_stop_daemon (int argc, char **argv) 493int start_stop_daemon (int argc, char **argv)
461{ 494{
462 int devnull_fd = -1; 495 int devnull_fd = -1;
463
464#ifdef TIOCNOTTY 496#ifdef TIOCNOTTY
465 int tty_fd = -1; 497 int tty_fd = -1;
466#endif 498#endif
499
467#ifdef HAVE_PAM 500#ifdef HAVE_PAM
468 pam_handle_t *pamh = NULL; 501 pam_handle_t *pamh = NULL;
469 int pamr; 502 int pamr;
470#endif 503#endif
471
472 static struct option longopts[] = {
473 { "stop", 0, NULL, 'K'},
474 { "nicelevel", 1, NULL, 'N'},
475 { "retry", 1, NULL, 'R'},
476 { "start", 0, NULL, 'S'},
477 { "startas", 1, NULL, 'a'},
478 { "background", 0, NULL, 'b'},
479 { "chuid", 1, NULL, 'c'},
480 { "chdir", 1, NULL, 'd'},
481 { "group", 1, NULL, 'g'},
482 { "make-pidfile", 0, NULL, 'm'},
483 { "name", 1, NULL, 'n'},
484 { "oknodo", 0, NULL, 'o'},
485 { "pidfile", 1, NULL, 'p'},
486 { "quiet", 0, NULL, 'q'},
487 { "signal", 1, NULL, 's'},
488 { "test", 0, NULL, 't'},
489 { "user", 1, NULL, 'u'},
490 { "chroot", 1, NULL, 'r'},
491 { "verbose", 0, NULL, 'v'},
492 { "exec", 1, NULL, 'x'},
493 { "stdout", 1, NULL, '1'},
494 { "stderr", 1, NULL, '2'},
495 { NULL, 0, NULL, 0}
496 };
497 504
498 int opt; 505 int opt;
499 bool start = false; 506 bool start = false;
500 bool stop = false; 507 bool stop = false;
501 bool oknodo = false; 508 bool oknodo = false;
521 pid_t pid; 528 pid_t pid;
522 int i; 529 int i;
523 char *svcname = getenv ("SVCNAME"); 530 char *svcname = getenv ("SVCNAME");
524 char *env; 531 char *env;
525 532
526 progname = argv[0]; 533 applet = argv[0];
527 atexit (cleanup); 534 atexit (cleanup);
528 535
529 signal (SIGINT, handle_signal); 536 signal (SIGINT, handle_signal);
530 signal (SIGQUIT, handle_signal); 537 signal (SIGQUIT, handle_signal);
531 signal (SIGTERM, handle_signal); 538 signal (SIGTERM, handle_signal);
532 539
533 if ((env = getenv ("SSD_NICELEVEL"))) 540 if ((env = getenv ("SSD_NICELEVEL")))
534 if (sscanf (env, "%d", &nicelevel) != 1) 541 if (sscanf (env, "%d", &nicelevel) != 1)
535 eerror ("%s: invalid nice level `%s' (SSD_NICELEVEL)", progname, env); 542 eerror ("%s: invalid nice level `%s' (SSD_NICELEVEL)", applet, env);
536 543
537 while ((opt = getopt_long (argc, argv, 544 while ((opt = getopt_long (argc, argv, getoptstring, longopts,
538 "KN:R:Sbc:d:g:mn:op:qs:tu:r:vx:1:2:",
539 longopts, (int *) 0)) != -1) 545 (int *) 0)) != -1)
540 switch (opt) { 546 switch (opt) {
541 case 'K': /* --stop */ 547 case 'K': /* --stop */
542 stop = true; 548 stop = true;
543 break; 549 break;
544 550
545 case 'N': /* --nice */ 551 case 'N': /* --nice */
546 if (sscanf (optarg, "%d", &nicelevel) != 1) 552 if (sscanf (optarg, "%d", &nicelevel) != 1)
547 eerrorx ("%s: invalid nice level `%s'", progname, optarg); 553 eerrorx ("%s: invalid nice level `%s'", applet, optarg);
548 break; 554 break;
549 555
550 case 'R': /* --retry <schedule>|<timeout> */ 556 case 'R': /* --retry <schedule>|<timeout> */
551 parse_schedule (optarg, sig); 557 parse_schedule (optarg, sig);
552 break; 558 break;
570 pw = getpwnam (cu); 576 pw = getpwnam (cu);
571 else 577 else
572 pw = getpwuid (tid); 578 pw = getpwuid (tid);
573 579
574 if (! pw) 580 if (! pw)
575 eerrorx ("%s: user `%s' not found", progname, cu); 581 eerrorx ("%s: user `%s' not found", applet, cu);
576 uid = pw->pw_uid; 582 uid = pw->pw_uid;
577 if (! gid) 583 if (! gid)
578 gid = pw->pw_gid; 584 gid = pw->pw_gid;
579 585
580 if (p) { 586 if (p) {
585 gr = getgrnam (cg); 591 gr = getgrnam (cg);
586 else 592 else
587 gr = getgrgid (tid); 593 gr = getgrgid (tid);
588 594
589 if (! gr) 595 if (! gr)
590 eerrorx ("%s: group `%s' not found", progname, cg); 596 eerrorx ("%s: group `%s' not found", applet, cg);
591 gid = gr->gr_gid; 597 gid = gr->gr_gid;
592 } 598 }
593 } 599 }
594 break; 600 break;
595 601
605 gr = getgrnam (optarg); 611 gr = getgrnam (optarg);
606 else 612 else
607 gr = getgrgid (tid); 613 gr = getgrgid (tid);
608 614
609 if (! gr) 615 if (! gr)
610 eerrorx ("%s: group `%s' not found", progname, optarg); 616 eerrorx ("%s: group `%s' not found", applet, optarg);
611 gid = gr->gr_gid; 617 gid = gr->gr_gid;
612 } 618 }
613 break; 619 break;
614 620
615 case 'm': /* --make-pidfile */ 621 case 'm': /* --make-pidfile */
642 648
643 case 'u': /* --user <username>|<uid> */ 649 case 'u': /* --user <username>|<uid> */
644 if (sscanf (optarg, "%d", &tid) != 1) { 650 if (sscanf (optarg, "%d", &tid) != 1) {
645 struct passwd *pw = getpwnam (optarg); 651 struct passwd *pw = getpwnam (optarg);
646 if (! pw) 652 if (! pw)
647 eerrorx ("%s: user `%s' not found", progname, optarg); 653 eerrorx ("%s: user `%s' not found", applet, optarg);
648 uid = pw->pw_uid; 654 uid = pw->pw_uid;
649 } else 655 } else
650 uid = tid; 656 uid = tid;
651 break; 657 break;
652 658
669 675
670 case '2': /* --stderr /path/to/stderr.logfile */ 676 case '2': /* --stderr /path/to/stderr.logfile */
671 redirect_stderr = optarg; 677 redirect_stderr = optarg;
672 break; 678 break;
673 679
674 default: 680 case_RC_COMMON_GETOPT
675 exit (EXIT_FAILURE);
676 } 681 }
677 682
678 /* Respect RC as well as how we are called */ 683 /* Respect RC as well as how we are called */
679 if (rc_is_env ("RC_QUIET", "yes") && ! verbose) 684 if (rc_is_env ("RC_QUIET", "yes") && ! verbose)
680 quiet = true; 685 quiet = true;
690 oknodo = true; 695 oknodo = true;
691 stop = true; 696 stop = true;
692 } 697 }
693 698
694 if (start == stop) 699 if (start == stop)
695 eerrorx ("%s: need one of --start or --stop", progname); 700 eerrorx ("%s: need one of --start or --stop", applet);
696 701
697 if (start && ! exec) 702 if (start && ! exec)
698 eerrorx ("%s: --start needs --exec", progname); 703 eerrorx ("%s: --start needs --exec", applet);
699 704
700 if (stop && ! exec && ! pidfile && ! cmd && ! uid) 705 if (stop && ! exec && ! pidfile && ! cmd && ! uid)
701 eerrorx ("%s: --stop needs --exec, --pidfile, --name or --user", progname); 706 eerrorx ("%s: --stop needs --exec, --pidfile, --name or --user", applet);
702 707
703 if (makepidfile && ! pidfile) 708 if (makepidfile && ! pidfile)
704 eerrorx ("%s: --make-pidfile is only relevant with --pidfile", progname); 709 eerrorx ("%s: --make-pidfile is only relevant with --pidfile", applet);
705 710
706 if (background && ! start) 711 if (background && ! start)
707 eerrorx ("%s: --background is only relevant with --start", progname); 712 eerrorx ("%s: --background is only relevant with --start", applet);
708 713
709 if ((redirect_stdout || redirect_stderr) && ! background) 714 if ((redirect_stdout || redirect_stderr) && ! background)
710 eerrorx ("%s: --stdout and --stderr are only relevant with --background", 715 eerrorx ("%s: --stdout and --stderr are only relevant with --background",
711 progname); 716 applet);
712 717
713 argc -= optind; 718 argc -= optind;
714 argv += optind; 719 argv += optind;
715 720
716 /* Validate that the binary exists if we are starting */ 721 /* Validate that the binary exists if we are starting */
719 if (ch_root) 724 if (ch_root)
720 tmp = rc_strcatpaths (ch_root, exec, (char *) NULL); 725 tmp = rc_strcatpaths (ch_root, exec, (char *) NULL);
721 else 726 else
722 tmp = exec; 727 tmp = exec;
723 if (! rc_is_file (tmp)) { 728 if (! rc_is_file (tmp)) {
724 eerror ("%s: %s does not exist", progname, tmp); 729 eerror ("%s: %s does not exist", applet, tmp);
725 if (ch_root) 730 if (ch_root)
726 free (tmp); 731 free (tmp);
727 exit (EXIT_FAILURE); 732 exit (EXIT_FAILURE);
728 } 733 }
729 if (ch_root) 734 if (ch_root)
754 759
755 exit (EXIT_SUCCESS); 760 exit (EXIT_SUCCESS);
756 } 761 }
757 762
758 if (do_stop (exec, cmd, pidfile, uid, 0, true, false, true) > 0) 763 if (do_stop (exec, cmd, pidfile, uid, 0, true, false, true) > 0)
759 eerrorx ("%s: %s is already running", progname, exec); 764 eerrorx ("%s: %s is already running", applet, exec);
760 765
761 if (test) { 766 if (test) {
762 if (quiet) 767 if (quiet)
763 exit (EXIT_SUCCESS); 768 exit (EXIT_SUCCESS);
764 769
793 if (background) 798 if (background)
794 signal (SIGCHLD, handle_signal); 799 signal (SIGCHLD, handle_signal);
795 800
796 *--argv = exec; 801 *--argv = exec;
797 if ((pid = fork ()) == -1) 802 if ((pid = fork ()) == -1)
798 eerrorx ("%s: fork: %s", progname, strerror (errno)); 803 eerrorx ("%s: fork: %s", applet, strerror (errno));
799 804
800 /* Child process - lets go! */ 805 /* Child process - lets go! */
801 if (pid == 0) { 806 if (pid == 0) {
802 pid_t mypid = getpid (); 807 pid_t mypid = getpid ();
803 808
807 812
808 devnull_fd = open("/dev/null", O_RDWR); 813 devnull_fd = open("/dev/null", O_RDWR);
809 814
810 if (nicelevel) { 815 if (nicelevel) {
811 if (setpriority (PRIO_PROCESS, mypid, nicelevel) == -1) 816 if (setpriority (PRIO_PROCESS, mypid, nicelevel) == -1)
812 eerrorx ("%s: setpritory %d: %s", progname, nicelevel, 817 eerrorx ("%s: setpritory %d: %s", applet, nicelevel,
813 strerror(errno)); 818 strerror(errno));
814 } 819 }
815 820
816 if (ch_root && chroot (ch_root) < 0) 821 if (ch_root && chroot (ch_root) < 0)
817 eerrorx ("%s: chroot `%s': %s", progname, ch_root, strerror (errno)); 822 eerrorx ("%s: chroot `%s': %s", applet, ch_root, strerror (errno));
818 823
819 if (ch_dir && chdir (ch_dir) < 0) 824 if (ch_dir && chdir (ch_dir) < 0)
820 eerrorx ("%s: chdir `%s': %s", progname, ch_dir, strerror (errno)); 825 eerrorx ("%s: chdir `%s': %s", applet, ch_dir, strerror (errno));
821 826
822 if (makepidfile && pidfile) { 827 if (makepidfile && pidfile) {
823 FILE *fp = fopen (pidfile, "w"); 828 FILE *fp = fopen (pidfile, "w");
824 if (! fp) 829 if (! fp)
825 eerrorx ("%s: fopen `%s': %s", progname, pidfile, strerror 830 eerrorx ("%s: fopen `%s': %s", applet, pidfile, strerror
826 (errno)); 831 (errno));
827 fprintf (fp, "%d\n", mypid); 832 fprintf (fp, "%d\n", mypid);
828 fclose (fp); 833 fclose (fp);
829 } 834 }
830 835
839 if (pamr == PAM_SUCCESS) 844 if (pamr == PAM_SUCCESS)
840 pamr = pam_acct_mgmt (pamh, PAM_SILENT); 845 pamr = pam_acct_mgmt (pamh, PAM_SILENT);
841 if (pamr == PAM_SUCCESS) 846 if (pamr == PAM_SUCCESS)
842 pamr = pam_open_session (pamh, PAM_SILENT); 847 pamr = pam_open_session (pamh, PAM_SILENT);
843 if (pamr != PAM_SUCCESS) 848 if (pamr != PAM_SUCCESS)
844 eerrorx ("%s: pam error: %s", progname, pam_strerror(pamh, pamr)); 849 eerrorx ("%s: pam error: %s", applet, pam_strerror(pamh, pamr));
845#endif 850#endif
846 851
847 if (gid && setgid (gid)) 852 if (gid && setgid (gid))
848 eerrorx ("%s: unable to set groupid to %d", progname, gid); 853 eerrorx ("%s: unable to set groupid to %d", applet, gid);
849 if (changeuser && initgroups (changeuser, gid)) 854 if (changeuser && initgroups (changeuser, gid))
850 eerrorx ("%s: initgroups (%s, %d)", progname, changeuser, gid); 855 eerrorx ("%s: initgroups (%s, %d)", applet, changeuser, gid);
851 if (uid && setuid (uid)) 856 if (uid && setuid (uid))
852 eerrorx ("%s: unable to set userid to %d", progname, uid); 857 eerrorx ("%s: unable to set userid to %d", applet, uid);
853 else { 858 else {
854 struct passwd *passwd = getpwuid (uid); 859 struct passwd *passwd = getpwuid (uid);
855 if (passwd) { 860 if (passwd) {
856 unsetenv ("HOME"); 861 unsetenv ("HOME");
857 if (passwd->pw_dir) 862 if (passwd->pw_dir)
896 stderr_fd = devnull_fd; 901 stderr_fd = devnull_fd;
897 if (redirect_stdout) { 902 if (redirect_stdout) {
898 if ((stdout_fd = open (redirect_stdout, O_WRONLY | O_CREAT | O_APPEND, 903 if ((stdout_fd = open (redirect_stdout, O_WRONLY | O_CREAT | O_APPEND,
899 S_IRUSR | S_IWUSR)) == -1) 904 S_IRUSR | S_IWUSR)) == -1)
900 eerrorx ("%s: unable to open the logfile for stdout `%s': %s", 905 eerrorx ("%s: unable to open the logfile for stdout `%s': %s",
901 progname, redirect_stdout, strerror (errno)); 906 applet, redirect_stdout, strerror (errno));
902 } 907 }
903 if (redirect_stderr) { 908 if (redirect_stderr) {
904 if ((stderr_fd = open (redirect_stderr, O_WRONLY | O_CREAT | O_APPEND, 909 if ((stderr_fd = open (redirect_stderr, O_WRONLY | O_CREAT | O_APPEND,
905 S_IRUSR | S_IWUSR)) == -1) 910 S_IRUSR | S_IWUSR)) == -1)
906 eerrorx ("%s: unable to open the logfile for stderr `%s': %s", 911 eerrorx ("%s: unable to open the logfile for stderr `%s': %s",
907 progname, redirect_stderr, strerror (errno)); 912 applet, redirect_stderr, strerror (errno));
908 } 913 }
909 914
910 if (background) { 915 if (background) {
911 /* Hmmm, some daemons may need stdin? */ 916 /* Hmmm, some daemons may need stdin? */
912 dup2 (devnull_fd, STDIN_FILENO); 917 dup2 (devnull_fd, STDIN_FILENO);
922 execve (exec, argv, newenv); 927 execve (exec, argv, newenv);
923#ifdef HAVE_PAM 928#ifdef HAVE_PAM
924 if (pamr == PAM_SUCCESS) 929 if (pamr == PAM_SUCCESS)
925 pam_close_session (pamh, PAM_SILENT); 930 pam_close_session (pamh, PAM_SILENT);
926#endif 931#endif
927 eerrorx ("%s: failed to exec `%s': %s", progname, exec, strerror (errno)); 932 eerrorx ("%s: failed to exec `%s': %s", applet, exec, strerror (errno));
928 } 933 }
929 934
930 /* Parent process */ 935 /* Parent process */
931 if (! background) { 936 if (! background) {
932 /* As we're not backgrounding the process, wait for our pid to return */ 937 /* As we're not backgrounding the process, wait for our pid to return */
942 } 947 }
943 } while (! WIFEXITED (status) && ! WIFSIGNALED (status)); 948 } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
944 949
945 if (! WIFEXITED (status) || WEXITSTATUS (status) != 0) { 950 if (! WIFEXITED (status) || WEXITSTATUS (status) != 0) {
946 if (! quiet) 951 if (! quiet)
947 eerrorx ("%s: failed to start `%s'", progname, exec); 952 eerrorx ("%s: failed to start `%s'", applet, exec);
948 exit (EXIT_FAILURE); 953 exit (EXIT_FAILURE);
949 } 954 }
950 955
951 pid = savepid; 956 pid = savepid;
952 } 957 }
963 ts.tv_nsec = POLL_INTERVAL; 968 ts.tv_nsec = POLL_INTERVAL;
964 969
965 while (nloops) { 970 while (nloops) {
966 if (nanosleep (&ts, NULL) == -1) { 971 if (nanosleep (&ts, NULL) == -1) {
967 if (errno == EINTR) 972 if (errno == EINTR)
968 eerror ("%s: caught an interupt", progname); 973 eerror ("%s: caught an interupt", applet);
969 else { 974 else {
970 eerror ("%s: nanosleep: %s", progname, strerror (errno)); 975 eerror ("%s: nanosleep: %s", applet, strerror (errno));
971 return (0); 976 return (0);
972 } 977 }
973 } 978 }
974 nloops --; 979 nloops --;
975 980
1000 alive = true; 1005 alive = true;
1001 } 1006 }
1002 } 1007 }
1003 1008
1004 if (! alive) 1009 if (! alive)
1005 eerrorx ("%s: %s died", progname, exec); 1010 eerrorx ("%s: %s died", applet, exec);
1006 } 1011 }
1007 1012
1008 if (retestpid) { 1013 if (retestpid) {
1009 if (do_stop (NULL, NULL, pidfile, uid, 0, true, 1014 if (do_stop (NULL, NULL, pidfile, uid, 0, true,
1010 false, true) < 1) 1015 false, true) < 1)
1011 eerrorx ("%s: %s died", progname, exec); 1016 eerrorx ("%s: %s died", applet, exec);
1012 } 1017 }
1013 } 1018 }
1014 1019
1015 if (svcname) 1020 if (svcname)
1016 rc_set_service_daemon (svcname, exec, cmd, pidfile, true); 1021 rc_set_service_daemon (svcname, exec, cmd, pidfile, true);

Legend:
Removed from v.2837  
changed lines
  Added in v.2838

  ViewVC Help
Powered by ViewVC 1.1.20