From 32e75879103a943ac682cbde7b37ea4e4fbc24ab Mon Sep 17 00:00:00 2001 From: John Denker Date: Sat, 2 Jun 2012 09:07:44 -0700 Subject: add some tools --- tools/pido.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tools/pido.c (limited to 'tools/pido.c') diff --git a/tools/pido.c b/tools/pido.c new file mode 100644 index 0000000..9b92337 --- /dev/null +++ b/tools/pido.c @@ -0,0 +1,85 @@ +/////////////// +// 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, "pido: failed to exec '%s': ", argv[2]); + perror(0); + for (int ii = 0; ii < argc; ii++){ + fprintf(stderr, "'%s' ", argv[ii]); + } + fprintf(stderr, "\n"); + exit(2); + } + return 0; +} -- cgit v1.2.3