1e298b784SMax Laier /* $FreeBSD$ */
2e298b784SMax Laier /* $OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $ */
3e298b784SMax Laier /* $NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $ */
4e298b784SMax Laier
5e298b784SMax Laier /*-
6e298b784SMax Laier * Copyright (c) 1999 The NetBSD Foundation, Inc.
7e298b784SMax Laier * All rights reserved.
8e298b784SMax Laier *
9e298b784SMax Laier * This code is derived from software contributed to The NetBSD Foundation
10e298b784SMax Laier * by Jason R. Thorpe.
11e298b784SMax Laier *
12e298b784SMax Laier * Redistribution and use in source and binary forms, with or without
13e298b784SMax Laier * modification, are permitted provided that the following conditions
14e298b784SMax Laier * are met:
15e298b784SMax Laier * 1. Redistributions of source code must retain the above copyright
16e298b784SMax Laier * notice, this list of conditions and the following disclaimer.
17e298b784SMax Laier * 2. Redistributions in binary form must reproduce the above copyright
18e298b784SMax Laier * notice, this list of conditions and the following disclaimer in the
19e298b784SMax Laier * documentation and/or other materials provided with the distribution.
20e298b784SMax Laier *
21e298b784SMax Laier * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22e298b784SMax Laier * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23e298b784SMax Laier * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24e298b784SMax Laier * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25e298b784SMax Laier * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26e298b784SMax Laier * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27e298b784SMax Laier * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28e298b784SMax Laier * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29e298b784SMax Laier * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30e298b784SMax Laier * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31e298b784SMax Laier * POSSIBILITY OF SUCH DAMAGE.
32e298b784SMax Laier */
33e298b784SMax Laier
34e298b784SMax Laier #if defined(LIBC_SCCS) && !defined(lint)
35e298b784SMax Laier static const char rcsid[] = "$OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $";
36e298b784SMax Laier #endif /* LIBC_SCCS and not lint */
37e298b784SMax Laier
38e298b784SMax Laier #include <sys/param.h>
39e298b784SMax Laier #include <errno.h>
40e298b784SMax Laier #include <paths.h>
41e298b784SMax Laier #include <stdio.h>
42e298b784SMax Laier #include <stdlib.h>
43e298b784SMax Laier #include <unistd.h>
44e298b784SMax Laier #ifdef __FreeBSD__
45e298b784SMax Laier #include "pidfile.h"
46e298b784SMax Laier #else
47e298b784SMax Laier #include <util.h>
48e298b784SMax Laier #endif
49e298b784SMax Laier
50e298b784SMax Laier static char *pidfile_path;
51e298b784SMax Laier static pid_t pidfile_pid;
52e298b784SMax Laier
53e298b784SMax Laier static void pidfile_cleanup(void);
54e298b784SMax Laier
55e298b784SMax Laier extern char *__progname;
56e298b784SMax Laier
57e298b784SMax Laier int
pidfile(const char * basename)58e298b784SMax Laier pidfile(const char *basename)
59e298b784SMax Laier {
60e298b784SMax Laier FILE *f;
61e298b784SMax Laier int save_errno;
62e298b784SMax Laier pid_t pid;
63e298b784SMax Laier
64e298b784SMax Laier if (basename == NULL)
65e298b784SMax Laier basename = __progname;
66e298b784SMax Laier
67e298b784SMax Laier if (pidfile_path != NULL) {
68e298b784SMax Laier free(pidfile_path);
69e298b784SMax Laier pidfile_path = NULL;
70e298b784SMax Laier }
71e298b784SMax Laier
72e298b784SMax Laier /* _PATH_VARRUN includes trailing / */
73e298b784SMax Laier (void) asprintf(&pidfile_path, "%s%s.pid", _PATH_VARRUN, basename);
74e298b784SMax Laier if (pidfile_path == NULL)
75e298b784SMax Laier return (-1);
76e298b784SMax Laier
77e298b784SMax Laier if ((f = fopen(pidfile_path, "w")) == NULL) {
78e298b784SMax Laier save_errno = errno;
79e298b784SMax Laier free(pidfile_path);
80e298b784SMax Laier pidfile_path = NULL;
81e298b784SMax Laier errno = save_errno;
82e298b784SMax Laier return (-1);
83e298b784SMax Laier }
84e298b784SMax Laier
85e298b784SMax Laier pid = getpid();
86e298b784SMax Laier if (fprintf(f, "%ld\n", (long)pid) <= 0 || fclose(f) != 0) {
87e298b784SMax Laier save_errno = errno;
88e298b784SMax Laier (void) unlink(pidfile_path);
89e298b784SMax Laier free(pidfile_path);
90e298b784SMax Laier pidfile_path = NULL;
91e298b784SMax Laier errno = save_errno;
92e298b784SMax Laier return (-1);
93e298b784SMax Laier }
94e298b784SMax Laier
95e298b784SMax Laier pidfile_pid = pid;
96e298b784SMax Laier if (atexit(pidfile_cleanup) < 0) {
97e298b784SMax Laier save_errno = errno;
98e298b784SMax Laier (void) unlink(pidfile_path);
99e298b784SMax Laier free(pidfile_path);
100e298b784SMax Laier pidfile_path = NULL;
101e298b784SMax Laier pidfile_pid = 0;
102e298b784SMax Laier errno = save_errno;
103e298b784SMax Laier return (-1);
104e298b784SMax Laier }
105e298b784SMax Laier
106e298b784SMax Laier return (0);
107e298b784SMax Laier }
108e298b784SMax Laier
109e298b784SMax Laier static void
pidfile_cleanup(void)110e298b784SMax Laier pidfile_cleanup(void)
111e298b784SMax Laier {
112e298b784SMax Laier
113e298b784SMax Laier if (pidfile_path != NULL && pidfile_pid == getpid())
114e298b784SMax Laier (void) unlink(pidfile_path);
115e298b784SMax Laier }
116