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 FD_CLOEXEC close-on-exec flag on the open file descriptor. 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 fcntl 2 , 209.Xr fstat 2 , 210.Xr open 2 , 211and 212.Xr read 2 213calls. 214.Pp 215The 216.Fn pidfile_write 217function will fail if: 218.Bl -tag -width Er 219.It Bq Er EDOOFUS 220Improper function use. 221Probably called before 222.Fn pidfile_open . 223.El 224.Pp 225The 226.Fn pidfile_write 227function may also fail and set 228.Va errno 229for any errors specified for the 230.Xr fstat 2 , 231.Xr ftruncate 2 , 232and 233.Xr write 2 234calls. 235.Pp 236The 237.Fn pidfile_close 238function may fail and set 239.Va errno 240for any errors specified for the 241.Xr close 2 242and 243.Xr fstat 2 244calls. 245.Pp 246The 247.Fn pidfile_remove 248function will fail if: 249.Bl -tag -width Er 250.It Bq Er EDOOFUS 251Improper function use. 252Probably called not from the process which made 253.Fn pidfile_write . 254.El 255.Pp 256The 257.Fn pidfile_remove 258function may also fail and set 259.Va errno 260for any errors specified for the 261.Xr close 2 , 262.Xr fstat 2 , 263.Xr write 2 , 264and 265.Xr unlink 2 266system calls and the 267.Xr flopen 3 268library function. 269.Pp 270The 271.Fn pidfile_fileno 272function will fail if: 273.Bl -tag -width Er 274.It Bq Er EDOOFUS 275Improper function use. 276Probably called not from the process which used 277.Fn pidfile_open . 278.El 279.Sh SEE ALSO 280.Xr open 2 , 281.Xr daemon 3 , 282.Xr flopen 3 283.Sh AUTHORS 284.An -nosplit 285The 286.Nm pidfile 287functionality is based on ideas from 288.An John-Mark Gurney Aq jmg@FreeBSD.org . 289.Pp 290The code and manual page was written by 291.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org . 292