minit

A small yet feature-complete init (http://fefe.de/minit/)
Log | Files | Refs | README | LICENSE

commit 567631f57b416fdff2d195f23a9506e74cdf0185
parent 1d169d82463f208e31ade6b646a8c1f1f4e69a30
Author: leitner <leitner>
Date:   Thu, 24 Apr 2003 14:44:39 +0000

  minit now checks whether a PID actually exists before accepting msvc -P
    this removes a race condition when the forked service terminates
    before pidfilehack notifies minit of the PID
  msvc now accepts more than one service after -o, -d, ...

Diffstat:
MCHANGES | 4++++
Mminit.c | 5++++-
Mmsvc.c | 81++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
3 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/CHANGES b/CHANGES @@ -7,6 +7,10 @@ Olaf: add write_proc. Olaf: lines in depends can now be commented out with a # Olaf: add a method to clear dead services (mark as terminated) + minit now checks whether a PID actually exists before accepting msvc -P + this removes a race condition when the forked service terminates + before pidfilehack notifies minit of the PID + msvc now accepts more than one service after -o, -d, ... 0.8: call waitpid repeatedly until it returns "no children". diff --git a/minit.c b/minit.c @@ -475,7 +475,10 @@ error: tmp=0; while ((c=*x++-'0')<10) tmp=tmp*10+c; } - if (tmp>0) pid=tmp; + if (tmp>0) { + if (kill(tmp,0)) goto error; + pid=tmp; + } root[idx].pid=tmp; goto ok; case 's': diff --git a/msvc.c b/msvc.c @@ -124,6 +124,7 @@ main(int argc,char *argv[]) { goto error; } else { int i; + int ret=0; int sig=0; pid_t pid; if (argv[1][0]=='-') { @@ -136,37 +137,43 @@ main(int argc,char *argv[]) { case 't': sig=SIGTERM; goto dokill; break; case 'k': sig=SIGKILL; goto dokill; break; case 'o': - if (startservice(argv[2]) || respawn(argv[2],0)) { - buffer_puts(buffer_2,"Could not start "); - buffer_puts(buffer_2,argv[2]); - buffer_putsflush(buffer_2,"\n"); - goto error; - } + for (i=2; i<argc; ++i) + if (startservice(argv[i]) || respawn(argv[i],0)) { + buffer_puts(buffer_2,"Could not start "); + buffer_puts(buffer_2,argv[i]); + buffer_putsflush(buffer_2,"\n"); + ret=1; + } break; case 'd': - pid=__readpid(argv[2]); - if (pid==0) { - buffer_putsflush(buffer_2,"service not found\n"); - goto error; - } else if (pid==1) - return 0; - if (respawn(argv[2],0) || kill(pid,SIGTERM) || kill(pid,SIGCONT)); + for (i=2; i<argc; ++i) { + pid=__readpid(argv[i]); + if (pid==0) { + buffer_puts(buffer_2,"msvc: "); + buffer_puts(buffer_2,argv[i]); + buffer_putsflush(buffer_2,": no such service\n"); + ret=1; + } else if (pid==1) + continue; + if (respawn(argv[i],0) || kill(pid,SIGTERM) || kill(pid,SIGCONT)); + } break; case 'u': - if (startservice(argv[2]) || respawn(argv[2],1)) { - buffer_puts(buffer_2,"Could not start "); - buffer_puts(buffer_2,argv[2]); - buffer_putsflush(buffer_2,"\n"); - goto error; - } + for (i=2; i<argc; ++i) + if (startservice(argv[i]) || respawn(argv[i],1)) { + buffer_puts(buffer_2,"Could not start "); + buffer_puts(buffer_2,argv[i]); + buffer_putsflush(buffer_2,"\n"); + ret=1; + } break; case 'C': - if (check_remove(argv[2])) { - buffer_puts(buffer_2,"Service "); - buffer_puts(buffer_2,argv[2]); - buffer_putsflush(buffer_2," had terminated or was killed\n"); - goto error; - } + for (i=2; i<argc; ++i) + if (check_remove(argv[i])) { + buffer_puts(buffer_2,argv[i]); + buffer_putsflush(buffer_2," had terminated or was killed\n"); + ret=1; + } break; case 'P': pid=atoi(argv[1]+2); @@ -175,23 +182,33 @@ main(int argc,char *argv[]) { buffer_puts(buffer_2,"Could not set pid of service "); buffer_puts(buffer_2,argv[2]); buffer_putsflush(buffer_2,"\n"); - goto error; + ret=1; } } } - return 0; + return ret; dokill: for (i=2; i<=argc; i++) { - pid=__readpid(argv[2]); + pid=__readpid(argv[i]); + if (!pid) { + buffer_puts(buffer_2,"msvc: "); + buffer_puts(buffer_2,argv[i]); + buffer_putsflush(buffer_2,": no such service!\n"); + ret=1; + } if (kill(pid,sig)) { - buffer_puts(buffer_2,"Could not send signal to PID "); + buffer_puts(buffer_2,"msvc: "); + buffer_puts(buffer_2,argv[i]); + buffer_puts(buffer_2,": could not send signal "); + buffer_putulong(buffer_2,sig); + buffer_puts(buffer_2," to PID "); buffer_putulong(buffer_2,pid); buffer_putsflush(buffer_2,"\n"); -error: - return 1; + ret=1; } } - return 0; +error: + return ret; } } else { buffer_putsflush(buffer_2,"could not open /etc/minit/in or /etc/minit/out\n");