1412fa8f1SPawel Jakub Dawidek.\" Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 2412fa8f1SPawel Jakub Dawidek.\" All rights reserved. 3412fa8f1SPawel Jakub Dawidek.\" 4412fa8f1SPawel Jakub Dawidek.\" Redistribution and use in source and binary forms, with or without 5412fa8f1SPawel Jakub Dawidek.\" modification, are permitted provided that the following conditions 6412fa8f1SPawel Jakub Dawidek.\" are met: 7412fa8f1SPawel Jakub Dawidek.\" 1. Redistributions of source code must retain the above copyright 8412fa8f1SPawel Jakub Dawidek.\" notice, this list of conditions and the following disclaimer. 9412fa8f1SPawel Jakub Dawidek.\" 2. Redistributions in binary form must reproduce the above copyright 10412fa8f1SPawel Jakub Dawidek.\" notice, this list of conditions and the following disclaimer in the 11412fa8f1SPawel Jakub Dawidek.\" documentation and/or other materials provided with the distribution. 12412fa8f1SPawel Jakub Dawidek.\" 13412fa8f1SPawel Jakub Dawidek.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 14412fa8f1SPawel Jakub Dawidek.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15412fa8f1SPawel Jakub Dawidek.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16412fa8f1SPawel Jakub Dawidek.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 17412fa8f1SPawel Jakub Dawidek.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18412fa8f1SPawel Jakub Dawidek.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19412fa8f1SPawel Jakub Dawidek.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20412fa8f1SPawel Jakub Dawidek.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21412fa8f1SPawel Jakub Dawidek.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22412fa8f1SPawel Jakub Dawidek.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23412fa8f1SPawel Jakub Dawidek.\" SUCH DAMAGE. 24412fa8f1SPawel Jakub Dawidek.\" 25412fa8f1SPawel Jakub Dawidek.\" $FreeBSD$ 26412fa8f1SPawel Jakub Dawidek.\" 27e8cc80c0SPawel Jakub Dawidek.Dd October 16, 2011 28412fa8f1SPawel Jakub Dawidek.Dt PIDFILE 3 29412fa8f1SPawel Jakub Dawidek.Os 30412fa8f1SPawel Jakub Dawidek.Sh NAME 31412fa8f1SPawel Jakub Dawidek.Nm pidfile_open , 32412fa8f1SPawel Jakub Dawidek.Nm pidfile_write , 33412fa8f1SPawel Jakub Dawidek.Nm pidfile_close , 34412fa8f1SPawel Jakub Dawidek.Nm pidfile_remove 356b84cd58SRuslan Ermilov.Nd "library for PID files handling" 36412fa8f1SPawel Jakub Dawidek.Sh LIBRARY 37412fa8f1SPawel Jakub Dawidek.Lb libutil 38412fa8f1SPawel Jakub Dawidek.Sh SYNOPSIS 39412fa8f1SPawel Jakub Dawidek.In sys/param.h 40412fa8f1SPawel Jakub Dawidek.In libutil.h 416b84cd58SRuslan Ermilov.Ft "struct pidfh *" 42412fa8f1SPawel Jakub Dawidek.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr" 43412fa8f1SPawel Jakub Dawidek.Ft int 44412fa8f1SPawel Jakub Dawidek.Fn pidfile_write "struct pidfh *pfh" 45412fa8f1SPawel Jakub Dawidek.Ft int 46412fa8f1SPawel Jakub Dawidek.Fn pidfile_close "struct pidfh *pfh" 47412fa8f1SPawel Jakub Dawidek.Ft int 48412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove "struct pidfh *pfh" 49f295618dSGuy Helmer.Ft int 50f295618dSGuy Helmer.Fn pidfile_fileno "struct pidfh *pfh" 51412fa8f1SPawel Jakub Dawidek.Sh DESCRIPTION 52412fa8f1SPawel Jakub DawidekThe 536b84cd58SRuslan Ermilov.Nm pidfile 546b84cd58SRuslan Ermilovfamily of functions allows daemons to handle PID files. 55412fa8f1SPawel Jakub DawidekIt uses 56cb7cd07aSDag-Erling Smørgrav.Xr flopen 3 576b84cd58SRuslan Ermilovto lock a pidfile and detect already running daemons. 58412fa8f1SPawel Jakub Dawidek.Pp 59412fa8f1SPawel Jakub DawidekThe 60412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 616b84cd58SRuslan Ermilovfunction opens (or creates) a file specified by the 62412fa8f1SPawel Jakub Dawidek.Fa path 63cb7cd07aSDag-Erling Smørgravargument and locks it. 64e8cc80c0SPawel Jakub DawidekIf 65412fa8f1SPawel Jakub Dawidek.Fa pidptr 66e8cc80c0SPawel Jakub Dawidekargument is not 67e8cc80c0SPawel Jakub Dawidek.Dv NULL 68e8cc80c0SPawel Jakub Dawidekand file can not be locked, the function will use it to store a PID of an 69e8cc80c0SPawel Jakub Dawidekalready running daemon or 70e8cc80c0SPawel Jakub Dawidek.Li -1 71e8cc80c0SPawel Jakub Dawidekin case daemon did not write its PID yet. 726b84cd58SRuslan ErmilovThe function does not write process' PID into the file here, so it can be 736b84cd58SRuslan Ermilovused before 746b84cd58SRuslan Ermilov.Fn fork Ns ing 756b84cd58SRuslan Ermilovand exit with a proper error message when needed. 766b84cd58SRuslan ErmilovIf the 77412fa8f1SPawel Jakub Dawidek.Fa path 786b84cd58SRuslan Ermilovargument is 796b84cd58SRuslan Ermilov.Dv NULL , 806b84cd58SRuslan Ermilov.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid 81412fa8f1SPawel Jakub Dawidekfile will be used. 82*719060e9SGuy HelmerThe 83*719060e9SGuy Helmer.Fn pidfile_open 84*719060e9SGuy Helmerfunction sets the FD_CLOEXEC close-on-exec flag on the open file descriptor. 85412fa8f1SPawel Jakub Dawidek.Pp 86412fa8f1SPawel Jakub DawidekThe 87412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 886b84cd58SRuslan Ermilovfunction writes process' PID into a previously opened file. 89412fa8f1SPawel Jakub Dawidek.Pp 90412fa8f1SPawel Jakub DawidekThe 91412fa8f1SPawel Jakub Dawidek.Fn pidfile_close 926b84cd58SRuslan Ermilovfunction closes a pidfile. 936b84cd58SRuslan ErmilovIt should be used after daemon 946b84cd58SRuslan Ermilov.Fn fork Ns s 956b84cd58SRuslan Ermilovto start a child process. 96412fa8f1SPawel Jakub Dawidek.Pp 97412fa8f1SPawel Jakub DawidekThe 98412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 996b84cd58SRuslan Ermilovfunction closes and removes a pidfile. 100f295618dSGuy Helmer.Pp 101f295618dSGuy HelmerThe 102f295618dSGuy Helmer.Fn pidfile_fileno 103f295618dSGuy Helmerfunction returns the file descriptor for the open pid file. 104412fa8f1SPawel Jakub Dawidek.Sh RETURN VALUES 105412fa8f1SPawel Jakub DawidekThe 106412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 1076b84cd58SRuslan Ermilovfunction returns a valid pointer to a 1086b84cd58SRuslan Ermilov.Vt pidfh 1096b84cd58SRuslan Ermilovstructure on success, or 110412fa8f1SPawel Jakub Dawidek.Dv NULL 111412fa8f1SPawel Jakub Dawidekif an error occurs. 1126b84cd58SRuslan ErmilovIf an error occurs, 113412fa8f1SPawel Jakub Dawidek.Va errno 114412fa8f1SPawel Jakub Dawidekwill be set. 115a27c52a9SDag-Erling Smørgrav.Pp 116412fa8f1SPawel Jakub Dawidek.Rv -std pidfile_write pidfile_close pidfile_remove 117f295618dSGuy Helmer.Pp 118f295618dSGuy HelmerThe 119f295618dSGuy Helmer.Fn pidfile_fileno 120f295618dSGuy Helmerfunction returns the low-level file descriptor. 121f295618dSGuy HelmerIt returns -1 and sets 122f295618dSGuy Helmer.Va errno 123f295618dSGuy Helmerif a NULL 124f295618dSGuy Helmer.Vt pidfh 125f295618dSGuy Helmeris specified, or if the pidfile is no longer open. 126412fa8f1SPawel Jakub Dawidek.Sh EXAMPLES 1276b84cd58SRuslan ErmilovThe following example shows in which order these functions should be used. 128560c4fc1SPawel Jakub DawidekNote that it is safe to pass 129560c4fc1SPawel Jakub Dawidek.Dv NULL 130560c4fc1SPawel Jakub Dawidekto 131560c4fc1SPawel Jakub Dawidek.Fn pidfile_write , 132f295618dSGuy Helmer.Fn pidfile_remove , 133560c4fc1SPawel Jakub Dawidek.Fn pidfile_close 134f295618dSGuy Helmerand 135f295618dSGuy Helmer.Fn pidfile_fileno 136560c4fc1SPawel Jakub Dawidekfunctions. 137412fa8f1SPawel Jakub Dawidek.Bd -literal 138412fa8f1SPawel Jakub Dawidekstruct pidfh *pfh; 139412fa8f1SPawel Jakub Dawidekpid_t otherpid, childpid; 140412fa8f1SPawel Jakub Dawidek 1418b28aef2SPawel Jakub Dawidekpfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 142412fa8f1SPawel Jakub Dawidekif (pfh == NULL) { 143560c4fc1SPawel Jakub Dawidek if (errno == EEXIST) { 144ef608a60SGiorgos Keramidas errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 145ef608a60SGiorgos Keramidas (intmax_t)otherpid); 146560c4fc1SPawel Jakub Dawidek } 147412fa8f1SPawel Jakub Dawidek /* If we cannot create pidfile from other reasons, only warn. */ 148412fa8f1SPawel Jakub Dawidek warn("Cannot open or create pidfile"); 149412fa8f1SPawel Jakub Dawidek} 150412fa8f1SPawel Jakub Dawidek 151412fa8f1SPawel Jakub Dawidekif (daemon(0, 0) == -1) { 152412fa8f1SPawel Jakub Dawidek warn("Cannot daemonize"); 153412fa8f1SPawel Jakub Dawidek pidfile_remove(pfh); 154412fa8f1SPawel Jakub Dawidek exit(EXIT_FAILURE); 155412fa8f1SPawel Jakub Dawidek} 156412fa8f1SPawel Jakub Dawidek 157412fa8f1SPawel Jakub Dawidekpidfile_write(pfh); 158412fa8f1SPawel Jakub Dawidek 159412fa8f1SPawel Jakub Dawidekfor (;;) { 160412fa8f1SPawel Jakub Dawidek /* Do work. */ 161412fa8f1SPawel Jakub Dawidek childpid = fork(); 162412fa8f1SPawel Jakub Dawidek switch (childpid) { 163412fa8f1SPawel Jakub Dawidek case -1: 164412fa8f1SPawel Jakub Dawidek syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 165412fa8f1SPawel Jakub Dawidek break; 166412fa8f1SPawel Jakub Dawidek case 0: 167412fa8f1SPawel Jakub Dawidek pidfile_close(pfh); 168412fa8f1SPawel Jakub Dawidek /* Do child work. */ 169412fa8f1SPawel Jakub Dawidek break; 170412fa8f1SPawel Jakub Dawidek default: 171ef608a60SGiorgos Keramidas syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 172412fa8f1SPawel Jakub Dawidek break; 173412fa8f1SPawel Jakub Dawidek } 174412fa8f1SPawel Jakub Dawidek} 175412fa8f1SPawel Jakub Dawidek 176412fa8f1SPawel Jakub Dawidekpidfile_remove(pfh); 177412fa8f1SPawel Jakub Dawidekexit(EXIT_SUCCESS); 178412fa8f1SPawel Jakub Dawidek.Ed 179412fa8f1SPawel Jakub Dawidek.Sh ERRORS 180412fa8f1SPawel Jakub DawidekThe 181412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 182412fa8f1SPawel Jakub Dawidekfunction will fail if: 183412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 184412fa8f1SPawel Jakub Dawidek.It Bq Er EEXIST 1856b84cd58SRuslan ErmilovSome process already holds the lock on the given pidfile, meaning that a 186412fa8f1SPawel Jakub Dawidekdaemon is already running. 187e8cc80c0SPawel Jakub DawidekIf 188e8cc80c0SPawel Jakub Dawidek.Fa pidptr 189e8cc80c0SPawel Jakub Dawidekargument is not 190e8cc80c0SPawel Jakub Dawidek.Dv NULL 191e8cc80c0SPawel Jakub Dawidekthe function will use it to store a PID of an already running daemon or 192e8cc80c0SPawel Jakub Dawidek.Li -1 193e8cc80c0SPawel Jakub Dawidekin case daemon did not write its PID yet. 194412fa8f1SPawel Jakub Dawidek.It Bq Er ENAMETOOLONG 195412fa8f1SPawel Jakub DawidekSpecified pidfile's name is too long. 196412fa8f1SPawel Jakub Dawidek.It Bq Er EINVAL 197412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, but PID read 198412fa8f1SPawel Jakub Dawidekfrom there is invalid. 199412fa8f1SPawel Jakub Dawidek.El 200412fa8f1SPawel Jakub Dawidek.Pp 201412fa8f1SPawel Jakub DawidekThe 202412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 203412fa8f1SPawel Jakub Dawidekfunction may also fail and set 204412fa8f1SPawel Jakub Dawidek.Va errno 205412fa8f1SPawel Jakub Dawidekfor any errors specified for the 206*719060e9SGuy Helmer.Xr fcntl 2 , 207412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 208412fa8f1SPawel Jakub Dawidek.Xr open 2 , 2096b84cd58SRuslan Ermilovand 210412fa8f1SPawel Jakub Dawidek.Xr read 2 2116b84cd58SRuslan Ermilovcalls. 212412fa8f1SPawel Jakub Dawidek.Pp 213412fa8f1SPawel Jakub DawidekThe 214412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 215412fa8f1SPawel Jakub Dawidekfunction will fail if: 216412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 217412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS 2186b84cd58SRuslan ErmilovImproper function use. 219412fa8f1SPawel Jakub DawidekProbably called before 220412fa8f1SPawel Jakub Dawidek.Fn pidfile_open . 221412fa8f1SPawel Jakub Dawidek.El 222412fa8f1SPawel Jakub Dawidek.Pp 223412fa8f1SPawel Jakub DawidekThe 224412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 225412fa8f1SPawel Jakub Dawidekfunction may also fail and set 226412fa8f1SPawel Jakub Dawidek.Va errno 227412fa8f1SPawel Jakub Dawidekfor any errors specified for the 228412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 229412fa8f1SPawel Jakub Dawidek.Xr ftruncate 2 , 2306b84cd58SRuslan Ermilovand 231412fa8f1SPawel Jakub Dawidek.Xr write 2 2326b84cd58SRuslan Ermilovcalls. 233412fa8f1SPawel Jakub Dawidek.Pp 234412fa8f1SPawel Jakub DawidekThe 235412fa8f1SPawel Jakub Dawidek.Fn pidfile_close 236412fa8f1SPawel Jakub Dawidekfunction may fail and set 237412fa8f1SPawel Jakub Dawidek.Va errno 238412fa8f1SPawel Jakub Dawidekfor any errors specified for the 2396b84cd58SRuslan Ermilov.Xr close 2 2406b84cd58SRuslan Ermilovand 241412fa8f1SPawel Jakub Dawidek.Xr fstat 2 2426b84cd58SRuslan Ermilovcalls. 243412fa8f1SPawel Jakub Dawidek.Pp 244412fa8f1SPawel Jakub DawidekThe 245412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 246412fa8f1SPawel Jakub Dawidekfunction will fail if: 247412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 248412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS 2496b84cd58SRuslan ErmilovImproper function use. 250412fa8f1SPawel Jakub DawidekProbably called not from the process which made 251412fa8f1SPawel Jakub Dawidek.Fn pidfile_write . 252412fa8f1SPawel Jakub Dawidek.El 253412fa8f1SPawel Jakub Dawidek.Pp 254412fa8f1SPawel Jakub DawidekThe 255412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 256412fa8f1SPawel Jakub Dawidekfunction may also fail and set 257412fa8f1SPawel Jakub Dawidek.Va errno 258412fa8f1SPawel Jakub Dawidekfor any errors specified for the 259412fa8f1SPawel Jakub Dawidek.Xr close 2 , 260412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 261412fa8f1SPawel Jakub Dawidek.Xr write 2 , 2626b84cd58SRuslan Ermilovand 263412fa8f1SPawel Jakub Dawidek.Xr unlink 2 264cb7cd07aSDag-Erling Smørgravsystem calls and the 265cb7cd07aSDag-Erling Smørgrav.Xr flopen 3 266cb7cd07aSDag-Erling Smørgravlibrary function. 267f295618dSGuy Helmer.Pp 268f295618dSGuy HelmerThe 269f295618dSGuy Helmer.Fn pidfile_fileno 270f295618dSGuy Helmerfunction will fail if: 271f295618dSGuy Helmer.Bl -tag -width Er 272f295618dSGuy Helmer.It Bq Er EDOOFUS 273f295618dSGuy HelmerImproper function use. 274f295618dSGuy HelmerProbably called not from the process which used 275f295618dSGuy Helmer.Fn pidfile_open . 276f295618dSGuy Helmer.El 277412fa8f1SPawel Jakub Dawidek.Sh SEE ALSO 278412fa8f1SPawel Jakub Dawidek.Xr open 2 , 279cb7cd07aSDag-Erling Smørgrav.Xr daemon 3 , 280cb7cd07aSDag-Erling Smørgrav.Xr flopen 3 281412fa8f1SPawel Jakub Dawidek.Sh AUTHORS 282412fa8f1SPawel Jakub Dawidek.An -nosplit 283412fa8f1SPawel Jakub DawidekThe 2846b84cd58SRuslan Ermilov.Nm pidfile 285412fa8f1SPawel Jakub Dawidekfunctionality is based on ideas from 286412fa8f1SPawel Jakub Dawidek.An John-Mark Gurney Aq jmg@FreeBSD.org . 287412fa8f1SPawel Jakub Dawidek.Pp 288412fa8f1SPawel Jakub DawidekThe code and manual page was written by 289412fa8f1SPawel Jakub Dawidek.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org . 290