1.\" Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.\" $FreeBSD$ 26.\" 27.Dd October 16, 2011 28.Dt PIDFILE 3 29.Os 30.Sh NAME 31.Nm pidfile_open , 32.Nm pidfile_write , 33.Nm pidfile_close , 34.Nm pidfile_remove 35.Nd "library for PID files handling" 36.Sh LIBRARY 37.Lb libutil 38.Sh SYNOPSIS 39.In libutil.h 40.Ft "struct pidfh *" 41.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr" 42.Ft int 43.Fn pidfile_write "struct pidfh *pfh" 44.Ft int 45.Fn pidfile_close "struct pidfh *pfh" 46.Ft int 47.Fn pidfile_remove "struct pidfh *pfh" 48.Ft int 49.Fn pidfile_fileno "struct pidfh *pfh" 50.Sh DESCRIPTION 51The 52.Nm pidfile 53family of functions allows daemons to handle PID files. 54It uses 55.Xr flopen 3 56to lock a pidfile and detect already running daemons. 57.Pp 58The 59.Fn pidfile_open 60function opens (or creates) a file specified by the 61.Fa path 62argument and locks it. 63If 64.Fa pidptr 65argument is not 66.Dv NULL 67and file can not be locked, the function will use it to store a PID of an 68already running daemon or 69.Li -1 70in case daemon did not write its PID yet. 71The function does not write process' PID into the file here, so it can be 72used before 73.Fn fork Ns ing 74and exit with a proper error message when needed. 75If the 76.Fa path 77argument is 78.Dv NULL , 79.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid 80file will be used. 81The 82.Fn pidfile_open 83function sets the O_CLOEXEC close-on-exec flag when opening the pidfile. 84.Pp 85The 86.Fn pidfile_write 87function writes process' PID into a previously opened file. 88.Pp 89The 90.Fn pidfile_close 91function closes a pidfile. 92It should be used after daemon 93.Fn fork Ns s 94to start a child process. 95.Pp 96The 97.Fn pidfile_remove 98function closes and removes a pidfile. 99.Pp 100The 101.Fn pidfile_fileno 102function returns the file descriptor for the open pidfile. 103.Sh RETURN VALUES 104The 105.Fn pidfile_open 106function returns a valid pointer to a 107.Vt pidfh 108structure on success, or 109.Dv NULL 110if an error occurs. 111If an error occurs, 112.Va errno 113will be set. 114.Pp 115.Rv -std pidfile_write pidfile_close pidfile_remove 116.Pp 117The 118.Fn pidfile_fileno 119function returns the low-level file descriptor. 120It returns 121.Li -1 122and sets 123.Va errno 124if a NULL 125.Vt pidfh 126is specified, or if the pidfile is no longer open. 127.Sh EXAMPLES 128The following example shows in which order these functions should be used. 129Note that it is safe to pass 130.Dv NULL 131to 132.Fn pidfile_write , 133.Fn pidfile_remove , 134.Fn pidfile_close 135and 136.Fn pidfile_fileno 137functions. 138.Bd -literal 139struct pidfh *pfh; 140pid_t otherpid, childpid; 141 142pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 143if (pfh == NULL) { 144 if (errno == EEXIST) { 145 errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 146 (intmax_t)otherpid); 147 } 148 /* If we cannot create pidfile from other reasons, only warn. */ 149 warn("Cannot open or create pidfile"); 150} 151 152if (daemon(0, 0) == -1) { 153 warn("Cannot daemonize"); 154 pidfile_remove(pfh); 155 exit(EXIT_FAILURE); 156} 157 158pidfile_write(pfh); 159 160for (;;) { 161 /* Do work. */ 162 childpid = fork(); 163 switch (childpid) { 164 case -1: 165 syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 166 break; 167 case 0: 168 pidfile_close(pfh); 169 /* Do child work. */ 170 break; 171 default: 172 syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 173 break; 174 } 175} 176 177pidfile_remove(pfh); 178exit(EXIT_SUCCESS); 179.Ed 180.Sh ERRORS 181The 182.Fn pidfile_open 183function will fail if: 184.Bl -tag -width Er 185.It Bq Er EEXIST 186Some process already holds the lock on the given pidfile, meaning that a 187daemon is already running. 188If 189.Fa pidptr 190argument is not 191.Dv NULL 192the function will use it to store a PID of an already running daemon or 193.Li -1 194in case daemon did not write its PID yet. 195.It Bq Er ENAMETOOLONG 196Specified pidfile's name is too long. 197.It Bq Er EINVAL 198Some process already holds the lock on the given pidfile, but PID read 199from there is invalid. 200.El 201.Pp 202The 203.Fn pidfile_open 204function may also fail and set 205.Va errno 206for any errors specified for the 207.Xr fstat 2 , 208.Xr open 2 , 209and 210.Xr read 2 211calls. 212.Pp 213The 214.Fn pidfile_write 215function will fail if: 216.Bl -tag -width Er 217.It Bq Er EDOOFUS 218Improper function use. 219Probably called before 220.Fn pidfile_open . 221.El 222.Pp 223The 224.Fn pidfile_write 225function may also fail and set 226.Va errno 227for any errors specified for the 228.Xr fstat 2 , 229.Xr ftruncate 2 , 230and 231.Xr write 2 232calls. 233.Pp 234The 235.Fn pidfile_close 236function may fail and set 237.Va errno 238for any errors specified for the 239.Xr close 2 240and 241.Xr fstat 2 242calls. 243.Pp 244The 245.Fn pidfile_remove 246function will fail if: 247.Bl -tag -width Er 248.It Bq Er EDOOFUS 249Improper function use. 250Probably called not from the process which made 251.Fn pidfile_write . 252.El 253.Pp 254The 255.Fn pidfile_remove 256function may also fail and set 257.Va errno 258for any errors specified for the 259.Xr close 2 , 260.Xr fstat 2 , 261.Xr write 2 , 262and 263.Xr unlink 2 264system calls and the 265.Xr flopen 3 266library function. 267.Pp 268The 269.Fn pidfile_fileno 270function will fail if: 271.Bl -tag -width Er 272.It Bq Er EDOOFUS 273Improper function use. 274Probably called not from the process which used 275.Fn pidfile_open . 276.El 277.Sh SEE ALSO 278.Xr open 2 , 279.Xr daemon 3 , 280.Xr flopen 3 281.Sh AUTHORS 282.An -nosplit 283The 284.Nm pidfile 285functionality is based on ideas from 286.An John-Mark Gurney Aq jmg@FreeBSD.org . 287.Pp 288The code and manual page was written by 289.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org . 290