xref: /f-stack/tools/libutil/pidfile.3 (revision 22ce4aff)
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