1412fa8f1SPawel Jakub Dawidek.\" Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 2412fa8f1SPawel Jakub Dawidek.\" All rights reserved. 3412fa8f1SPawel Jakub Dawidek.\" 4412fa8f1SPawel Jakub Dawidek.\" Redistribution and use in source and binary forms, with or without 5412fa8f1SPawel Jakub Dawidek.\" modification, are permitted provided that the following conditions 6412fa8f1SPawel Jakub Dawidek.\" are met: 7412fa8f1SPawel Jakub Dawidek.\" 1. Redistributions of source code must retain the above copyright 8412fa8f1SPawel Jakub Dawidek.\" notice, this list of conditions and the following disclaimer. 9412fa8f1SPawel Jakub Dawidek.\" 2. Redistributions in binary form must reproduce the above copyright 10412fa8f1SPawel Jakub Dawidek.\" notice, this list of conditions and the following disclaimer in the 11412fa8f1SPawel Jakub Dawidek.\" documentation and/or other materials provided with the distribution. 12412fa8f1SPawel Jakub Dawidek.\" 13412fa8f1SPawel Jakub Dawidek.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 14412fa8f1SPawel Jakub Dawidek.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15412fa8f1SPawel Jakub Dawidek.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16412fa8f1SPawel Jakub Dawidek.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 17412fa8f1SPawel Jakub Dawidek.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18412fa8f1SPawel Jakub Dawidek.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19412fa8f1SPawel Jakub Dawidek.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20412fa8f1SPawel Jakub Dawidek.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21412fa8f1SPawel Jakub Dawidek.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22412fa8f1SPawel Jakub Dawidek.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23412fa8f1SPawel Jakub Dawidek.\" SUCH DAMAGE. 24412fa8f1SPawel Jakub Dawidek.\" 25412fa8f1SPawel Jakub Dawidek.\" $FreeBSD$ 26412fa8f1SPawel Jakub Dawidek.\" 27412fa8f1SPawel Jakub Dawidek.Dd August 22, 2005 28412fa8f1SPawel Jakub Dawidek.Dt PIDFILE 3 29412fa8f1SPawel Jakub Dawidek.Os 30412fa8f1SPawel Jakub Dawidek.Sh NAME 31412fa8f1SPawel Jakub Dawidek.Nm pidfile_open , 32412fa8f1SPawel Jakub Dawidek.Nm pidfile_write , 33412fa8f1SPawel Jakub Dawidek.Nm pidfile_close , 34412fa8f1SPawel Jakub Dawidek.Nm pidfile_remove 35412fa8f1SPawel Jakub Dawidek.Nd library for PID files handling 36412fa8f1SPawel Jakub Dawidek.Sh LIBRARY 37412fa8f1SPawel Jakub Dawidek.Lb libutil 38412fa8f1SPawel Jakub Dawidek.Sh SYNOPSIS 39412fa8f1SPawel Jakub Dawidek.In sys/param.h 40412fa8f1SPawel Jakub Dawidek.In libutil.h 41412fa8f1SPawel Jakub Dawidek.Ft struct pidfh * 42412fa8f1SPawel Jakub Dawidek.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr" 43412fa8f1SPawel Jakub Dawidek.Ft int 44412fa8f1SPawel Jakub Dawidek.Fn pidfile_write "struct pidfh *pfh" 45412fa8f1SPawel Jakub Dawidek.Ft int 46412fa8f1SPawel Jakub Dawidek.Fn pidfile_close "struct pidfh *pfh" 47412fa8f1SPawel Jakub Dawidek.Ft int 48412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove "struct pidfh *pfh" 49412fa8f1SPawel Jakub Dawidek.Sh DESCRIPTION 50412fa8f1SPawel Jakub DawidekThe 51412fa8f1SPawel Jakub Dawidek.Nm libpidfile 52412fa8f1SPawel Jakub Dawideklibrary provides functions for daemons to handle file with PID. 53412fa8f1SPawel Jakub DawidekIt uses 54412fa8f1SPawel Jakub Dawidek.Xr flock 2 55412fa8f1SPawel Jakub Dawidekto lock pidfile and detect already running daemons. 56412fa8f1SPawel Jakub Dawidek.Pp 57412fa8f1SPawel Jakub DawidekThe 58412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 59412fa8f1SPawel Jakub Dawidekfunction opens (or creates) a file specified by 60412fa8f1SPawel Jakub Dawidek.Fa path 61412fa8f1SPawel Jakub Dawidekargument and locks it with 62412fa8f1SPawel Jakub Dawidek.Xr flock 2 63412fa8f1SPawel Jakub Dawideksyscall. 64412fa8f1SPawel Jakub DawidekIf file can not be locked, PID of already running daemon is returned in 65412fa8f1SPawel Jakub Dawidek.Fa pidptr 66412fa8f1SPawel Jakub Dawidekargument (if it is not NULL). 67412fa8f1SPawel Jakub DawidekThe function doesn't write process' PID into the file here, so it can be 68412fa8f1SPawel Jakub Dawidekused before fork()ing and exit with proper error message when needed. 69412fa8f1SPawel Jakub DawidekIf 70412fa8f1SPawel Jakub Dawidek.Fa path 71412fa8f1SPawel Jakub Dawidekargument is NULL, 72412fa8f1SPawel Jakub Dawidek.Pa /var/run/<progname>.pid 73412fa8f1SPawel Jakub Dawidekfile will be used. 74412fa8f1SPawel Jakub Dawidek.Pp 75412fa8f1SPawel Jakub DawidekThe 76412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 77412fa8f1SPawel Jakub Dawidekfunction write process' PID into previously opened file. 78412fa8f1SPawel Jakub Dawidek.Pp 79412fa8f1SPawel Jakub DawidekThe 80412fa8f1SPawel Jakub Dawidek.Fn pidfile_close 81412fa8f1SPawel Jakub Dawidekfunction closes pidfile. 82412fa8f1SPawel Jakub DawidekIt should be used after daemon fork()s to start a child process. 83412fa8f1SPawel Jakub Dawidek.Pp 84412fa8f1SPawel Jakub DawidekThe 85412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 86412fa8f1SPawel Jakub Dawidekfunction closes and removes pidfile. 87412fa8f1SPawel Jakub Dawidek.Sh RETURN VALUES 88412fa8f1SPawel Jakub DawidekThe 89412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 90412fa8f1SPawel Jakub Dawidekfunction return a valid pointer to a pidfh structure on success or 91412fa8f1SPawel Jakub Dawidek.Dv NULL 92412fa8f1SPawel Jakub Dawidekif an error occurs. 93412fa8f1SPawel Jakub DawidekIf an error does occur, 94412fa8f1SPawel Jakub Dawidek.Va errno 95412fa8f1SPawel Jakub Dawidekwill be set. 96412fa8f1SPawel Jakub Dawidek.Rv -std pidfile_write pidfile_close pidfile_remove 97412fa8f1SPawel Jakub Dawidek.Sh EXAMPLES 98412fa8f1SPawel Jakub DawidekThe following example shows in which order those functions should be used. 99412fa8f1SPawel Jakub Dawidek.Bd -literal 100412fa8f1SPawel Jakub Dawidekstruct pidfh *pfh; 101412fa8f1SPawel Jakub Dawidekpid_t otherpid, childpid; 102412fa8f1SPawel Jakub Dawidek 103412fa8f1SPawel Jakub Dawidekpfh = pidfile_open("/var/run/daemon.pid", 0644, &otherpid); 104412fa8f1SPawel Jakub Dawidekif (pfh == NULL) { 105412fa8f1SPawel Jakub Dawidek if (errno == EEXIST) 106412fa8f1SPawel Jakub Dawidek errx(EXIT_FAILURE, "Daemon already running, pid: %d.", otherpid); 107412fa8f1SPawel Jakub Dawidek /* If we cannot create pidfile from other reasons, only warn. */ 108412fa8f1SPawel Jakub Dawidek warn("Cannot open or create pidfile"); 109412fa8f1SPawel Jakub Dawidek} 110412fa8f1SPawel Jakub Dawidek 111412fa8f1SPawel Jakub Dawidekif (daemon(0, 0) == -1) { 112412fa8f1SPawel Jakub Dawidek warn("Cannot daemonize"); 113412fa8f1SPawel Jakub Dawidek pidfile_remove(pfh); 114412fa8f1SPawel Jakub Dawidek exit(EXIT_FAILURE); 115412fa8f1SPawel Jakub Dawidek} 116412fa8f1SPawel Jakub Dawidek 117412fa8f1SPawel Jakub Dawidekpidfile_write(pfh); 118412fa8f1SPawel Jakub Dawidek 119412fa8f1SPawel Jakub Dawidekfor (;;) { 120412fa8f1SPawel Jakub Dawidek /* Do work. */ 121412fa8f1SPawel Jakub Dawidek childpid = fork(); 122412fa8f1SPawel Jakub Dawidek switch (childpid) { 123412fa8f1SPawel Jakub Dawidek case -1: 124412fa8f1SPawel Jakub Dawidek syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 125412fa8f1SPawel Jakub Dawidek break; 126412fa8f1SPawel Jakub Dawidek case 0: 127412fa8f1SPawel Jakub Dawidek pidfile_close(pfh); 128412fa8f1SPawel Jakub Dawidek /* Do child work. */ 129412fa8f1SPawel Jakub Dawidek break; 130412fa8f1SPawel Jakub Dawidek default: 131412fa8f1SPawel Jakub Dawidek syslog(LOG_INFO, "Child %d started.", childpid); 132412fa8f1SPawel Jakub Dawidek break; 133412fa8f1SPawel Jakub Dawidek } 134412fa8f1SPawel Jakub Dawidek} 135412fa8f1SPawel Jakub Dawidek 136412fa8f1SPawel Jakub Dawidekpidfile_remove(pfh); 137412fa8f1SPawel Jakub Dawidekexit(EXIT_SUCCESS); 138412fa8f1SPawel Jakub Dawidek.Ed 139412fa8f1SPawel Jakub Dawidek.Sh ERRORS 140412fa8f1SPawel Jakub DawidekThe 141412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 142412fa8f1SPawel Jakub Dawidekfunction will fail if: 143412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 144412fa8f1SPawel Jakub Dawidek.It Bq Er EEXIST 145412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, which means, 146412fa8f1SPawel Jakub Dawidekdaemon is already running. 147412fa8f1SPawel Jakub Dawidek.It Bq Er ENAMETOOLONG 148412fa8f1SPawel Jakub DawidekSpecified pidfile's name is too long. 149412fa8f1SPawel Jakub Dawidek.It Bq Er EINVAL 150412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, but PID read 151412fa8f1SPawel Jakub Dawidekfrom there is invalid. 152412fa8f1SPawel Jakub Dawidek.El 153412fa8f1SPawel Jakub Dawidek.Pp 154412fa8f1SPawel Jakub DawidekThe 155412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 156412fa8f1SPawel Jakub Dawidekfunction may also fail and set 157412fa8f1SPawel Jakub Dawidek.Va errno 158412fa8f1SPawel Jakub Dawidekfor any errors specified for the 159412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 160412fa8f1SPawel Jakub Dawidek.Xr open 2 , 161412fa8f1SPawel Jakub Dawidek.Xr read 2 162412fa8f1SPawel Jakub Dawidekroutines. 163412fa8f1SPawel Jakub Dawidek.Pp 164412fa8f1SPawel Jakub DawidekThe 165412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 166412fa8f1SPawel Jakub Dawidekfunction will fail if: 167412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 168412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS 169412fa8f1SPawel Jakub DawidekInproper function use. 170412fa8f1SPawel Jakub DawidekProbably called before 171412fa8f1SPawel Jakub Dawidek.Fn pidfile_open . 172412fa8f1SPawel Jakub Dawidek.El 173412fa8f1SPawel Jakub Dawidek.Pp 174412fa8f1SPawel Jakub DawidekThe 175412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 176412fa8f1SPawel Jakub Dawidekfunction may also fail and set 177412fa8f1SPawel Jakub Dawidek.Va errno 178412fa8f1SPawel Jakub Dawidekfor any errors specified for the 179412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 180412fa8f1SPawel Jakub Dawidek.Xr ftruncate 2 , 181412fa8f1SPawel Jakub Dawidek.Xr write 2 182412fa8f1SPawel Jakub Dawidekroutines. 183412fa8f1SPawel Jakub Dawidek.Pp 184412fa8f1SPawel Jakub DawidekThe 185412fa8f1SPawel Jakub Dawidek.Fn pidfile_close 186412fa8f1SPawel Jakub Dawidekfunction may fail and set 187412fa8f1SPawel Jakub Dawidek.Va errno 188412fa8f1SPawel Jakub Dawidekfor any errors specified for the 189412fa8f1SPawel Jakub Dawidek.Xr close 2 , 190412fa8f1SPawel Jakub Dawidek.Xr fstat 2 191412fa8f1SPawel Jakub Dawidekroutines. 192412fa8f1SPawel Jakub Dawidek.Pp 193412fa8f1SPawel Jakub DawidekThe 194412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 195412fa8f1SPawel Jakub Dawidekfunction will fail if: 196412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 197412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS 198412fa8f1SPawel Jakub DawidekInproper function use. 199412fa8f1SPawel Jakub DawidekProbably called not from the process which made 200412fa8f1SPawel Jakub Dawidek.Fn pidfile_write . 201412fa8f1SPawel Jakub Dawidek.El 202412fa8f1SPawel Jakub Dawidek.Pp 203412fa8f1SPawel Jakub DawidekThe 204412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 205412fa8f1SPawel Jakub Dawidekfunction may also fail and set 206412fa8f1SPawel Jakub Dawidek.Va errno 207412fa8f1SPawel Jakub Dawidekfor any errors specified for the 208412fa8f1SPawel Jakub Dawidek.Xr close 2 , 209412fa8f1SPawel Jakub Dawidek.Xr flock 2 , 210412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 211412fa8f1SPawel Jakub Dawidek.Xr write 2 , 212412fa8f1SPawel Jakub Dawidek.Xr unlink 2 213412fa8f1SPawel Jakub Dawidekroutines. 214412fa8f1SPawel Jakub Dawidek.Pp 215412fa8f1SPawel Jakub Dawidek.Sh SEE ALSO 216412fa8f1SPawel Jakub Dawidek.Xr flock 2 , 217412fa8f1SPawel Jakub Dawidek.Xr open 2 , 218412fa8f1SPawel Jakub Dawidek.Xr daemon 3 219412fa8f1SPawel Jakub Dawidek.Sh AUTHORS 220412fa8f1SPawel Jakub Dawidek.An -nosplit 221412fa8f1SPawel Jakub DawidekThe 222412fa8f1SPawel Jakub Dawidek.Xr pidfile 3 223412fa8f1SPawel Jakub Dawidekfunctionality is based on ideas from 224412fa8f1SPawel Jakub Dawidek.An John-Mark Gurney Aq jmg@FreeBSD.org . 225412fa8f1SPawel Jakub Dawidek.Pp 226412fa8f1SPawel Jakub DawidekThe code and manual page was written by 227412fa8f1SPawel Jakub Dawidek.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org . 228