/////////////// // pido // writes the pid, then execs something. // // Usage: // pido pidfile /absolute/path/prog progarg1 progarg2 ... // If the first arg is missing or is "-" or is "" // then we write to STDOUT. // If the first arg is "--" then we write to STDERR. // Otherwise the first arg is an ordinary filename. // Pido is important for scripts in init.d/ if they // want to start a pipeline. // If you use the command: // aa | bb | cc & // then $! returns the pid of cc. // Alas, aa and/or bb may be just as important as cc // (or even more important). // For example, cc might be a simple logging utility, // while aa is the daemon of interest. // // It is often true BUT NOT PROVABLY TRUE that the pid // of bb is $! minus 1, and the pid of aa is $! minus 2. // If you want something provably correct, do this: // pido /var/run/aa.pid /absolute/path/aa | bb | cc & // Then you know the correct pid of aa has been written // to the file aa.pid. // The perfect test for this is: // ./pido - ./pido - // which should print the same pid number twice. // There might be a way to do this with a simple shell script: // echo ... exec ... // but if there is, I haven't figured it out. #include #include /* for exit() */ #include #include /* for fork(), wait() */ #include //////////////////////////////////////// // Here with data coming in on fd 0. // and control coming in on ft 1. int main(int argc, char* argv[], char* env[]) { FILE* ouch = stdout; int isfile = 1; if (argc > 1) { if (argv[1][0] == '-' || argv[1][0] == 0) { isfile = 0; if (argv[1][1] == '-') ouch = stderr; } if (isfile) { ouch = fopen (argv[1], "w"); if (!ouch) { fprintf(stderr, "pido: cannot open pidfile '%s': ", argv[1]); perror(0); exit (1); } } } fprintf(ouch, "%d\n", getpid()); if (isfile) fclose(ouch); if (argc > 2) { execve(argv[2], argv+2, env); fprintf(stderr, "hi-q: failed to exec '%s': ", argv[2]); perror(0); exit(2); } return 0; }