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.\" 27cb7cd07aSDag-Erling Smørgrav.Dd October 20, 2008 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" 49412fa8f1SPawel Jakub Dawidek.Sh DESCRIPTION 50412fa8f1SPawel Jakub DawidekThe 516b84cd58SRuslan Ermilov.Nm pidfile 526b84cd58SRuslan Ermilovfamily of functions allows daemons to handle PID files. 53412fa8f1SPawel Jakub DawidekIt uses 54cb7cd07aSDag-Erling Smørgrav.Xr flopen 3 556b84cd58SRuslan Ermilovto lock a pidfile and detect already running daemons. 56412fa8f1SPawel Jakub Dawidek.Pp 57412fa8f1SPawel Jakub DawidekThe 58412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 596b84cd58SRuslan Ermilovfunction opens (or creates) a file specified by the 60412fa8f1SPawel Jakub Dawidek.Fa path 61cb7cd07aSDag-Erling Smørgravargument and locks it. 626b84cd58SRuslan ErmilovIf a file can not be locked, a PID of an already running daemon is returned in 636b84cd58SRuslan Ermilovthe 64412fa8f1SPawel Jakub Dawidek.Fa pidptr 656b84cd58SRuslan Ermilovargument (if it is not 666b84cd58SRuslan Ermilov.Dv NULL ) . 676b84cd58SRuslan ErmilovThe function does not write process' PID into the file here, so it can be 686b84cd58SRuslan Ermilovused before 696b84cd58SRuslan Ermilov.Fn fork Ns ing 706b84cd58SRuslan Ermilovand exit with a proper error message when needed. 716b84cd58SRuslan ErmilovIf the 72412fa8f1SPawel Jakub Dawidek.Fa path 736b84cd58SRuslan Ermilovargument is 746b84cd58SRuslan Ermilov.Dv NULL , 756b84cd58SRuslan Ermilov.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid 76412fa8f1SPawel Jakub Dawidekfile will be used. 77412fa8f1SPawel Jakub Dawidek.Pp 78412fa8f1SPawel Jakub DawidekThe 79412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 806b84cd58SRuslan Ermilovfunction writes process' PID into a previously opened file. 81412fa8f1SPawel Jakub Dawidek.Pp 82412fa8f1SPawel Jakub DawidekThe 83412fa8f1SPawel Jakub Dawidek.Fn pidfile_close 846b84cd58SRuslan Ermilovfunction closes a pidfile. 856b84cd58SRuslan ErmilovIt should be used after daemon 866b84cd58SRuslan Ermilov.Fn fork Ns s 876b84cd58SRuslan Ermilovto start a child process. 88412fa8f1SPawel Jakub Dawidek.Pp 89412fa8f1SPawel Jakub DawidekThe 90412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 916b84cd58SRuslan Ermilovfunction closes and removes a pidfile. 92412fa8f1SPawel Jakub Dawidek.Sh RETURN VALUES 93412fa8f1SPawel Jakub DawidekThe 94412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 956b84cd58SRuslan Ermilovfunction returns a valid pointer to a 966b84cd58SRuslan Ermilov.Vt pidfh 976b84cd58SRuslan Ermilovstructure on success, or 98412fa8f1SPawel Jakub Dawidek.Dv NULL 99412fa8f1SPawel Jakub Dawidekif an error occurs. 1006b84cd58SRuslan ErmilovIf an error occurs, 101412fa8f1SPawel Jakub Dawidek.Va errno 102412fa8f1SPawel Jakub Dawidekwill be set. 103a27c52a9SDag-Erling Smørgrav.Pp 104412fa8f1SPawel Jakub Dawidek.Rv -std pidfile_write pidfile_close pidfile_remove 105412fa8f1SPawel Jakub Dawidek.Sh EXAMPLES 1066b84cd58SRuslan ErmilovThe following example shows in which order these functions should be used. 107560c4fc1SPawel Jakub DawidekNote that it is safe to pass 108560c4fc1SPawel Jakub Dawidek.Dv NULL 109560c4fc1SPawel Jakub Dawidekto 110560c4fc1SPawel Jakub Dawidek.Fn pidfile_write , 111560c4fc1SPawel Jakub Dawidek.Fn pidfile_remove 112560c4fc1SPawel Jakub Dawidekand 113560c4fc1SPawel Jakub Dawidek.Fn pidfile_close 114560c4fc1SPawel Jakub Dawidekfunctions. 115412fa8f1SPawel Jakub Dawidek.Bd -literal 116412fa8f1SPawel Jakub Dawidekstruct pidfh *pfh; 117412fa8f1SPawel Jakub Dawidekpid_t otherpid, childpid; 118412fa8f1SPawel Jakub Dawidek 1198b28aef2SPawel Jakub Dawidekpfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 120412fa8f1SPawel Jakub Dawidekif (pfh == NULL) { 121560c4fc1SPawel Jakub Dawidek if (errno == EEXIST) { 122ef608a60SGiorgos Keramidas errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 123ef608a60SGiorgos Keramidas (intmax_t)otherpid); 124560c4fc1SPawel Jakub Dawidek } 125412fa8f1SPawel Jakub Dawidek /* If we cannot create pidfile from other reasons, only warn. */ 126412fa8f1SPawel Jakub Dawidek warn("Cannot open or create pidfile"); 127412fa8f1SPawel Jakub Dawidek} 128412fa8f1SPawel Jakub Dawidek 129412fa8f1SPawel Jakub Dawidekif (daemon(0, 0) == -1) { 130412fa8f1SPawel Jakub Dawidek warn("Cannot daemonize"); 131412fa8f1SPawel Jakub Dawidek pidfile_remove(pfh); 132412fa8f1SPawel Jakub Dawidek exit(EXIT_FAILURE); 133412fa8f1SPawel Jakub Dawidek} 134412fa8f1SPawel Jakub Dawidek 135412fa8f1SPawel Jakub Dawidekpidfile_write(pfh); 136412fa8f1SPawel Jakub Dawidek 137412fa8f1SPawel Jakub Dawidekfor (;;) { 138412fa8f1SPawel Jakub Dawidek /* Do work. */ 139412fa8f1SPawel Jakub Dawidek childpid = fork(); 140412fa8f1SPawel Jakub Dawidek switch (childpid) { 141412fa8f1SPawel Jakub Dawidek case -1: 142412fa8f1SPawel Jakub Dawidek syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 143412fa8f1SPawel Jakub Dawidek break; 144412fa8f1SPawel Jakub Dawidek case 0: 145412fa8f1SPawel Jakub Dawidek pidfile_close(pfh); 146412fa8f1SPawel Jakub Dawidek /* Do child work. */ 147412fa8f1SPawel Jakub Dawidek break; 148412fa8f1SPawel Jakub Dawidek default: 149ef608a60SGiorgos Keramidas syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 150412fa8f1SPawel Jakub Dawidek break; 151412fa8f1SPawel Jakub Dawidek } 152412fa8f1SPawel Jakub Dawidek} 153412fa8f1SPawel Jakub Dawidek 154412fa8f1SPawel Jakub Dawidekpidfile_remove(pfh); 155412fa8f1SPawel Jakub Dawidekexit(EXIT_SUCCESS); 156412fa8f1SPawel Jakub Dawidek.Ed 157412fa8f1SPawel Jakub Dawidek.Sh ERRORS 158412fa8f1SPawel Jakub DawidekThe 159412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 160412fa8f1SPawel Jakub Dawidekfunction will fail if: 161412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 162412fa8f1SPawel Jakub Dawidek.It Bq Er EEXIST 1636b84cd58SRuslan ErmilovSome process already holds the lock on the given pidfile, meaning that a 164412fa8f1SPawel Jakub Dawidekdaemon is already running. 165412fa8f1SPawel Jakub Dawidek.It Bq Er ENAMETOOLONG 166412fa8f1SPawel Jakub DawidekSpecified pidfile's name is too long. 167412fa8f1SPawel Jakub Dawidek.It Bq Er EINVAL 168412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, but PID read 169412fa8f1SPawel Jakub Dawidekfrom there is invalid. 170fefc6803SKonstantin Belousov.It Bq Er EAGAIN 171fefc6803SKonstantin BelousovSome process already holds the lock on the given pidfile, but the file 1723dca0939SSimon L. B. Nielsenis truncated. 1733dca0939SSimon L. B. NielsenMost likely, the existing daemon is writing new PID into 174fefc6803SKonstantin Belousovthe file. 175412fa8f1SPawel Jakub Dawidek.El 176412fa8f1SPawel Jakub Dawidek.Pp 177412fa8f1SPawel Jakub DawidekThe 178412fa8f1SPawel Jakub Dawidek.Fn pidfile_open 179412fa8f1SPawel Jakub Dawidekfunction may also fail and set 180412fa8f1SPawel Jakub Dawidek.Va errno 181412fa8f1SPawel Jakub Dawidekfor any errors specified for the 182412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 183412fa8f1SPawel Jakub Dawidek.Xr open 2 , 1846b84cd58SRuslan Ermilovand 185412fa8f1SPawel Jakub Dawidek.Xr read 2 1866b84cd58SRuslan Ermilovcalls. 187412fa8f1SPawel Jakub Dawidek.Pp 188412fa8f1SPawel Jakub DawidekThe 189412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 190412fa8f1SPawel Jakub Dawidekfunction will fail if: 191412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 192412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS 1936b84cd58SRuslan ErmilovImproper function use. 194412fa8f1SPawel Jakub DawidekProbably called before 195412fa8f1SPawel Jakub Dawidek.Fn pidfile_open . 196412fa8f1SPawel Jakub Dawidek.El 197412fa8f1SPawel Jakub Dawidek.Pp 198412fa8f1SPawel Jakub DawidekThe 199412fa8f1SPawel Jakub Dawidek.Fn pidfile_write 200412fa8f1SPawel Jakub Dawidekfunction may also fail and set 201412fa8f1SPawel Jakub Dawidek.Va errno 202412fa8f1SPawel Jakub Dawidekfor any errors specified for the 203412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 204412fa8f1SPawel Jakub Dawidek.Xr ftruncate 2 , 2056b84cd58SRuslan Ermilovand 206412fa8f1SPawel Jakub Dawidek.Xr write 2 2076b84cd58SRuslan Ermilovcalls. 208412fa8f1SPawel Jakub Dawidek.Pp 209412fa8f1SPawel Jakub DawidekThe 210412fa8f1SPawel Jakub Dawidek.Fn pidfile_close 211412fa8f1SPawel Jakub Dawidekfunction may fail and set 212412fa8f1SPawel Jakub Dawidek.Va errno 213412fa8f1SPawel Jakub Dawidekfor any errors specified for the 2146b84cd58SRuslan Ermilov.Xr close 2 2156b84cd58SRuslan Ermilovand 216412fa8f1SPawel Jakub Dawidek.Xr fstat 2 2176b84cd58SRuslan Ermilovcalls. 218412fa8f1SPawel Jakub Dawidek.Pp 219412fa8f1SPawel Jakub DawidekThe 220412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 221412fa8f1SPawel Jakub Dawidekfunction will fail if: 222412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er 223412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS 2246b84cd58SRuslan ErmilovImproper function use. 225412fa8f1SPawel Jakub DawidekProbably called not from the process which made 226412fa8f1SPawel Jakub Dawidek.Fn pidfile_write . 227412fa8f1SPawel Jakub Dawidek.El 228412fa8f1SPawel Jakub Dawidek.Pp 229412fa8f1SPawel Jakub DawidekThe 230412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove 231412fa8f1SPawel Jakub Dawidekfunction may also fail and set 232412fa8f1SPawel Jakub Dawidek.Va errno 233412fa8f1SPawel Jakub Dawidekfor any errors specified for the 234412fa8f1SPawel Jakub Dawidek.Xr close 2 , 235412fa8f1SPawel Jakub Dawidek.Xr fstat 2 , 236412fa8f1SPawel Jakub Dawidek.Xr write 2 , 2376b84cd58SRuslan Ermilovand 238412fa8f1SPawel Jakub Dawidek.Xr unlink 2 239cb7cd07aSDag-Erling Smørgravsystem calls and the 240cb7cd07aSDag-Erling Smørgrav.Xr flopen 3 241cb7cd07aSDag-Erling Smørgravlibrary function. 242412fa8f1SPawel Jakub Dawidek.Sh SEE ALSO 243412fa8f1SPawel Jakub Dawidek.Xr open 2 , 244cb7cd07aSDag-Erling Smørgrav.Xr daemon 3 , 245cb7cd07aSDag-Erling Smørgrav.Xr flopen 3 246412fa8f1SPawel Jakub Dawidek.Sh AUTHORS 247412fa8f1SPawel Jakub Dawidek.An -nosplit 248412fa8f1SPawel Jakub DawidekThe 2496b84cd58SRuslan Ermilov.Nm pidfile 250412fa8f1SPawel Jakub Dawidekfunctionality is based on ideas from 251412fa8f1SPawel Jakub Dawidek.An John-Mark Gurney Aq jmg@FreeBSD.org . 252412fa8f1SPawel Jakub Dawidek.Pp 253412fa8f1SPawel Jakub DawidekThe code and manual page was written by 254412fa8f1SPawel Jakub Dawidek.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org . 255