start-stop-daemon.pl 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #!/usr/bin/perl --
  2. $version= '0.93.30'; # This line modified by Makefile
  3. sub usageversion {
  4. print(STDERR <<END)
  5. Debian GNU/Linux start-stop-daemon $version. Copyright (C) 1995
  6. Ian Jackson. This is free software; see the GNU General Public Licence
  7. version 2 or later for copying conditions. There is NO warranty.
  8. Usage: start-stop-daemon --start | --stop | --version|--help options ...
  9. Options: --test --oknodo --exec <executable> --pidfile <pid-file>
  10. --quiet|--verbose --user <username>|<uid> --name <process-name>
  11. --signal <signal> --startas <pathname>
  12. -- <... all of the rest are arguments to daemon ...>
  13. Be careful - try not to call without --exec. \`start-stop-daemon --stop'
  14. would send a SIGTERM to every process, if it weren't specially prevented.
  15. Exit status: 0 = done 1 = nothing done (=> 0 if --oknodo) 2 = trouble
  16. END
  17. || &quit("failed to write usage: $!");
  18. }
  19. sub quit { print STDERR "start-stop-daemon: @_\n"; exit(2); }
  20. sub badusage { print STDERR "start-stop-daemon: @_\n\n"; &usageversion; exit(2); }
  21. $exitnodo= 1;
  22. $quietmode= 0;
  23. $signal= 15;
  24. undef $operation;
  25. undef $exec;
  26. undef $pidfile;
  27. undef $user;
  28. undef $name;
  29. undef $startas;
  30. while (@ARGV) {
  31. $_= shift(@ARGV);
  32. last if m/^--$/;
  33. if (!m/^--/) {
  34. &quit("unknown argument \`$_'");
  35. } elsif (m/^--(help|version)$/) {
  36. &usageversion; exit(0);
  37. } elsif (m/^--test$/) {
  38. $testmode= 1;
  39. } elsif (m/^--quiet$/) {
  40. $quietmode= 1;
  41. } elsif (m/^--verbose$/) {
  42. $quietmode= -1;
  43. } elsif (m/^--oknodo$/) {
  44. $exitnodo= 0;
  45. } elsif (m/^--(start|stop)$/) {
  46. $operation= $1; next;
  47. } elsif (m/^--signal$/) {
  48. $_= shift(@ARGV); m/^\d+$/ || &badusage("--signal takes a numeric argument");
  49. $signal= $_;
  50. } elsif (m/^--(exec|pidfile|name|startas)$/) {
  51. defined($_= shift(@ARGV)) || &badusage("--$1 takes an argument");
  52. eval("\$$1= \$_");
  53. } elsif (m/^--user$/) {
  54. defined($_= shift(@ARGV)) || &badusage("--user takes a username argument");
  55. if (m/^\d+$/) {
  56. $user= $_;
  57. } else {
  58. (@u= getpwnam($_)) || &quit("user \`$_' not found");
  59. $user= $u[2];
  60. }
  61. $userspec= $_;
  62. } else {
  63. &badusage("unknown option \`$_'");
  64. }
  65. }
  66. defined($operation) ||
  67. &badusage("need --start or --stop");
  68. defined($exec) || defined($pidfile) || defined($user) ||
  69. &badusage("need at least one of --exec, --pidfile or --user");
  70. $startas= $exec if !defined($startas);
  71. $operation ne 'start' || defined($startas) ||
  72. &badusage("--start needs --exec or --startas");
  73. if (defined($exec)) {
  74. $exec =~ s,^,./, unless $exec =~ m,^[./],;
  75. (@ve= stat("$exec")) || &quit("unable to stat executable \`$exec': $!");
  76. }
  77. @found= ();
  78. if (defined($pidfile)) {
  79. $pidfile =~ s,^,./, unless $pidfile =~ m,^[./],;
  80. if (open(PID,"< $pidfile")) {
  81. $pid= <PID>;
  82. &check($1) if $pid =~ m/^\s*(\d+)\s*$/;
  83. close(PID);
  84. }
  85. } else {
  86. opendir(PROC,"/proc") || &quit("failed to opendir /proc: $!");
  87. $foundany= 0;
  88. while (defined($pid= readdir(PROC))) {
  89. next unless $pid =~ m/^\d+$/;
  90. $foundany++; &check($pid);
  91. }
  92. $foundany || &quit("nothing in /proc - not mounted ?");
  93. }
  94. sub check {
  95. local ($p)= @_;
  96. if (defined($exec)) {
  97. return unless @vp= stat("/proc/$p/exe");
  98. return unless $vp[0] eq $ve[0] && $vp[1] eq $ve[1];
  99. }
  100. open(C,"/proc/$p/stat");
  101. (@vs= stat(C)) || return;
  102. if (defined($user)) {
  103. (close(C), return) unless $vs[4] == $user;
  104. }
  105. if (defined($name)) {
  106. $c= <C>; close(C);
  107. return unless $c =~ m/^$p \(([^\)]*)\) / && $1 eq $name;
  108. }
  109. close(C);
  110. push(@found,$p);
  111. }
  112. if ($operation eq 'start') {
  113. if (@found) {
  114. print "$exec already running.\n" unless $quietmode>0;
  115. exit($exitnodo);
  116. }
  117. if ($testmode) {
  118. print "would start $startas @ARGV.\n";
  119. exit(0);
  120. }
  121. print "starting $exec ...\n" if $quietmode<0;
  122. exec($startas,@ARGV);
  123. &quit("unable to start $exec: $!");
  124. }
  125. $what= defined($name) ? $name :
  126. defined($exec) ? $exec :
  127. defined($pidfile) ? "process in pidfile \`$pidfile'" :
  128. defined($user) ? "process(es) owned by \`$userspec'" :
  129. &quit("internal error, this is a bug - please report:".
  130. " no name,exec,pidfile,user");
  131. if (!@found) {
  132. print "no $what found; none killed.\n" unless $quietmode>0;
  133. exit($exitnodo);
  134. }
  135. for $pid (@found) {
  136. if ($testmode) {
  137. print "would send signal $signal to $pid.\n";
  138. } else {
  139. if (kill($signal,$pid)) {
  140. push(@killed,$pid);
  141. } else {
  142. print "start-stop-daemon: warning: failed to kill $pid: $!\n"; #
  143. }
  144. }
  145. }
  146. print "stopped $what (pid @killed).\n" if $quietmode<0;
  147. exit(0);