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 February 8, 2012 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. 88The file is truncated before write, so calling the 89.Fn pidfile_write 90function multiple times is supported. 91.Pp 92The 93.Fn pidfile_close 94function closes a pidfile. 95It should be used after daemon 96.Fn fork Ns s 97to start a child process. 98.Pp 99The 100.Fn pidfile_remove 101function closes and removes a pidfile. 102.Pp 103The 104.Fn pidfile_fileno 105function returns the file descriptor for the open pidfile. 106.Sh RETURN VALUES 107The 108.Fn pidfile_open 109function returns a valid pointer to a 110.Vt pidfh 111structure on success, or 112.Dv NULL 113if an error occurs. 114If an error occurs, 115.Va errno 116will be set. 117.Pp 118.Rv -std pidfile_write pidfile_close pidfile_remove 119.Pp 120The 121.Fn pidfile_fileno 122function returns the low-level file descriptor. 123It returns 124.Li -1 125and sets 126.Va errno 127if a NULL 128.Vt pidfh 129is specified, or if the pidfile is no longer open. 130.Sh EXAMPLES 131The following example shows in which order these functions should be used. 132Note that it is safe to pass 133.Dv NULL 134to 135.Fn pidfile_write , 136.Fn pidfile_remove , 137.Fn pidfile_close 138and 139.Fn pidfile_fileno 140functions. 141.Bd -literal 142struct pidfh *pfh; 143pid_t otherpid, childpid; 144 145pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 146if (pfh == NULL) { 147 if (errno == EEXIST) { 148 errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 149 (intmax_t)otherpid); 150 } 151 /* If we cannot create pidfile from other reasons, only warn. */ 152 warn("Cannot open or create pidfile"); 153 /* 154 * Even though pfh is NULL we can continue, as the other pidfile_* 155 * function can handle such situation by doing nothing except setting 156 * errno to EDOOFUS. 157 */ 158} 159 160if (daemon(0, 0) == -1) { 161 warn("Cannot daemonize"); 162 pidfile_remove(pfh); 163 exit(EXIT_FAILURE); 164} 165 166pidfile_write(pfh); 167 168for (;;) { 169 /* Do work. */ 170 childpid = fork(); 171 switch (childpid) { 172 case -1: 173 syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 174 break; 175 case 0: 176 pidfile_close(pfh); 177 /* Do child work. */ 178 break; 179 default: 180 syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 181 break; 182 } 183} 184 185pidfile_remove(pfh); 186exit(EXIT_SUCCESS); 187.Ed 188.Sh ERRORS 189The 190.Fn pidfile_open 191function will fail if: 192.Bl -tag -width Er 193.It Bq Er EEXIST 194Some process already holds the lock on the given pidfile, meaning that a 195daemon is already running. 196If 197.Fa pidptr 198argument is not 199.Dv NULL 200the function will use it to store a PID of an already running daemon or 201.Li -1 202in case daemon did not write its PID yet. 203.It Bq Er ENAMETOOLONG 204Specified pidfile's name is too long. 205.It Bq Er EINVAL 206Some process already holds the lock on the given pidfile, but PID read 207from there is invalid. 208.El 209.Pp 210The 211.Fn pidfile_open 212function may also fail and set 213.Va errno 214for any errors specified for the 215.Xr fstat 2 , 216.Xr open 2 , 217and 218.Xr read 2 219calls. 220.Pp 221The 222.Fn pidfile_write 223function will fail if: 224.Bl -tag -width Er 225.It Bq Er EDOOFUS 226Improper function use. 227Probably called before 228.Fn pidfile_open . 229.El 230.Pp 231The 232.Fn pidfile_write 233function may also fail and set 234.Va errno 235for any errors specified for the 236.Xr fstat 2 , 237.Xr ftruncate 2 , 238and 239.Xr write 2 240calls. 241.Pp 242The 243.Fn pidfile_close 244function may fail and set 245.Va errno 246for any errors specified for the 247.Xr close 2 248and 249.Xr fstat 2 250calls. 251.Pp 252The 253.Fn pidfile_remove 254function will fail if: 255.Bl -tag -width Er 256.It Bq Er EDOOFUS 257Improper function use. 258Probably called not from the process which made 259.Fn pidfile_write . 260.El 261.Pp 262The 263.Fn pidfile_remove 264function may also fail and set 265.Va errno 266for any errors specified for the 267.Xr close 2 , 268.Xr fstat 2 , 269.Xr write 2 , 270and 271.Xr unlink 2 272system calls and the 273.Xr flopen 3 274library function. 275.Pp 276The 277.Fn pidfile_fileno 278function will fail if: 279.Bl -tag -width Er 280.It Bq Er EDOOFUS 281Improper function use. 282Probably called not from the process which used 283.Fn pidfile_open . 284.El 285.Sh SEE ALSO 286.Xr open 2 , 287.Xr daemon 3 , 288.Xr flopen 3 289.Sh AUTHORS 290.An -nosplit 291The 292.Nm pidfile 293functionality is based on ideas from 294.An John-Mark Gurney Aq Mt jmg@FreeBSD.org . 295.Pp 296The code and manual page was written by 297.An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org . 298