xref: /freebsd/lib/libutil/pidfile.3 (revision f295618d06dd1b215fcd963b33c1265acea36ac9)
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"
49*f295618dSGuy Helmer.Ft int
50*f295618dSGuy 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.
82412fa8f1SPawel Jakub Dawidek.Pp
83412fa8f1SPawel Jakub DawidekThe
84412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
856b84cd58SRuslan Ermilovfunction writes process' PID into a previously opened file.
86412fa8f1SPawel Jakub Dawidek.Pp
87412fa8f1SPawel Jakub DawidekThe
88412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
896b84cd58SRuslan Ermilovfunction closes a pidfile.
906b84cd58SRuslan ErmilovIt should be used after daemon
916b84cd58SRuslan Ermilov.Fn fork Ns s
926b84cd58SRuslan Ermilovto start a child process.
93412fa8f1SPawel Jakub Dawidek.Pp
94412fa8f1SPawel Jakub DawidekThe
95412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
966b84cd58SRuslan Ermilovfunction closes and removes a pidfile.
97*f295618dSGuy Helmer.Pp
98*f295618dSGuy HelmerThe
99*f295618dSGuy Helmer.Fn pidfile_fileno
100*f295618dSGuy Helmerfunction returns the file descriptor for the open pid file.
101412fa8f1SPawel Jakub Dawidek.Sh RETURN VALUES
102412fa8f1SPawel Jakub DawidekThe
103412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
1046b84cd58SRuslan Ermilovfunction returns a valid pointer to a
1056b84cd58SRuslan Ermilov.Vt pidfh
1066b84cd58SRuslan Ermilovstructure on success, or
107412fa8f1SPawel Jakub Dawidek.Dv NULL
108412fa8f1SPawel Jakub Dawidekif an error occurs.
1096b84cd58SRuslan ErmilovIf an error occurs,
110412fa8f1SPawel Jakub Dawidek.Va errno
111412fa8f1SPawel Jakub Dawidekwill be set.
112a27c52a9SDag-Erling Smørgrav.Pp
113412fa8f1SPawel Jakub Dawidek.Rv -std pidfile_write pidfile_close pidfile_remove
114*f295618dSGuy Helmer.Pp
115*f295618dSGuy HelmerThe
116*f295618dSGuy Helmer.Fn pidfile_fileno
117*f295618dSGuy Helmerfunction returns the low-level file descriptor.
118*f295618dSGuy HelmerIt returns -1 and sets
119*f295618dSGuy Helmer.Va errno
120*f295618dSGuy Helmerif a NULL
121*f295618dSGuy Helmer.Vt pidfh
122*f295618dSGuy Helmeris specified, or if the pidfile is no longer open.
123412fa8f1SPawel Jakub Dawidek.Sh EXAMPLES
1246b84cd58SRuslan ErmilovThe following example shows in which order these functions should be used.
125560c4fc1SPawel Jakub DawidekNote that it is safe to pass
126560c4fc1SPawel Jakub Dawidek.Dv NULL
127560c4fc1SPawel Jakub Dawidekto
128560c4fc1SPawel Jakub Dawidek.Fn pidfile_write ,
129*f295618dSGuy Helmer.Fn pidfile_remove ,
130560c4fc1SPawel Jakub Dawidek.Fn pidfile_close
131*f295618dSGuy Helmerand
132*f295618dSGuy Helmer.Fn pidfile_fileno
133560c4fc1SPawel Jakub Dawidekfunctions.
134412fa8f1SPawel Jakub Dawidek.Bd -literal
135412fa8f1SPawel Jakub Dawidekstruct pidfh *pfh;
136412fa8f1SPawel Jakub Dawidekpid_t otherpid, childpid;
137412fa8f1SPawel Jakub Dawidek
1388b28aef2SPawel Jakub Dawidekpfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
139412fa8f1SPawel Jakub Dawidekif (pfh == NULL) {
140560c4fc1SPawel Jakub Dawidek	if (errno == EEXIST) {
141ef608a60SGiorgos Keramidas		errx(EXIT_FAILURE, "Daemon already running, pid: %jd.",
142ef608a60SGiorgos Keramidas		    (intmax_t)otherpid);
143560c4fc1SPawel Jakub Dawidek	}
144412fa8f1SPawel Jakub Dawidek	/* If we cannot create pidfile from other reasons, only warn. */
145412fa8f1SPawel Jakub Dawidek	warn("Cannot open or create pidfile");
146412fa8f1SPawel Jakub Dawidek}
147412fa8f1SPawel Jakub Dawidek
148412fa8f1SPawel Jakub Dawidekif (daemon(0, 0) == -1) {
149412fa8f1SPawel Jakub Dawidek	warn("Cannot daemonize");
150412fa8f1SPawel Jakub Dawidek	pidfile_remove(pfh);
151412fa8f1SPawel Jakub Dawidek	exit(EXIT_FAILURE);
152412fa8f1SPawel Jakub Dawidek}
153412fa8f1SPawel Jakub Dawidek
154412fa8f1SPawel Jakub Dawidekpidfile_write(pfh);
155412fa8f1SPawel Jakub Dawidek
156412fa8f1SPawel Jakub Dawidekfor (;;) {
157412fa8f1SPawel Jakub Dawidek	/* Do work. */
158412fa8f1SPawel Jakub Dawidek	childpid = fork();
159412fa8f1SPawel Jakub Dawidek	switch (childpid) {
160412fa8f1SPawel Jakub Dawidek	case -1:
161412fa8f1SPawel Jakub Dawidek		syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
162412fa8f1SPawel Jakub Dawidek		break;
163412fa8f1SPawel Jakub Dawidek	case 0:
164412fa8f1SPawel Jakub Dawidek		pidfile_close(pfh);
165412fa8f1SPawel Jakub Dawidek		/* Do child work. */
166412fa8f1SPawel Jakub Dawidek		break;
167412fa8f1SPawel Jakub Dawidek	default:
168ef608a60SGiorgos Keramidas		syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
169412fa8f1SPawel Jakub Dawidek		break;
170412fa8f1SPawel Jakub Dawidek	}
171412fa8f1SPawel Jakub Dawidek}
172412fa8f1SPawel Jakub Dawidek
173412fa8f1SPawel Jakub Dawidekpidfile_remove(pfh);
174412fa8f1SPawel Jakub Dawidekexit(EXIT_SUCCESS);
175412fa8f1SPawel Jakub Dawidek.Ed
176412fa8f1SPawel Jakub Dawidek.Sh ERRORS
177412fa8f1SPawel Jakub DawidekThe
178412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
179412fa8f1SPawel Jakub Dawidekfunction will fail if:
180412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
181412fa8f1SPawel Jakub Dawidek.It Bq Er EEXIST
1826b84cd58SRuslan ErmilovSome process already holds the lock on the given pidfile, meaning that a
183412fa8f1SPawel Jakub Dawidekdaemon is already running.
184e8cc80c0SPawel Jakub DawidekIf
185e8cc80c0SPawel Jakub Dawidek.Fa pidptr
186e8cc80c0SPawel Jakub Dawidekargument is not
187e8cc80c0SPawel Jakub Dawidek.Dv NULL
188e8cc80c0SPawel Jakub Dawidekthe function will use it to store a PID of an already running daemon or
189e8cc80c0SPawel Jakub Dawidek.Li -1
190e8cc80c0SPawel Jakub Dawidekin case daemon did not write its PID yet.
191412fa8f1SPawel Jakub Dawidek.It Bq Er ENAMETOOLONG
192412fa8f1SPawel Jakub DawidekSpecified pidfile's name is too long.
193412fa8f1SPawel Jakub Dawidek.It Bq Er EINVAL
194412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, but PID read
195412fa8f1SPawel Jakub Dawidekfrom there is invalid.
196412fa8f1SPawel Jakub Dawidek.El
197412fa8f1SPawel Jakub Dawidek.Pp
198412fa8f1SPawel Jakub DawidekThe
199412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
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 open 2 ,
2056b84cd58SRuslan Ermilovand
206412fa8f1SPawel Jakub Dawidek.Xr read 2
2076b84cd58SRuslan Ermilovcalls.
208412fa8f1SPawel Jakub Dawidek.Pp
209412fa8f1SPawel Jakub DawidekThe
210412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
211412fa8f1SPawel Jakub Dawidekfunction will fail if:
212412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
213412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
2146b84cd58SRuslan ErmilovImproper function use.
215412fa8f1SPawel Jakub DawidekProbably called before
216412fa8f1SPawel Jakub Dawidek.Fn pidfile_open .
217412fa8f1SPawel Jakub Dawidek.El
218412fa8f1SPawel Jakub Dawidek.Pp
219412fa8f1SPawel Jakub DawidekThe
220412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
221412fa8f1SPawel Jakub Dawidekfunction may also fail and set
222412fa8f1SPawel Jakub Dawidek.Va errno
223412fa8f1SPawel Jakub Dawidekfor any errors specified for the
224412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
225412fa8f1SPawel Jakub Dawidek.Xr ftruncate 2 ,
2266b84cd58SRuslan Ermilovand
227412fa8f1SPawel Jakub Dawidek.Xr write 2
2286b84cd58SRuslan Ermilovcalls.
229412fa8f1SPawel Jakub Dawidek.Pp
230412fa8f1SPawel Jakub DawidekThe
231412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
232412fa8f1SPawel Jakub Dawidekfunction may fail and set
233412fa8f1SPawel Jakub Dawidek.Va errno
234412fa8f1SPawel Jakub Dawidekfor any errors specified for the
2356b84cd58SRuslan Ermilov.Xr close 2
2366b84cd58SRuslan Ermilovand
237412fa8f1SPawel Jakub Dawidek.Xr fstat 2
2386b84cd58SRuslan Ermilovcalls.
239412fa8f1SPawel Jakub Dawidek.Pp
240412fa8f1SPawel Jakub DawidekThe
241412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
242412fa8f1SPawel Jakub Dawidekfunction will fail if:
243412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
244412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
2456b84cd58SRuslan ErmilovImproper function use.
246412fa8f1SPawel Jakub DawidekProbably called not from the process which made
247412fa8f1SPawel Jakub Dawidek.Fn pidfile_write .
248412fa8f1SPawel Jakub Dawidek.El
249412fa8f1SPawel Jakub Dawidek.Pp
250412fa8f1SPawel Jakub DawidekThe
251412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
252412fa8f1SPawel Jakub Dawidekfunction may also fail and set
253412fa8f1SPawel Jakub Dawidek.Va errno
254412fa8f1SPawel Jakub Dawidekfor any errors specified for the
255412fa8f1SPawel Jakub Dawidek.Xr close 2 ,
256412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
257412fa8f1SPawel Jakub Dawidek.Xr write 2 ,
2586b84cd58SRuslan Ermilovand
259412fa8f1SPawel Jakub Dawidek.Xr unlink 2
260cb7cd07aSDag-Erling Smørgravsystem calls and the
261cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
262cb7cd07aSDag-Erling Smørgravlibrary function.
263*f295618dSGuy Helmer.Pp
264*f295618dSGuy HelmerThe
265*f295618dSGuy Helmer.Fn pidfile_fileno
266*f295618dSGuy Helmerfunction will fail if:
267*f295618dSGuy Helmer.Bl -tag -width Er
268*f295618dSGuy Helmer.It Bq Er EDOOFUS
269*f295618dSGuy HelmerImproper function use.
270*f295618dSGuy HelmerProbably called not from the process which used
271*f295618dSGuy Helmer.Fn pidfile_open .
272*f295618dSGuy Helmer.El
273412fa8f1SPawel Jakub Dawidek.Sh SEE ALSO
274412fa8f1SPawel Jakub Dawidek.Xr open 2 ,
275cb7cd07aSDag-Erling Smørgrav.Xr daemon 3 ,
276cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
277412fa8f1SPawel Jakub Dawidek.Sh AUTHORS
278412fa8f1SPawel Jakub Dawidek.An -nosplit
279412fa8f1SPawel Jakub DawidekThe
2806b84cd58SRuslan Ermilov.Nm pidfile
281412fa8f1SPawel Jakub Dawidekfunctionality is based on ideas from
282412fa8f1SPawel Jakub Dawidek.An John-Mark Gurney Aq jmg@FreeBSD.org .
283412fa8f1SPawel Jakub Dawidek.Pp
284412fa8f1SPawel Jakub DawidekThe code and manual page was written by
285412fa8f1SPawel Jakub Dawidek.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
286