From 2a957ed711497aacf5bc11599cca740f5ea21750 Mon Sep 17 00:00:00 2001 From: tron Date: Fri, 19 Oct 2001 20:36:59 +0000 Subject: [PATCH] - Don't delete the pidfile if the process executing the cleanup handler isn't the process who created it. - If a new basename is supplied remove the an old pidfile if it was created by this process and create a new one as suggested by Jason Thorpe. This fixes PR lib/13357 by Greg A. Woods. --- lib/libutil/pidfile.3 | 7 +++-- lib/libutil/pidfile.c | 66 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/lib/libutil/pidfile.3 b/lib/libutil/pidfile.3 index 08be941fbc5b..67f67de93bd3 100644 --- a/lib/libutil/pidfile.3 +++ b/lib/libutil/pidfile.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: pidfile.3,v 1.2 2001/04/12 22:34:31 sommerfeld Exp $ +.\" $NetBSD: pidfile.3,v 1.3 2001/10/19 20:36:59 tron Exp $ .\" .\" Copyright (c) 1999 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -65,7 +65,10 @@ receives a fatal signal. .Pp Note that only the first invocation of .Nm -causes a pid file to be written; subsequent invocations have no effect. +causes a pid file to be written; subsequent invocations have no effect +unless a new +.Ar basename +is supplied. .Sh SEE ALSO .Xr atexit 3 .Sh HISTORY diff --git a/lib/libutil/pidfile.c b/lib/libutil/pidfile.c index 48199540aef9..58a688a291c4 100644 --- a/lib/libutil/pidfile.c +++ b/lib/libutil/pidfile.c @@ -1,11 +1,11 @@ -/* $NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $ */ +/* $NetBSD: pidfile.c,v 1.5 2001/10/19 20:36:59 tron Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe. + * by Jason R. Thorpe and Matthias Scheler. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,7 +26,7 @@ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +B * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS @@ -38,16 +38,20 @@ #include #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $"); +__RCSID("$NetBSD: pidfile.c,v 1.5 2001/10/19 20:36:59 tron Exp $"); #endif #include #include #include #include +#include #include #include +static int pidfile_atexit_done; +static pid_t pidfile_pid; +static char *pidfile_basename; static char *pidfile_path; static void pidfile_cleanup(void); @@ -57,30 +61,66 @@ pidfile(const char *basename) { FILE *f; - if (pidfile_path != NULL) - return; + /* + * Register handler which will remove the pidfile later. + */ + if (!pidfile_atexit_done) { + if (atexit(pidfile_cleanup) < 0) + return; + pidfile_atexit_done = 1; + } if (basename == NULL) basename = getprogname(); + /* + * If pidfile has already been created for the supplied basename + * we don't need to create a pidfile again. + */ + if (pidfile_path != NULL) { + if (strcmp(pidfile_basename, basename) == 0) + return; + /* + * Remove existing pidfile if it was created by this process. + */ + pidfile_cleanup(); + + free(pidfile_path); + pidfile_path = NULL; + free(pidfile_basename); + pidfile_basename = NULL; + } + + pidfile_pid = getpid(); + + pidfile_basename = strdup(basename); + if (pidfile_basename == NULL) + return; + /* _PATH_VARRUN includes trailing / */ (void) asprintf(&pidfile_path, "%s%s.pid", _PATH_VARRUN, basename); - if (pidfile_path == NULL) + if (pidfile_path == NULL) { + free(pidfile_basename); + pidfile_basename = NULL; return; + } - if ((f = fopen(pidfile_path, "w")) == NULL) + if ((f = fopen(pidfile_path, "w")) == NULL) { + free(pidfile_path); + pidfile_path = NULL; + free(pidfile_basename); + pidfile_basename = NULL; return; + } - (void) fprintf(f, "%d\n", getpid()); + (void) fprintf(f, "%d\n", pidfile_pid); (void) fclose(f); - - (void) atexit(pidfile_cleanup); } static void pidfile_cleanup(void) { - - if (pidfile_path != NULL) + /* Only remove the pidfile if it was created by this process. */ + if ((pidfile_path != NULL) && (pidfile_pid == getpid())) (void) unlink(pidfile_path); }