From: mdw Date: Thu, 22 Feb 2001 09:07:54 +0000 (+0000) Subject: Write a pidfile on request, and delete it when finished. X-Git-Tag: 1.0.0pre1~9 X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/commitdiff_plain/06b2a088f26208fa8974f8326f01fdfa7908f08b Write a pidfile on request, and delete it when finished. --- diff --git a/client.c b/client.c index c1abe68e..db58ed5f 100644 --- a/client.c +++ b/client.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: client.c,v 1.6 2001/02/22 09:06:08 mdw Exp $ + * $Id: client.c,v 1.7 2001/02/22 09:07:54 mdw Exp $ * * Client for TrIPE * @@ -29,6 +29,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: client.c,v $ + * Revision 1.7 2001/02/22 09:07:54 mdw + * Write a pidfile on request, and delete it when finished. + * * Revision 1.6 2001/02/22 09:06:08 mdw * Fix logfile rotation to avoid program collapse. * @@ -98,9 +101,10 @@ /*----- Static variables --------------------------------------------------*/ +static const char *pidfile = 0; +static const char *logname = 0; static FILE *logfp = 0; static unsigned f = 0; -static const char *logname = 0; static int fd; #define f_bogus 1u @@ -117,9 +121,8 @@ static int fd; static void reap(int sig) { - int s; int e = errno; - while (waitpid(-1, &s, WNOHANG) > 0) + while (waitpid(-1, 0, WNOHANG) > 0) ; errno = e; } @@ -226,6 +229,19 @@ static void sighup(int sig, void *v) logfile(logname); } +static void cleanup(void) +{ + if (pidfile) + unlink(pidfile); +} + +static void sigdie(int sig) +{ + cleanup(); + signal(sig, SIG_DFL); + raise(sig); +} + static void version(FILE *fp) { pquis(fp, "$, TrIPE version " VERSION "\n"); @@ -238,7 +254,8 @@ Usage:\n\ $ [-w] [-options] [command [args]...]\n\ $ [-Dl] [-f file] [-options]\n\ Options:\n\ - [-s] [-d directory] [-a socket] [-p program] [-S arg,arg,...]\n\ + [-s] [-d directory] [-a socket] [-P pidfile]\n\ + [-p program] [-S arg,arg,...]\n\ "); } @@ -258,6 +275,7 @@ Options in full:\n\ -D, --daemon Become a background task after connecting.\n\ -d, --directory=DIR Select current directory [default /var/lib/tripe]\n\ -a, --admin-socket=FILE Select socket to connect to.\n\ +-P, --pidfile=FILE Write process-id to FILE.\n\ \n\ -s, --spawn Start server rather than connecting.\n\ -p, --spawn-path=PATH Specify path to executable.\n\ @@ -276,6 +294,7 @@ int main(int argc, char *argv[]) const char *spawnpath = "tripe"; string_v spawnopts = DA_INIT; char *p; + FILE *pidfp = 0; ego(argv[0]); @@ -298,10 +317,11 @@ int main(int argc, char *argv[]) { "syslog", 0, 0, 'l' }, { "logfile", OPTF_ARGREQ, 0, 'f' }, { "warnings", 0, 0, 'w' }, + { "pidfile", OPTF_ARGREQ, 0, 'P' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "hvuDd:a:sp:S:lwf:n", opts, 0, 0, 0); + int i = mdwopt(argc, argv, "+hvuDd:a:sp:S:lwf:nP:", opts, 0, 0, 0); if (i < 0) break; switch (i) { @@ -343,9 +363,11 @@ int main(int argc, char *argv[]) break; case 'f': logname = optarg; - logfile(logname); f |= f_noinput; break; + case 'P': + pidfile = optarg; + break; default: f |= f_bogus; break; @@ -356,6 +378,25 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + /* --- Set various things up --- */ + + if (chdir(dir)) { + die(EXIT_FAILURE, "couldn't set `%s' as current directory: %s", + dir, strerror(errno)); + } + if (logname) + logfile(logname); + if (!pidfile && (f & f_daemon) && ((f & f_syslog) || logname)) + pidfile = "tripectl.pid"; + if (pidfile && (pidfp = fopen(pidfile, "w")) == 0) { + die(EXIT_FAILURE, "couldn't open `%s' for writing: %s", + pidfile, strerror(errno)); + } + signal(SIGINT, sigdie); + signal(SIGQUIT, sigdie); + signal(SIGTERM, sigdie); + atexit(cleanup); + /* --- Connect to the server --- */ if (f & f_spawn) { @@ -373,12 +414,9 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, 0); DA_UNSHIFT(&spawnopts, (char *)spawnpath); - if (!(f & f_spawnopts)) { - DA_PUSH(&spawnopts, "-d"); - DA_PUSH(&spawnopts, (char *)dir); - DA_PUSH(&spawnopts, "-a"); - DA_PUSH(&spawnopts, (char *)sock); - } + DA_UNSHIFT(&spawnopts, (char *)sock); + DA_UNSHIFT(&spawnopts, "-a"); + DA_UNSHIFT(&spawnopts, "-d."); DA_PUSH(&spawnopts, 0); if (socketpair(PF_UNIX, SOCK_STREAM, 0, pfd)) die(EXIT_FAILURE, "error from socketpair: %s", strerror(errno)); @@ -395,6 +433,8 @@ int main(int argc, char *argv[]) if (logfp) fclose(logfp); closelog(); + if (f & f_daemon) + u_detach(); execvp(DA(&spawnopts)[0], DA(&spawnopts)); die(127, "couldn't exec `%s': %s", spawnpath, strerror(errno)); } @@ -404,15 +444,12 @@ int main(int argc, char *argv[]) } else { struct sockaddr_un sun; size_t sz = strlen(sock) + 1; - dstr d = DSTR_INIT; - dstr_putf(&d, "%s/%s", dir, sock); - if (d.sz + 1 > sizeof(sun.sun_path)) + if (sz > sizeof(sun.sun_path)) die(EXIT_FAILURE, "socket name `%s' too long", sock); memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; - memcpy(sun.sun_path, d.buf, d.sz + 1); - sz = d.sz + offsetof(struct sockaddr_un, sun_path) + 1; - dstr_destroy(&d); + memcpy(sun.sun_path, sock, sz); + sz = sz + offsetof(struct sockaddr_un, sun_path); if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) die(EXIT_FAILURE, "error making socket: %s", strerror(errno)); if (connect(fd, (struct sockaddr *)&sun, sz)) { @@ -425,6 +462,10 @@ int main(int argc, char *argv[]) if (u_daemon()) die(EXIT_FAILURE, "error becoming daemon: %s", strerror(errno)); } + if (pidfp) { + fprintf(pidfp, "%li", (long)getpid()); + fclose(pidfp); + } /* --- If we're meant to be interactive, do that --- */