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.Dd May 10, 2020 26.Dt PIDFILE 3 27.Os 28.Sh NAME 29.Nm pidfile_open , 30.Nm pidfile_write , 31.Nm pidfile_close , 32.Nm pidfile_remove 33.Nd "library for PID files handling" 34.Sh LIBRARY 35.Lb libutil 36.Sh SYNOPSIS 37.In libutil.h 38.Ft "struct pidfh *" 39.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr" 40.Ft int 41.Fn pidfile_write "struct pidfh *pfh" 42.Ft int 43.Fn pidfile_close "struct pidfh *pfh" 44.Ft int 45.Fn pidfile_remove "struct pidfh *pfh" 46.Ft int 47.Fn pidfile_fileno "struct pidfh *pfh" 48.Sh DESCRIPTION 49The 50.Nm pidfile 51family of functions allows daemons to handle PID files. 52It uses 53.Xr flopen 3 54to lock a pidfile and detect already running daemons. 55.Pp 56The 57.Fn pidfile_open 58function opens (or creates) a file specified by the 59.Fa path 60argument and locks it. 61If 62.Fa pidptr 63argument is not 64.Dv NULL 65and file can not be locked, the function will use it to store a PID of an 66already running daemon or 67.Li -1 68in case daemon did not write its PID yet. 69The function does not write process' PID into the file here, so it can be 70used before 71.Fn fork Ns ing 72and exit with a proper error message when needed. 73If the 74.Fa path 75argument is 76.Dv NULL , 77.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid 78file will be used. 79The 80.Fn pidfile_open 81function sets the O_CLOEXEC close-on-exec flag when opening the pidfile. 82.Pp 83The 84.Fn pidfile_write 85function writes process' PID into a previously opened file. 86The file is truncated before write, so calling the 87.Fn pidfile_write 88function multiple times is supported. 89.Pp 90The 91.Fn pidfile_close 92function closes a pidfile. 93It should be used after daemon 94.Fn fork Ns s 95to start a child process. 96.Pp 97The 98.Fn pidfile_remove 99function closes and removes a pidfile. 100.Pp 101The 102.Fn pidfile_fileno 103function returns the file descriptor for the open pidfile. 104.Sh RETURN VALUES 105The 106.Fn pidfile_open 107function returns a valid pointer to a 108.Vt pidfh 109structure on success, or 110.Dv NULL 111if an error occurs. 112If an error occurs, 113.Va errno 114will be set. 115.Pp 116.Rv -std pidfile_write pidfile_close pidfile_remove 117.Pp 118The 119.Fn pidfile_fileno 120function returns the low-level file descriptor. 121It returns 122.Li -1 123and sets 124.Va errno 125if a NULL 126.Vt pidfh 127is specified, or if the pidfile is no longer open. 128.Sh EXAMPLES 129The following example shows in which order these functions should be used. 130Note that it is safe to pass 131.Dv NULL 132to 133.Fn pidfile_write , 134.Fn pidfile_remove , 135.Fn pidfile_close 136and 137.Fn pidfile_fileno 138functions. 139.Bd -literal 140struct pidfh *pfh; 141pid_t otherpid, childpid; 142 143pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 144if (pfh == NULL) { 145 if (errno == EEXIST) { 146 errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 147 (intmax_t)otherpid); 148 } 149 /* If we cannot create pidfile from other reasons, only warn. */ 150 warn("Cannot open or create pidfile"); 151 /* 152 * Even though pfh is NULL we can continue, as the other pidfile_* 153 * function can handle such situation by doing nothing except setting 154 * errno to EDOOFUS. 155 */ 156} 157 158if (daemon(0, 0) == -1) { 159 warn("Cannot daemonize"); 160 pidfile_remove(pfh); 161 exit(EXIT_FAILURE); 162} 163 164pidfile_write(pfh); 165 166for (;;) { 167 /* Do work. */ 168 childpid = fork(); 169 switch (childpid) { 170 case -1: 171 syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 172 break; 173 case 0: 174 pidfile_close(pfh); 175 /* Do child work. */ 176 break; 177 default: 178 syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 179 break; 180 } 181} 182 183pidfile_remove(pfh); 184exit(EXIT_SUCCESS); 185.Ed 186.Sh ERRORS 187The 188.Fn pidfile_open 189function will fail if: 190.Bl -tag -width Er 191.It Bq Er EEXIST 192Some process already holds the lock on the given pidfile, meaning that a 193daemon is already running. 194If 195.Fa pidptr 196argument is not 197.Dv NULL 198the function will use it to store a PID of an already running daemon or 199.Li -1 200in case daemon did not write its PID yet. 201.It Bq Er ENAMETOOLONG 202Specified pidfile's name is too long. 203.It Bq Er EINVAL 204Some process already holds the lock on the given pidfile, but PID read 205from there is invalid. 206.El 207.Pp 208The 209.Fn pidfile_open 210function may also fail and set 211.Va errno 212for any errors specified for the 213.Xr fstat 2 , 214.Xr open 2 , 215and 216.Xr read 2 217calls. 218.Pp 219The 220.Fn pidfile_write 221function will fail if: 222.Bl -tag -width Er 223.It Bq Er EDOOFUS 224Improper function use. 225Probably called before 226.Fn pidfile_open . 227.El 228.Pp 229The 230.Fn pidfile_write 231function may also fail and set 232.Va errno 233for any errors specified for the 234.Xr fstat 2 , 235.Xr ftruncate 2 , 236and 237.Xr write 2 238calls. 239.Pp 240The 241.Fn pidfile_close 242function may fail and set 243.Va errno 244for any errors specified for the 245.Xr close 2 246and 247.Xr fstat 2 248calls. 249.Pp 250The 251.Fn pidfile_remove 252function will fail if: 253.Bl -tag -width Er 254.It Bq Er EDOOFUS 255Improper function use. 256Probably called not from the process which made 257.Fn pidfile_write . 258.El 259.Pp 260The 261.Fn pidfile_remove 262function may also fail and set 263.Va errno 264for any errors specified for the 265.Xr close 2 , 266.Xr fstat 2 , 267.Xr write 2 , 268and 269.Xr unlink 2 270system calls and the 271.Xr flopen 3 272library function. 273.Pp 274The 275.Fn pidfile_fileno 276function will fail if: 277.Bl -tag -width Er 278.It Bq Er EDOOFUS 279Improper function use. 280Probably called not from the process which used 281.Fn pidfile_open . 282.El 283.Sh SEE ALSO 284.Xr open 2 , 285.Xr daemon 3 , 286.Xr flopen 3 287.Sh HISTORY 288The functions 289.Fn pidfile_open , 290.Fn pidfile_write , 291.Fn pidfile_close 292and 293.Fn pidfile_remove 294first appeared in 295.Fx 5.5 . 296.Sh AUTHORS 297.An -nosplit 298The 299.Nm pidfile 300functionality is based on ideas from 301.An John-Mark Gurney Aq Mt jmg@FreeBSD.org . 302.Pp 303The code and manual page was written by 304.An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org . 305