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 sys/param.h 40.In libutil.h 41.Ft "struct pidfh *" 42.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr" 43.Ft int 44.Fn pidfile_write "struct pidfh *pfh" 45.Ft int 46.Fn pidfile_close "struct pidfh *pfh" 47.Ft int 48.Fn pidfile_remove "struct pidfh *pfh" 49.Ft int 50.Fn pidfile_fileno "struct pidfh *pfh" 51.Sh DESCRIPTION 52The 53.Nm pidfile 54family of functions allows daemons to handle PID files. 55It uses 56.Xr flopen 3 57to lock a pidfile and detect already running daemons. 58.Pp 59The 60.Fn pidfile_open 61function opens (or creates) a file specified by the 62.Fa path 63argument and locks it. 64If 65.Fa pidptr 66argument is not 67.Dv NULL 68and file can not be locked, the function will use it to store a PID of an 69already running daemon or 70.Li -1 71in case daemon did not write its PID yet. 72The function does not write process' PID into the file here, so it can be 73used before 74.Fn fork Ns ing 75and exit with a proper error message when needed. 76If the 77.Fa path 78argument is 79.Dv NULL , 80.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid 81file will be used. 82The 83.Fn pidfile_open 84function sets the O_CLOEXEC close-on-exec flag when opening the pidfile. 85.Pp 86The 87.Fn pidfile_write 88function writes process' PID into a previously opened file. 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 153if (daemon(0, 0) == -1) { 154 warn("Cannot daemonize"); 155 pidfile_remove(pfh); 156 exit(EXIT_FAILURE); 157} 158 159pidfile_write(pfh); 160 161for (;;) { 162 /* Do work. */ 163 childpid = fork(); 164 switch (childpid) { 165 case -1: 166 syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 167 break; 168 case 0: 169 pidfile_close(pfh); 170 /* Do child work. */ 171 break; 172 default: 173 syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 174 break; 175 } 176} 177 178pidfile_remove(pfh); 179exit(EXIT_SUCCESS); 180.Ed 181.Sh ERRORS 182The 183.Fn pidfile_open 184function will fail if: 185.Bl -tag -width Er 186.It Bq Er EEXIST 187Some process already holds the lock on the given pidfile, meaning that a 188daemon is already running. 189If 190.Fa pidptr 191argument is not 192.Dv NULL 193the function will use it to store a PID of an already running daemon or 194.Li -1 195in case daemon did not write its PID yet. 196.It Bq Er ENAMETOOLONG 197Specified pidfile's name is too long. 198.It Bq Er EINVAL 199Some process already holds the lock on the given pidfile, but PID read 200from there is invalid. 201.El 202.Pp 203The 204.Fn pidfile_open 205function may also fail and set 206.Va errno 207for any errors specified for the 208.Xr fstat 2 , 209.Xr open 2 , 210and 211.Xr read 2 212calls. 213.Pp 214The 215.Fn pidfile_write 216function will fail if: 217.Bl -tag -width Er 218.It Bq Er EDOOFUS 219Improper function use. 220Probably called before 221.Fn pidfile_open . 222.El 223.Pp 224The 225.Fn pidfile_write 226function may also fail and set 227.Va errno 228for any errors specified for the 229.Xr fstat 2 , 230.Xr ftruncate 2 , 231and 232.Xr write 2 233calls. 234.Pp 235The 236.Fn pidfile_close 237function may fail and set 238.Va errno 239for any errors specified for the 240.Xr close 2 241and 242.Xr fstat 2 243calls. 244.Pp 245The 246.Fn pidfile_remove 247function will fail if: 248.Bl -tag -width Er 249.It Bq Er EDOOFUS 250Improper function use. 251Probably called not from the process which made 252.Fn pidfile_write . 253.El 254.Pp 255The 256.Fn pidfile_remove 257function may also fail and set 258.Va errno 259for any errors specified for the 260.Xr close 2 , 261.Xr fstat 2 , 262.Xr write 2 , 263and 264.Xr unlink 2 265system calls and the 266.Xr flopen 3 267library function. 268.Pp 269The 270.Fn pidfile_fileno 271function will fail if: 272.Bl -tag -width Er 273.It Bq Er EDOOFUS 274Improper function use. 275Probably called not from the process which used 276.Fn pidfile_open . 277.El 278.Sh SEE ALSO 279.Xr open 2 , 280.Xr daemon 3 , 281.Xr flopen 3 282.Sh AUTHORS 283.An -nosplit 284The 285.Nm pidfile 286functionality is based on ideas from 287.An John-Mark Gurney Aq jmg@FreeBSD.org . 288.Pp 289The code and manual page was written by 290.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org . 291