Add pidfile(3).
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 22 Sep 2004 05:06:57 +0000 (05:06 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 22 Sep 2004 05:06:57 +0000 (05:06 +0000)
Obtained-from: NetBSD

lib/libutil/Makefile
lib/libutil/libutil.h
lib/libutil/pidfile.3 [new file with mode: 0644]
lib/libutil/pidfile.c [new file with mode: 0644]

index 1176c12..93e3d15 100644 (file)
@@ -1,6 +1,6 @@
 #      @(#)Makefile    8.1 (Berkeley) 6/4/93
 #      $FreeBSD: src/lib/libutil/Makefile,v 1.33.2.4 2001/04/25 10:04:42 ru Exp $
-#      $DragonFly: src/lib/libutil/Makefile,v 1.2 2003/06/17 04:26:51 dillon Exp $
+#      $DragonFly: src/lib/libutil/Makefile,v 1.3 2004/09/22 05:06:57 joerg Exp $
 
 LIB=   util
 SHLIB_MAJOR= 3
@@ -10,13 +10,13 @@ CFLAGS+=-DINET6
 SRCS=  login.c login_tty.c logout.c logwtmp.c pty.c \
        login_cap.c login_class.c login_auth.c login_times.c login_ok.c \
        login_crypt.c _secure_path.c uucplock.c property.c auth.c \
-       realhostname.c fparseln.c stub.c
+       realhostname.c fparseln.c stub.c pidfile.c
 INCS=  libutil.h login_cap.h
 
 MAN+=  login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \
        login_cap.3 login_class.3 login_times.3 login_ok.3 \
        _secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \
-       realhostname_sa.3 trimdomain.3 fparseln.3
+       realhostname_sa.3 trimdomain.3 fparseln.3 pidfile.3
 MAN+=  login.conf.5 auth.conf.5
 MLINKS+= property.3 properties_read.3  property.3 properties_free.3
 MLINKS+= property.3 property_find.3
index 298f7a0..291504e 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libutil/libutil.h,v 1.26.2.3 2000/11/22 03:49:49 murray Exp $
- * $DragonFly: src/lib/libutil/libutil.h,v 1.3 2003/11/12 20:21:31 eirikn Exp $
+ * $DragonFly: src/lib/libutil/libutil.h,v 1.4 2004/09/22 05:06:57 joerg Exp $
  */
 
 #ifndef _LIBUTIL_H_
@@ -63,6 +63,7 @@ int   uu_lock (const char *_ttyname);
 int    uu_unlock (const char *_ttyname);
 int    uu_lock_txfr (const char *_ttyname, pid_t _pid);
 int    _secure_path (const char *_path, uid_t _uid, gid_t _gid);
+int    pidfile(const char *);
 properties properties_read (int fd);
 void   properties_free (properties list);
 char   *property_find (properties list, const char *name);
diff --git a/lib/libutil/pidfile.3 b/lib/libutil/pidfile.3
new file mode 100644 (file)
index 0000000..fbd09c9
--- /dev/null
@@ -0,0 +1,96 @@
+.\"    $NetBSD: pidfile.3,v 1.8 2002/10/01 19:36:30 wiz Exp $
+.\"    $DragonFly: src/lib/libutil/pidfile.3,v 1.1 2004/09/22 05:06:57 joerg 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.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"        This product includes software developed by the NetBSD
+.\"        Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\"    contributors may be used to endorse or promote products derived
+.\"    from this software without specific prior written permission.
+.\"
+.\" 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
+.\" 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
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd June 5, 1999
+.Dt PIDFILE 3
+.Os
+.Sh NAME
+.Nm pidfile
+.Nd write a daemon pid file
+.Sh LIBRARY
+.Lb libutil
+.Sh SYNOPSIS
+.In util.h
+.Ft int
+.Fn pidfile "const char *basename"
+.Sh DESCRIPTION
+.Fn pidfile
+writes a file containing the process ID of the program to the
+.Pa /var/run
+directory.
+The file name has the form
+.Pa /var/run/basename.pid .
+If the
+.Ar basename
+argument is NULL,
+.Nm
+will determine the program name and use that instead.
+.Pp
+The pid file can be used as a quick reference if
+the process needs to be sent a signal.
+When the program exits, the pid file will be removed automatically, unless
+the program 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
+unless a new
+.Ar basename
+is supplied.
+If called with a new
+.Ar basename ,
+.Fn pidfile
+will remove the old pid file and write the new one.
+.Sh RETURN VALUES
+.Fn pidfile
+returns 0 on success and -1 on failure.
+.Sh SEE ALSO
+.Xr atexit 3
+.Sh HISTORY
+The
+.Nm
+function call appeared in
+.Nx 1.5 .
+.Sh BUGS
+.Fn pidfile
+uses
+.Xr atexit 3
+to ensure the pidfile is unlinked at program exit.
+However, programs that use the
+.Xr _exit 2
+function (for example, in signal handlers)
+will not trigger this behaviour.
diff --git a/lib/libutil/pidfile.c b/lib/libutil/pidfile.c
new file mode 100644 (file)
index 0000000..68c65a5
--- /dev/null
@@ -0,0 +1,123 @@
+/*     $NetBSD: pidfile.c,v 1.6 2001/10/20 09:20:28 taca Exp $ */
+/*     $DragonFly: src/lib/libutil/pidfile.c,v 1.1 2004/09/22 05:06:57 joerg 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 and Matthias Scheler.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * 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
+ * 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
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <libutil.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static int   pidfile_atexit_done;
+static pid_t pidfile_pid;
+static char *pidfile_basename;
+static char *pidfile_path;
+
+static void pidfile_cleanup(void);
+
+int
+pidfile(const char *basename)
+{
+       FILE *f;
+
+       /*
+        * Register handler which will remove the pidfile later.
+        */
+       if (!pidfile_atexit_done) {
+               if (atexit(pidfile_cleanup) < 0)
+                       return -1;
+               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 0;
+               /*
+                * 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 -1;
+
+       /* _PATH_VARRUN includes trailing / */
+       asprintf(&pidfile_path, "%s%s.pid", _PATH_VARRUN, basename);
+       if (pidfile_path == NULL) {
+               free(pidfile_basename);
+               pidfile_basename = NULL;
+               return -1;
+       }
+
+       if ((f = fopen(pidfile_path, "w")) == NULL) {
+               free(pidfile_path);
+               pidfile_path = NULL;
+               free(pidfile_basename);
+               pidfile_basename = NULL;
+               return -1;
+       }
+
+       fprintf(f, "%d\n", pidfile_pid);
+       fclose(f);
+       return 0;
+}
+
+static void
+pidfile_cleanup(void)
+{
+       /* Only remove the pidfile if it was created by this process. */
+       if ((pidfile_path != NULL) && (pidfile_pid == getpid()))
+               unlink(pidfile_path);
+}