xref: /freebsd/lib/libutil/pidfile.3 (revision e8cc80c0a07bf3235090c7d32b7b6b746842eba8)
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.\"
27*e8cc80c0SPawel 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"
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.
62*e8cc80c0SPawel Jakub DawidekIf
63412fa8f1SPawel Jakub Dawidek.Fa pidptr
64*e8cc80c0SPawel Jakub Dawidekargument is not
65*e8cc80c0SPawel Jakub Dawidek.Dv NULL
66*e8cc80c0SPawel Jakub Dawidekand file can not be locked, the function will use it to store a PID of an
67*e8cc80c0SPawel Jakub Dawidekalready running daemon or
68*e8cc80c0SPawel Jakub Dawidek.Li -1
69*e8cc80c0SPawel Jakub Dawidekin case daemon did not write its PID yet.
706b84cd58SRuslan ErmilovThe function does not write process' PID into the file here, so it can be
716b84cd58SRuslan Ermilovused before
726b84cd58SRuslan Ermilov.Fn fork Ns ing
736b84cd58SRuslan Ermilovand exit with a proper error message when needed.
746b84cd58SRuslan ErmilovIf the
75412fa8f1SPawel Jakub Dawidek.Fa path
766b84cd58SRuslan Ermilovargument is
776b84cd58SRuslan Ermilov.Dv NULL ,
786b84cd58SRuslan Ermilov.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid
79412fa8f1SPawel Jakub Dawidekfile will be used.
80412fa8f1SPawel Jakub Dawidek.Pp
81412fa8f1SPawel Jakub DawidekThe
82412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
836b84cd58SRuslan Ermilovfunction writes process' PID into a previously opened file.
84412fa8f1SPawel Jakub Dawidek.Pp
85412fa8f1SPawel Jakub DawidekThe
86412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
876b84cd58SRuslan Ermilovfunction closes a pidfile.
886b84cd58SRuslan ErmilovIt should be used after daemon
896b84cd58SRuslan Ermilov.Fn fork Ns s
906b84cd58SRuslan Ermilovto start a child process.
91412fa8f1SPawel Jakub Dawidek.Pp
92412fa8f1SPawel Jakub DawidekThe
93412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
946b84cd58SRuslan Ermilovfunction closes and removes a pidfile.
95412fa8f1SPawel Jakub Dawidek.Sh RETURN VALUES
96412fa8f1SPawel Jakub DawidekThe
97412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
986b84cd58SRuslan Ermilovfunction returns a valid pointer to a
996b84cd58SRuslan Ermilov.Vt pidfh
1006b84cd58SRuslan Ermilovstructure on success, or
101412fa8f1SPawel Jakub Dawidek.Dv NULL
102412fa8f1SPawel Jakub Dawidekif an error occurs.
1036b84cd58SRuslan ErmilovIf an error occurs,
104412fa8f1SPawel Jakub Dawidek.Va errno
105412fa8f1SPawel Jakub Dawidekwill be set.
106a27c52a9SDag-Erling Smørgrav.Pp
107412fa8f1SPawel Jakub Dawidek.Rv -std pidfile_write pidfile_close pidfile_remove
108412fa8f1SPawel Jakub Dawidek.Sh EXAMPLES
1096b84cd58SRuslan ErmilovThe following example shows in which order these functions should be used.
110560c4fc1SPawel Jakub DawidekNote that it is safe to pass
111560c4fc1SPawel Jakub Dawidek.Dv NULL
112560c4fc1SPawel Jakub Dawidekto
113560c4fc1SPawel Jakub Dawidek.Fn pidfile_write ,
114560c4fc1SPawel Jakub Dawidek.Fn pidfile_remove
115560c4fc1SPawel Jakub Dawidekand
116560c4fc1SPawel Jakub Dawidek.Fn pidfile_close
117560c4fc1SPawel Jakub Dawidekfunctions.
118412fa8f1SPawel Jakub Dawidek.Bd -literal
119412fa8f1SPawel Jakub Dawidekstruct pidfh *pfh;
120412fa8f1SPawel Jakub Dawidekpid_t otherpid, childpid;
121412fa8f1SPawel Jakub Dawidek
1228b28aef2SPawel Jakub Dawidekpfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
123412fa8f1SPawel Jakub Dawidekif (pfh == NULL) {
124560c4fc1SPawel Jakub Dawidek	if (errno == EEXIST) {
125ef608a60SGiorgos Keramidas		errx(EXIT_FAILURE, "Daemon already running, pid: %jd.",
126ef608a60SGiorgos Keramidas		    (intmax_t)otherpid);
127560c4fc1SPawel Jakub Dawidek	}
128412fa8f1SPawel Jakub Dawidek	/* If we cannot create pidfile from other reasons, only warn. */
129412fa8f1SPawel Jakub Dawidek	warn("Cannot open or create pidfile");
130412fa8f1SPawel Jakub Dawidek}
131412fa8f1SPawel Jakub Dawidek
132412fa8f1SPawel Jakub Dawidekif (daemon(0, 0) == -1) {
133412fa8f1SPawel Jakub Dawidek	warn("Cannot daemonize");
134412fa8f1SPawel Jakub Dawidek	pidfile_remove(pfh);
135412fa8f1SPawel Jakub Dawidek	exit(EXIT_FAILURE);
136412fa8f1SPawel Jakub Dawidek}
137412fa8f1SPawel Jakub Dawidek
138412fa8f1SPawel Jakub Dawidekpidfile_write(pfh);
139412fa8f1SPawel Jakub Dawidek
140412fa8f1SPawel Jakub Dawidekfor (;;) {
141412fa8f1SPawel Jakub Dawidek	/* Do work. */
142412fa8f1SPawel Jakub Dawidek	childpid = fork();
143412fa8f1SPawel Jakub Dawidek	switch (childpid) {
144412fa8f1SPawel Jakub Dawidek	case -1:
145412fa8f1SPawel Jakub Dawidek		syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
146412fa8f1SPawel Jakub Dawidek		break;
147412fa8f1SPawel Jakub Dawidek	case 0:
148412fa8f1SPawel Jakub Dawidek		pidfile_close(pfh);
149412fa8f1SPawel Jakub Dawidek		/* Do child work. */
150412fa8f1SPawel Jakub Dawidek		break;
151412fa8f1SPawel Jakub Dawidek	default:
152ef608a60SGiorgos Keramidas		syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
153412fa8f1SPawel Jakub Dawidek		break;
154412fa8f1SPawel Jakub Dawidek	}
155412fa8f1SPawel Jakub Dawidek}
156412fa8f1SPawel Jakub Dawidek
157412fa8f1SPawel Jakub Dawidekpidfile_remove(pfh);
158412fa8f1SPawel Jakub Dawidekexit(EXIT_SUCCESS);
159412fa8f1SPawel Jakub Dawidek.Ed
160412fa8f1SPawel Jakub Dawidek.Sh ERRORS
161412fa8f1SPawel Jakub DawidekThe
162412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
163412fa8f1SPawel Jakub Dawidekfunction will fail if:
164412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
165412fa8f1SPawel Jakub Dawidek.It Bq Er EEXIST
1666b84cd58SRuslan ErmilovSome process already holds the lock on the given pidfile, meaning that a
167412fa8f1SPawel Jakub Dawidekdaemon is already running.
168*e8cc80c0SPawel Jakub DawidekIf
169*e8cc80c0SPawel Jakub Dawidek.Fa pidptr
170*e8cc80c0SPawel Jakub Dawidekargument is not
171*e8cc80c0SPawel Jakub Dawidek.Dv NULL
172*e8cc80c0SPawel Jakub Dawidekthe function will use it to store a PID of an already running daemon or
173*e8cc80c0SPawel Jakub Dawidek.Li -1
174*e8cc80c0SPawel Jakub Dawidekin case daemon did not write its PID yet.
175412fa8f1SPawel Jakub Dawidek.It Bq Er ENAMETOOLONG
176412fa8f1SPawel Jakub DawidekSpecified pidfile's name is too long.
177412fa8f1SPawel Jakub Dawidek.It Bq Er EINVAL
178412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, but PID read
179412fa8f1SPawel Jakub Dawidekfrom there is invalid.
180412fa8f1SPawel Jakub Dawidek.El
181412fa8f1SPawel Jakub Dawidek.Pp
182412fa8f1SPawel Jakub DawidekThe
183412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
184412fa8f1SPawel Jakub Dawidekfunction may also fail and set
185412fa8f1SPawel Jakub Dawidek.Va errno
186412fa8f1SPawel Jakub Dawidekfor any errors specified for the
187412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
188412fa8f1SPawel Jakub Dawidek.Xr open 2 ,
1896b84cd58SRuslan Ermilovand
190412fa8f1SPawel Jakub Dawidek.Xr read 2
1916b84cd58SRuslan Ermilovcalls.
192412fa8f1SPawel Jakub Dawidek.Pp
193412fa8f1SPawel Jakub DawidekThe
194412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
195412fa8f1SPawel Jakub Dawidekfunction will fail if:
196412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
197412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
1986b84cd58SRuslan ErmilovImproper function use.
199412fa8f1SPawel Jakub DawidekProbably called before
200412fa8f1SPawel Jakub Dawidek.Fn pidfile_open .
201412fa8f1SPawel Jakub Dawidek.El
202412fa8f1SPawel Jakub Dawidek.Pp
203412fa8f1SPawel Jakub DawidekThe
204412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
205412fa8f1SPawel Jakub Dawidekfunction may also fail and set
206412fa8f1SPawel Jakub Dawidek.Va errno
207412fa8f1SPawel Jakub Dawidekfor any errors specified for the
208412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
209412fa8f1SPawel Jakub Dawidek.Xr ftruncate 2 ,
2106b84cd58SRuslan Ermilovand
211412fa8f1SPawel Jakub Dawidek.Xr write 2
2126b84cd58SRuslan Ermilovcalls.
213412fa8f1SPawel Jakub Dawidek.Pp
214412fa8f1SPawel Jakub DawidekThe
215412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
216412fa8f1SPawel Jakub Dawidekfunction may fail and set
217412fa8f1SPawel Jakub Dawidek.Va errno
218412fa8f1SPawel Jakub Dawidekfor any errors specified for the
2196b84cd58SRuslan Ermilov.Xr close 2
2206b84cd58SRuslan Ermilovand
221412fa8f1SPawel Jakub Dawidek.Xr fstat 2
2226b84cd58SRuslan Ermilovcalls.
223412fa8f1SPawel Jakub Dawidek.Pp
224412fa8f1SPawel Jakub DawidekThe
225412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
226412fa8f1SPawel Jakub Dawidekfunction will fail if:
227412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
228412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
2296b84cd58SRuslan ErmilovImproper function use.
230412fa8f1SPawel Jakub DawidekProbably called not from the process which made
231412fa8f1SPawel Jakub Dawidek.Fn pidfile_write .
232412fa8f1SPawel Jakub Dawidek.El
233412fa8f1SPawel Jakub Dawidek.Pp
234412fa8f1SPawel Jakub DawidekThe
235412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
236412fa8f1SPawel Jakub Dawidekfunction may also fail and set
237412fa8f1SPawel Jakub Dawidek.Va errno
238412fa8f1SPawel Jakub Dawidekfor any errors specified for the
239412fa8f1SPawel Jakub Dawidek.Xr close 2 ,
240412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
241412fa8f1SPawel Jakub Dawidek.Xr write 2 ,
2426b84cd58SRuslan Ermilovand
243412fa8f1SPawel Jakub Dawidek.Xr unlink 2
244cb7cd07aSDag-Erling Smørgravsystem calls and the
245cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
246cb7cd07aSDag-Erling Smørgravlibrary function.
247412fa8f1SPawel Jakub Dawidek.Sh SEE ALSO
248412fa8f1SPawel Jakub Dawidek.Xr open 2 ,
249cb7cd07aSDag-Erling Smørgrav.Xr daemon 3 ,
250cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
251412fa8f1SPawel Jakub Dawidek.Sh AUTHORS
252412fa8f1SPawel Jakub Dawidek.An -nosplit
253412fa8f1SPawel Jakub DawidekThe
2546b84cd58SRuslan Ermilov.Nm pidfile
255412fa8f1SPawel Jakub Dawidekfunctionality is based on ideas from
256412fa8f1SPawel Jakub Dawidek.An John-Mark Gurney Aq jmg@FreeBSD.org .
257412fa8f1SPawel Jakub Dawidek.Pp
258412fa8f1SPawel Jakub DawidekThe code and manual page was written by
259412fa8f1SPawel Jakub Dawidek.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
260