11eaf0ac3Slogwang.\" Copyright (c) 2005 Pawel Jakub Dawidek <[email protected]> 21eaf0ac3Slogwang.\" All rights reserved. 31eaf0ac3Slogwang.\" 41eaf0ac3Slogwang.\" Redistribution and use in source and binary forms, with or without 51eaf0ac3Slogwang.\" modification, are permitted provided that the following conditions 61eaf0ac3Slogwang.\" are met: 71eaf0ac3Slogwang.\" 1. Redistributions of source code must retain the above copyright 81eaf0ac3Slogwang.\" notice, this list of conditions and the following disclaimer. 91eaf0ac3Slogwang.\" 2. Redistributions in binary form must reproduce the above copyright 101eaf0ac3Slogwang.\" notice, this list of conditions and the following disclaimer in the 111eaf0ac3Slogwang.\" documentation and/or other materials provided with the distribution. 121eaf0ac3Slogwang.\" 131eaf0ac3Slogwang.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 141eaf0ac3Slogwang.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 151eaf0ac3Slogwang.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 161eaf0ac3Slogwang.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 171eaf0ac3Slogwang.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 181eaf0ac3Slogwang.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 191eaf0ac3Slogwang.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 201eaf0ac3Slogwang.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 211eaf0ac3Slogwang.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 221eaf0ac3Slogwang.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 231eaf0ac3Slogwang.\" SUCH DAMAGE. 241eaf0ac3Slogwang.\" 251eaf0ac3Slogwang.\" $FreeBSD$ 261eaf0ac3Slogwang.\" 27*22ce4affSfengbojiang.Dd May 10, 2020 281eaf0ac3Slogwang.Dt PIDFILE 3 291eaf0ac3Slogwang.Os 301eaf0ac3Slogwang.Sh NAME 311eaf0ac3Slogwang.Nm pidfile_open , 321eaf0ac3Slogwang.Nm pidfile_write , 331eaf0ac3Slogwang.Nm pidfile_close , 341eaf0ac3Slogwang.Nm pidfile_remove 351eaf0ac3Slogwang.Nd "library for PID files handling" 361eaf0ac3Slogwang.Sh LIBRARY 371eaf0ac3Slogwang.Lb libutil 381eaf0ac3Slogwang.Sh SYNOPSIS 391eaf0ac3Slogwang.In libutil.h 401eaf0ac3Slogwang.Ft "struct pidfh *" 411eaf0ac3Slogwang.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr" 421eaf0ac3Slogwang.Ft int 431eaf0ac3Slogwang.Fn pidfile_write "struct pidfh *pfh" 441eaf0ac3Slogwang.Ft int 451eaf0ac3Slogwang.Fn pidfile_close "struct pidfh *pfh" 461eaf0ac3Slogwang.Ft int 471eaf0ac3Slogwang.Fn pidfile_remove "struct pidfh *pfh" 481eaf0ac3Slogwang.Ft int 491eaf0ac3Slogwang.Fn pidfile_fileno "struct pidfh *pfh" 501eaf0ac3Slogwang.Sh DESCRIPTION 511eaf0ac3SlogwangThe 521eaf0ac3Slogwang.Nm pidfile 531eaf0ac3Slogwangfamily of functions allows daemons to handle PID files. 541eaf0ac3SlogwangIt uses 551eaf0ac3Slogwang.Xr flopen 3 561eaf0ac3Slogwangto lock a pidfile and detect already running daemons. 571eaf0ac3Slogwang.Pp 581eaf0ac3SlogwangThe 591eaf0ac3Slogwang.Fn pidfile_open 601eaf0ac3Slogwangfunction opens (or creates) a file specified by the 611eaf0ac3Slogwang.Fa path 621eaf0ac3Slogwangargument and locks it. 631eaf0ac3SlogwangIf 641eaf0ac3Slogwang.Fa pidptr 651eaf0ac3Slogwangargument is not 661eaf0ac3Slogwang.Dv NULL 671eaf0ac3Slogwangand file can not be locked, the function will use it to store a PID of an 681eaf0ac3Slogwangalready running daemon or 691eaf0ac3Slogwang.Li -1 701eaf0ac3Slogwangin case daemon did not write its PID yet. 711eaf0ac3SlogwangThe function does not write process' PID into the file here, so it can be 721eaf0ac3Slogwangused before 731eaf0ac3Slogwang.Fn fork Ns ing 741eaf0ac3Slogwangand exit with a proper error message when needed. 751eaf0ac3SlogwangIf the 761eaf0ac3Slogwang.Fa path 771eaf0ac3Slogwangargument is 781eaf0ac3Slogwang.Dv NULL , 791eaf0ac3Slogwang.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid 801eaf0ac3Slogwangfile will be used. 811eaf0ac3SlogwangThe 821eaf0ac3Slogwang.Fn pidfile_open 831eaf0ac3Slogwangfunction sets the O_CLOEXEC close-on-exec flag when opening the pidfile. 841eaf0ac3Slogwang.Pp 851eaf0ac3SlogwangThe 861eaf0ac3Slogwang.Fn pidfile_write 871eaf0ac3Slogwangfunction writes process' PID into a previously opened file. 881eaf0ac3SlogwangThe file is truncated before write, so calling the 891eaf0ac3Slogwang.Fn pidfile_write 901eaf0ac3Slogwangfunction multiple times is supported. 911eaf0ac3Slogwang.Pp 921eaf0ac3SlogwangThe 931eaf0ac3Slogwang.Fn pidfile_close 941eaf0ac3Slogwangfunction closes a pidfile. 951eaf0ac3SlogwangIt should be used after daemon 961eaf0ac3Slogwang.Fn fork Ns s 971eaf0ac3Slogwangto start a child process. 981eaf0ac3Slogwang.Pp 991eaf0ac3SlogwangThe 1001eaf0ac3Slogwang.Fn pidfile_remove 1011eaf0ac3Slogwangfunction closes and removes a pidfile. 1021eaf0ac3Slogwang.Pp 1031eaf0ac3SlogwangThe 1041eaf0ac3Slogwang.Fn pidfile_fileno 1051eaf0ac3Slogwangfunction returns the file descriptor for the open pidfile. 1061eaf0ac3Slogwang.Sh RETURN VALUES 1071eaf0ac3SlogwangThe 1081eaf0ac3Slogwang.Fn pidfile_open 1091eaf0ac3Slogwangfunction returns a valid pointer to a 1101eaf0ac3Slogwang.Vt pidfh 1111eaf0ac3Slogwangstructure on success, or 1121eaf0ac3Slogwang.Dv NULL 1131eaf0ac3Slogwangif an error occurs. 1141eaf0ac3SlogwangIf an error occurs, 1151eaf0ac3Slogwang.Va errno 1161eaf0ac3Slogwangwill be set. 1171eaf0ac3Slogwang.Pp 1181eaf0ac3Slogwang.Rv -std pidfile_write pidfile_close pidfile_remove 1191eaf0ac3Slogwang.Pp 1201eaf0ac3SlogwangThe 1211eaf0ac3Slogwang.Fn pidfile_fileno 1221eaf0ac3Slogwangfunction returns the low-level file descriptor. 1231eaf0ac3SlogwangIt returns 1241eaf0ac3Slogwang.Li -1 1251eaf0ac3Slogwangand sets 1261eaf0ac3Slogwang.Va errno 1271eaf0ac3Slogwangif a NULL 1281eaf0ac3Slogwang.Vt pidfh 1291eaf0ac3Slogwangis specified, or if the pidfile is no longer open. 1301eaf0ac3Slogwang.Sh EXAMPLES 1311eaf0ac3SlogwangThe following example shows in which order these functions should be used. 1321eaf0ac3SlogwangNote that it is safe to pass 1331eaf0ac3Slogwang.Dv NULL 1341eaf0ac3Slogwangto 1351eaf0ac3Slogwang.Fn pidfile_write , 1361eaf0ac3Slogwang.Fn pidfile_remove , 1371eaf0ac3Slogwang.Fn pidfile_close 1381eaf0ac3Slogwangand 1391eaf0ac3Slogwang.Fn pidfile_fileno 1401eaf0ac3Slogwangfunctions. 1411eaf0ac3Slogwang.Bd -literal 1421eaf0ac3Slogwangstruct pidfh *pfh; 1431eaf0ac3Slogwangpid_t otherpid, childpid; 1441eaf0ac3Slogwang 1451eaf0ac3Slogwangpfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 1461eaf0ac3Slogwangif (pfh == NULL) { 1471eaf0ac3Slogwang if (errno == EEXIST) { 1481eaf0ac3Slogwang errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 1491eaf0ac3Slogwang (intmax_t)otherpid); 1501eaf0ac3Slogwang } 1511eaf0ac3Slogwang /* If we cannot create pidfile from other reasons, only warn. */ 1521eaf0ac3Slogwang warn("Cannot open or create pidfile"); 1531eaf0ac3Slogwang /* 1541eaf0ac3Slogwang * Even though pfh is NULL we can continue, as the other pidfile_* 1551eaf0ac3Slogwang * function can handle such situation by doing nothing except setting 1561eaf0ac3Slogwang * errno to EDOOFUS. 1571eaf0ac3Slogwang */ 1581eaf0ac3Slogwang} 1591eaf0ac3Slogwang 1601eaf0ac3Slogwangif (daemon(0, 0) == -1) { 1611eaf0ac3Slogwang warn("Cannot daemonize"); 1621eaf0ac3Slogwang pidfile_remove(pfh); 1631eaf0ac3Slogwang exit(EXIT_FAILURE); 1641eaf0ac3Slogwang} 1651eaf0ac3Slogwang 1661eaf0ac3Slogwangpidfile_write(pfh); 1671eaf0ac3Slogwang 1681eaf0ac3Slogwangfor (;;) { 1691eaf0ac3Slogwang /* Do work. */ 1701eaf0ac3Slogwang childpid = fork(); 1711eaf0ac3Slogwang switch (childpid) { 1721eaf0ac3Slogwang case -1: 1731eaf0ac3Slogwang syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 1741eaf0ac3Slogwang break; 1751eaf0ac3Slogwang case 0: 1761eaf0ac3Slogwang pidfile_close(pfh); 1771eaf0ac3Slogwang /* Do child work. */ 1781eaf0ac3Slogwang break; 1791eaf0ac3Slogwang default: 1801eaf0ac3Slogwang syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 1811eaf0ac3Slogwang break; 1821eaf0ac3Slogwang } 1831eaf0ac3Slogwang} 1841eaf0ac3Slogwang 1851eaf0ac3Slogwangpidfile_remove(pfh); 1861eaf0ac3Slogwangexit(EXIT_SUCCESS); 1871eaf0ac3Slogwang.Ed 1881eaf0ac3Slogwang.Sh ERRORS 1891eaf0ac3SlogwangThe 1901eaf0ac3Slogwang.Fn pidfile_open 1911eaf0ac3Slogwangfunction will fail if: 1921eaf0ac3Slogwang.Bl -tag -width Er 1931eaf0ac3Slogwang.It Bq Er EEXIST 1941eaf0ac3SlogwangSome process already holds the lock on the given pidfile, meaning that a 1951eaf0ac3Slogwangdaemon is already running. 1961eaf0ac3SlogwangIf 1971eaf0ac3Slogwang.Fa pidptr 1981eaf0ac3Slogwangargument is not 1991eaf0ac3Slogwang.Dv NULL 2001eaf0ac3Slogwangthe function will use it to store a PID of an already running daemon or 2011eaf0ac3Slogwang.Li -1 2021eaf0ac3Slogwangin case daemon did not write its PID yet. 2031eaf0ac3Slogwang.It Bq Er ENAMETOOLONG 2041eaf0ac3SlogwangSpecified pidfile's name is too long. 2051eaf0ac3Slogwang.It Bq Er EINVAL 2061eaf0ac3SlogwangSome process already holds the lock on the given pidfile, but PID read 2071eaf0ac3Slogwangfrom there is invalid. 2081eaf0ac3Slogwang.El 2091eaf0ac3Slogwang.Pp 2101eaf0ac3SlogwangThe 2111eaf0ac3Slogwang.Fn pidfile_open 2121eaf0ac3Slogwangfunction may also fail and set 2131eaf0ac3Slogwang.Va errno 2141eaf0ac3Slogwangfor any errors specified for the 2151eaf0ac3Slogwang.Xr fstat 2 , 2161eaf0ac3Slogwang.Xr open 2 , 2171eaf0ac3Slogwangand 2181eaf0ac3Slogwang.Xr read 2 2191eaf0ac3Slogwangcalls. 2201eaf0ac3Slogwang.Pp 2211eaf0ac3SlogwangThe 2221eaf0ac3Slogwang.Fn pidfile_write 2231eaf0ac3Slogwangfunction will fail if: 2241eaf0ac3Slogwang.Bl -tag -width Er 2251eaf0ac3Slogwang.It Bq Er EDOOFUS 2261eaf0ac3SlogwangImproper function use. 2271eaf0ac3SlogwangProbably called before 2281eaf0ac3Slogwang.Fn pidfile_open . 2291eaf0ac3Slogwang.El 2301eaf0ac3Slogwang.Pp 2311eaf0ac3SlogwangThe 2321eaf0ac3Slogwang.Fn pidfile_write 2331eaf0ac3Slogwangfunction may also fail and set 2341eaf0ac3Slogwang.Va errno 2351eaf0ac3Slogwangfor any errors specified for the 2361eaf0ac3Slogwang.Xr fstat 2 , 2371eaf0ac3Slogwang.Xr ftruncate 2 , 2381eaf0ac3Slogwangand 2391eaf0ac3Slogwang.Xr write 2 2401eaf0ac3Slogwangcalls. 2411eaf0ac3Slogwang.Pp 2421eaf0ac3SlogwangThe 2431eaf0ac3Slogwang.Fn pidfile_close 2441eaf0ac3Slogwangfunction may fail and set 2451eaf0ac3Slogwang.Va errno 2461eaf0ac3Slogwangfor any errors specified for the 2471eaf0ac3Slogwang.Xr close 2 2481eaf0ac3Slogwangand 2491eaf0ac3Slogwang.Xr fstat 2 2501eaf0ac3Slogwangcalls. 2511eaf0ac3Slogwang.Pp 2521eaf0ac3SlogwangThe 2531eaf0ac3Slogwang.Fn pidfile_remove 2541eaf0ac3Slogwangfunction will fail if: 2551eaf0ac3Slogwang.Bl -tag -width Er 2561eaf0ac3Slogwang.It Bq Er EDOOFUS 2571eaf0ac3SlogwangImproper function use. 2581eaf0ac3SlogwangProbably called not from the process which made 2591eaf0ac3Slogwang.Fn pidfile_write . 2601eaf0ac3Slogwang.El 2611eaf0ac3Slogwang.Pp 2621eaf0ac3SlogwangThe 2631eaf0ac3Slogwang.Fn pidfile_remove 2641eaf0ac3Slogwangfunction may also fail and set 2651eaf0ac3Slogwang.Va errno 2661eaf0ac3Slogwangfor any errors specified for the 2671eaf0ac3Slogwang.Xr close 2 , 2681eaf0ac3Slogwang.Xr fstat 2 , 2691eaf0ac3Slogwang.Xr write 2 , 2701eaf0ac3Slogwangand 2711eaf0ac3Slogwang.Xr unlink 2 2721eaf0ac3Slogwangsystem calls and the 2731eaf0ac3Slogwang.Xr flopen 3 2741eaf0ac3Slogwanglibrary function. 2751eaf0ac3Slogwang.Pp 2761eaf0ac3SlogwangThe 2771eaf0ac3Slogwang.Fn pidfile_fileno 2781eaf0ac3Slogwangfunction will fail if: 2791eaf0ac3Slogwang.Bl -tag -width Er 2801eaf0ac3Slogwang.It Bq Er EDOOFUS 2811eaf0ac3SlogwangImproper function use. 2821eaf0ac3SlogwangProbably called not from the process which used 2831eaf0ac3Slogwang.Fn pidfile_open . 2841eaf0ac3Slogwang.El 2851eaf0ac3Slogwang.Sh SEE ALSO 2861eaf0ac3Slogwang.Xr open 2 , 2871eaf0ac3Slogwang.Xr daemon 3 , 2881eaf0ac3Slogwang.Xr flopen 3 289*22ce4affSfengbojiang.Sh HISTORY 290*22ce4affSfengbojiangThe functions 291*22ce4affSfengbojiang.Fn pidfile_open , 292*22ce4affSfengbojiang.Fn pidfile_write , 293*22ce4affSfengbojiang.Fn pidfile_close 294*22ce4affSfengbojiangand 295*22ce4affSfengbojiang.Fn pidfile_remove 296*22ce4affSfengbojiangfirst appeared in 297*22ce4affSfengbojiang.Fx 5.5 . 2981eaf0ac3Slogwang.Sh AUTHORS 2991eaf0ac3Slogwang.An -nosplit 3001eaf0ac3SlogwangThe 3011eaf0ac3Slogwang.Nm pidfile 3021eaf0ac3Slogwangfunctionality is based on ideas from 3031eaf0ac3Slogwang.An John-Mark Gurney Aq Mt [email protected] . 3041eaf0ac3Slogwang.Pp 3051eaf0ac3SlogwangThe code and manual page was written by 3061eaf0ac3Slogwang.An Pawel Jakub Dawidek Aq Mt [email protected] . 307