1182918Smarius/* $FreeBSD$ */ 2182918Smarius/* $OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $ */ 3182918Smarius/* $NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $ */ 4182918Smarius 5182918Smarius/*- 6182918Smarius * Copyright (c) 1999 The NetBSD Foundation, Inc. 7182918Smarius * All rights reserved. 8182918Smarius * 9182918Smarius * This code is derived from software contributed to The NetBSD Foundation 10182918Smarius * by Jason R. Thorpe. 11182918Smarius * 12182918Smarius * Redistribution and use in source and binary forms, with or without 13182918Smarius * modification, are permitted provided that the following conditions 14182918Smarius * are met: 15182918Smarius * 1. Redistributions of source code must retain the above copyright 16182918Smarius * notice, this list of conditions and the following disclaimer. 17182918Smarius * 2. Redistributions in binary form must reproduce the above copyright 18182918Smarius * notice, this list of conditions and the following disclaimer in the 19182918Smarius * documentation and/or other materials provided with the distribution. 20182918Smarius * 21182918Smarius * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22182918Smarius * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23182918Smarius * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24182918Smarius * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25182918Smarius * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26182918Smarius * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27182918Smarius * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28182918Smarius * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29182918Smarius * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30182918Smarius * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31182918Smarius * POSSIBILITY OF SUCH DAMAGE. 32182918Smarius */ 33182918Smarius 34182918Smarius#if defined(LIBC_SCCS) && !defined(lint) 35182918Smariusstatic const char rcsid[] = "$OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $"; 36182918Smarius#endif /* LIBC_SCCS and not lint */ 37182918Smarius 38182918Smarius#include <sys/param.h> 39182918Smarius#include <errno.h> 40182918Smarius#include <paths.h> 41182918Smarius#include <stdio.h> 42182918Smarius#include <stdlib.h> 43197164Smarius#include <unistd.h> 44197164Smarius#ifdef __FreeBSD__ 45197164Smarius#include "pidfile.h" 46197164Smarius#else 47182918Smarius#include <util.h> 48182918Smarius#endif 49182918Smarius 50182918Smariusstatic char *pidfile_path; 51182918Smariusstatic pid_t pidfile_pid; 52182918Smarius 53182918Smariusstatic void pidfile_cleanup(void); 54182918Smarius 55182918Smariusextern char *__progname; 56182918Smarius 57182918Smariusint 58182918Smariuspidfile(const char *basename) 59182918Smarius{ 60182918Smarius FILE *f; 61182918Smarius int save_errno; 62182918Smarius pid_t pid; 63182918Smarius 64182918Smarius if (basename == NULL) 65182918Smarius basename = __progname; 66182918Smarius 67182918Smarius if (pidfile_path != NULL) { 68182918Smarius free(pidfile_path); 69182918Smarius pidfile_path = NULL; 70182918Smarius } 71182918Smarius 72182918Smarius /* _PATH_VARRUN includes trailing / */ 73182918Smarius (void) asprintf(&pidfile_path, "%s%s.pid", _PATH_VARRUN, basename); 74182918Smarius if (pidfile_path == NULL) 75182918Smarius return (-1); 76182918Smarius 77182918Smarius if ((f = fopen(pidfile_path, "w")) == NULL) { 78182918Smarius save_errno = errno; 79182918Smarius free(pidfile_path); 80182918Smarius pidfile_path = NULL; 81182918Smarius errno = save_errno; 82182918Smarius return (-1); 83182918Smarius } 84182918Smarius 85229093Shselasky pid = getpid(); 86182918Smarius if (fprintf(f, "%ld\n", (long)pid) <= 0 || fclose(f) != 0) { 87182918Smarius save_errno = errno; 88182918Smarius (void) unlink(pidfile_path); 89182918Smarius free(pidfile_path); 90182918Smarius pidfile_path = NULL; 91182918Smarius errno = save_errno; 92182918Smarius return (-1); 93182918Smarius } 94182918Smarius 95182918Smarius pidfile_pid = pid; 96182918Smarius if (atexit(pidfile_cleanup) < 0) { 97182918Smarius save_errno = errno; 98182918Smarius (void) unlink(pidfile_path); 99182918Smarius free(pidfile_path); 100182918Smarius pidfile_path = NULL; 101182918Smarius pidfile_pid = 0; 102182918Smarius errno = save_errno; 103182918Smarius return (-1); 104182918Smarius } 105182918Smarius 106182918Smarius return (0); 107182918Smarius} 108182918Smarius 109182918Smariusstatic void 110182918Smariuspidfile_cleanup(void) 111182918Smarius{ 112182918Smarius 113182918Smarius if (pidfile_path != NULL && pidfile_pid == getpid()) 114182918Smarius (void) unlink(pidfile_path); 115182918Smarius} 116182918Smarius