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 August 2, 2025 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.Nm pidfile_fileno , 34.Nm pidfile_signal 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.Ft int 51.Fn pidfile_signal "const char *path" "int sig" "pid_t *pidptr" 52.Sh DESCRIPTION 53The 54.Nm pidfile 55family of functions allows daemons to handle PID files. 56It uses 57.Xr flopen 3 58to lock a pidfile and detect already running daemons. 59.Pp 60The 61.Fn pidfile_open 62function opens (or creates) a file specified by the 63.Fa path 64argument and locks it. 65If 66.Fa pidptr 67argument is not 68.Dv NULL 69and file can not be locked, the function will use it to store a PID of an 70already running daemon or 71.Li -1 72in case daemon did not write its PID yet. 73The function does not write process' PID into the file here, so it can be 74used before 75.Fn fork Ns ing 76and exit with a proper error message when needed. 77If the 78.Fa path 79argument is 80.Dv NULL , 81.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid 82file will be used. 83The 84.Fn pidfile_open 85function sets the O_CLOEXEC close-on-exec flag when opening the pidfile. 86.Pp 87The 88.Fn pidfile_write 89function writes process' PID into a previously opened file. 90The file is truncated before write, so calling the 91.Fn pidfile_write 92function multiple times is supported. 93.Pp 94The 95.Fn pidfile_close 96function closes a pidfile. 97It should be used after daemon 98.Fn fork Ns s 99to start a child process. 100.Pp 101The 102.Fn pidfile_remove 103function closes and removes a pidfile. 104.Pp 105The 106.Fn pidfile_fileno 107function returns the file descriptor for the open pidfile. 108.Pp 109The 110.Fn pidfile_signal 111function looks for the pidfile specified by 112.Va path , 113and if it exists and is locked, sends the signal specified by 114.Va sig 115to the PID it contains. 116If 117.Va pidptr 118is not 119.Dv NULL , 120the PID that was found in the pidfile is stored in the location it 121points to. 122Note that calling 123.Fn pidfile_signal 124with 125.Va sig 126set to zero is an effective way to verify the existence of a pidfile 127and of the process that owns it. 128.Sh RETURN VALUES 129The 130.Fn pidfile_open 131function returns a valid pointer to a 132.Vt pidfh 133structure on success, or 134.Dv NULL 135if an error occurs. 136If an error occurs, 137.Va errno 138will be set. 139.Pp 140.Rv -std pidfile_write pidfile_close pidfile_remove 141.Pp 142The 143.Fn pidfile_fileno 144function returns the low-level file descriptor. 145It returns 146.Li -1 147and sets 148.Va errno 149if a NULL 150.Vt pidfh 151is specified, or if the pidfile is no longer open. 152.Pp 153The 154.Fn pidfile_signal 155function returns 0 if it successfully signaled a process, and an 156appropriate 157.Va errno 158value otherwise. 159.Sh EXAMPLES 160The following example shows in which order these functions should be used. 161Note that it is safe to pass 162.Dv NULL 163to 164.Fn pidfile_write , 165.Fn pidfile_remove , 166.Fn pidfile_close , 167and 168.Fn pidfile_fileno 169functions. 170.Bd -literal 171struct pidfh *pfh; 172pid_t otherpid, childpid; 173 174pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 175if (pfh == NULL) { 176 if (errno == EEXIST) { 177 errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 178 (intmax_t)otherpid); 179 } 180 /* If we cannot create pidfile from other reasons, only warn. */ 181 warn("Cannot open or create pidfile"); 182 /* 183 * Even though pfh is NULL we can continue, as the other pidfile_* 184 * function can handle such situation by doing nothing except setting 185 * errno to EDOOFUS. 186 */ 187} 188 189if (daemon(0, 0) == -1) { 190 warn("Cannot daemonize"); 191 pidfile_remove(pfh); 192 exit(EXIT_FAILURE); 193} 194 195pidfile_write(pfh); 196 197for (;;) { 198 /* Do work. */ 199 childpid = fork(); 200 switch (childpid) { 201 case -1: 202 syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 203 break; 204 case 0: 205 pidfile_close(pfh); 206 /* Do child work. */ 207 break; 208 default: 209 syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 210 break; 211 } 212} 213 214pidfile_remove(pfh); 215exit(EXIT_SUCCESS); 216.Ed 217.Sh ERRORS 218The 219.Fn pidfile_open 220function will fail if: 221.Bl -tag -width Er 222.It Bq Er EEXIST 223Some process already holds the lock on the given pidfile, meaning that a 224daemon is already running. 225If 226.Fa pidptr 227argument is not 228.Dv NULL 229the function will use it to store a PID of an already running daemon or 230.Li -1 231in case daemon did not write its PID yet. 232.It Bq Er ENAMETOOLONG 233Specified pidfile's name is too long. 234.It Bq Er EINVAL 235Some process already holds the lock on the given pidfile, but PID read 236from there is invalid. 237.El 238.Pp 239The 240.Fn pidfile_open 241function may also fail and set 242.Va errno 243for any errors specified for the 244.Xr fstat 2 , 245.Xr open 2 , 246and 247.Xr read 2 248calls. 249.Pp 250The 251.Fn pidfile_write 252function will fail if: 253.Bl -tag -width Er 254.It Bq Er EDOOFUS 255Improper function use. 256Probably called before 257.Fn pidfile_open . 258.El 259.Pp 260The 261.Fn pidfile_write 262function may also fail and set 263.Va errno 264for any errors specified for the 265.Xr fstat 2 , 266.Xr ftruncate 2 , 267and 268.Xr write 2 269calls. 270.Pp 271The 272.Fn pidfile_close 273function may fail and set 274.Va errno 275for any errors specified for the 276.Xr close 2 277and 278.Xr fstat 2 279calls. 280.Pp 281The 282.Fn pidfile_remove 283function will fail if: 284.Bl -tag -width Er 285.It Bq Er EDOOFUS 286Improper function use. 287Probably called not from the process which made 288.Fn pidfile_write . 289.El 290.Pp 291The 292.Fn pidfile_remove 293function may also fail and set 294.Va errno 295for any errors specified for the 296.Xr close 2 , 297.Xr fstat 2 , 298.Xr write 2 , 299and 300.Xr unlink 2 301system calls and the 302.Xr flopen 3 303library function. 304.Pp 305The 306.Fn pidfile_fileno 307function will fail if: 308.Bl -tag -width Er 309.It Bq Er EDOOFUS 310Improper function use. 311Probably called not from the process which used 312.Fn pidfile_open . 313.El 314.Pp 315The 316.Fn pidfile_signal 317function will fail if: 318.Bl -tag -width Er 319.It Bq Er ENOENT 320The pidfile does not exist, or exists but is not locked. 321.It Bq Er EDOM 322The pidfile contains a negative number. 323.El 324.Pp 325The 326.Fn pidfile_signal 327function may also fail and return any of the 328.Va errno 329values specified for the 330.Fn pidfile_read 331function and the 332.Xr kill 2 333system call. 334.Sh SEE ALSO 335.Xr kill 2 , 336.Xr open 2 , 337.Xr daemon 3 , 338.Xr flopen 3 339.Sh HISTORY 340The functions 341.Fn pidfile_open , 342.Fn pidfile_write , 343.Fn pidfile_close , 344and 345.Fn pidfile_remove 346first appeared in 347.Fx 5.5 . 348The 349.Fn pidfile_fileno 350function was added in 351.Fx 9.1 . 352The 353.Fn pidfile_signal 354function was added in 355.Fx 14.0 . 356.Sh AUTHORS 357.An -nosplit 358The 359.Nm pidfile 360functionality is based on ideas from 361.An John-Mark Gurney Aq Mt jmg@FreeBSD.org . 362.Pp 363The code and manual page was written by 364.An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org . 365