xref: /freebsd/lib/libutil/pidfile.3 (revision 7f8d054f8aa98ec4697381bc16e948fa39e436d9)
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*7f8d054fSPawel Jakub Dawidek.Dd February 8, 2012
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 libutil.h
406b84cd58SRuslan Ermilov.Ft "struct pidfh *"
41412fa8f1SPawel Jakub Dawidek.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr"
42412fa8f1SPawel Jakub Dawidek.Ft int
43412fa8f1SPawel Jakub Dawidek.Fn pidfile_write "struct pidfh *pfh"
44412fa8f1SPawel Jakub Dawidek.Ft int
45412fa8f1SPawel Jakub Dawidek.Fn pidfile_close "struct pidfh *pfh"
46412fa8f1SPawel Jakub Dawidek.Ft int
47412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove "struct pidfh *pfh"
48f295618dSGuy Helmer.Ft int
49f295618dSGuy Helmer.Fn pidfile_fileno "struct pidfh *pfh"
50412fa8f1SPawel Jakub Dawidek.Sh DESCRIPTION
51412fa8f1SPawel Jakub DawidekThe
526b84cd58SRuslan Ermilov.Nm pidfile
536b84cd58SRuslan Ermilovfamily of functions allows daemons to handle PID files.
54412fa8f1SPawel Jakub DawidekIt uses
55cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
566b84cd58SRuslan Ermilovto lock a pidfile and detect already running daemons.
57412fa8f1SPawel Jakub Dawidek.Pp
58412fa8f1SPawel Jakub DawidekThe
59412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
606b84cd58SRuslan Ermilovfunction opens (or creates) a file specified by the
61412fa8f1SPawel Jakub Dawidek.Fa path
62cb7cd07aSDag-Erling Smørgravargument and locks it.
63e8cc80c0SPawel Jakub DawidekIf
64412fa8f1SPawel Jakub Dawidek.Fa pidptr
65e8cc80c0SPawel Jakub Dawidekargument is not
66e8cc80c0SPawel Jakub Dawidek.Dv NULL
67e8cc80c0SPawel Jakub Dawidekand file can not be locked, the function will use it to store a PID of an
68e8cc80c0SPawel Jakub Dawidekalready running daemon or
69e8cc80c0SPawel Jakub Dawidek.Li -1
70e8cc80c0SPawel Jakub Dawidekin case daemon did not write its PID yet.
716b84cd58SRuslan ErmilovThe function does not write process' PID into the file here, so it can be
726b84cd58SRuslan Ermilovused before
736b84cd58SRuslan Ermilov.Fn fork Ns ing
746b84cd58SRuslan Ermilovand exit with a proper error message when needed.
756b84cd58SRuslan ErmilovIf the
76412fa8f1SPawel Jakub Dawidek.Fa path
776b84cd58SRuslan Ermilovargument is
786b84cd58SRuslan Ermilov.Dv NULL ,
796b84cd58SRuslan Ermilov.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid
80412fa8f1SPawel Jakub Dawidekfile will be used.
81719060e9SGuy HelmerThe
82719060e9SGuy Helmer.Fn pidfile_open
8350636e13SGuy Helmerfunction sets the O_CLOEXEC close-on-exec flag when opening the pidfile.
84412fa8f1SPawel Jakub Dawidek.Pp
85412fa8f1SPawel Jakub DawidekThe
86412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
876b84cd58SRuslan Ermilovfunction writes process' PID into a previously opened file.
88*7f8d054fSPawel Jakub DawidekThe file is truncated before write, so calling the
89*7f8d054fSPawel Jakub Dawidek.Fn pidfile_write
90*7f8d054fSPawel Jakub Dawidekfunction multiple times is supported.
91412fa8f1SPawel Jakub Dawidek.Pp
92412fa8f1SPawel Jakub DawidekThe
93412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
946b84cd58SRuslan Ermilovfunction closes a pidfile.
956b84cd58SRuslan ErmilovIt should be used after daemon
966b84cd58SRuslan Ermilov.Fn fork Ns s
976b84cd58SRuslan Ermilovto start a child process.
98412fa8f1SPawel Jakub Dawidek.Pp
99412fa8f1SPawel Jakub DawidekThe
100412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
1016b84cd58SRuslan Ermilovfunction closes and removes a pidfile.
102f295618dSGuy Helmer.Pp
103f295618dSGuy HelmerThe
104f295618dSGuy Helmer.Fn pidfile_fileno
105f295618dSGuy Helmerfunction returns the file descriptor for the open pidfile.
106412fa8f1SPawel Jakub Dawidek.Sh RETURN VALUES
107412fa8f1SPawel Jakub DawidekThe
108412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
1096b84cd58SRuslan Ermilovfunction returns a valid pointer to a
1106b84cd58SRuslan Ermilov.Vt pidfh
1116b84cd58SRuslan Ermilovstructure on success, or
112412fa8f1SPawel Jakub Dawidek.Dv NULL
113412fa8f1SPawel Jakub Dawidekif an error occurs.
1146b84cd58SRuslan ErmilovIf an error occurs,
115412fa8f1SPawel Jakub Dawidek.Va errno
116412fa8f1SPawel Jakub Dawidekwill be set.
117a27c52a9SDag-Erling Smørgrav.Pp
118412fa8f1SPawel Jakub Dawidek.Rv -std pidfile_write pidfile_close pidfile_remove
119f295618dSGuy Helmer.Pp
120f295618dSGuy HelmerThe
121f295618dSGuy Helmer.Fn pidfile_fileno
122f295618dSGuy Helmerfunction returns the low-level file descriptor.
1234a25aa06SGuy HelmerIt returns
1244a25aa06SGuy Helmer.Li -1
1254a25aa06SGuy Helmerand sets
126f295618dSGuy Helmer.Va errno
127f295618dSGuy Helmerif a NULL
128f295618dSGuy Helmer.Vt pidfh
129f295618dSGuy Helmeris specified, or if the pidfile is no longer open.
130412fa8f1SPawel Jakub Dawidek.Sh EXAMPLES
1316b84cd58SRuslan ErmilovThe following example shows in which order these functions should be used.
132560c4fc1SPawel Jakub DawidekNote that it is safe to pass
133560c4fc1SPawel Jakub Dawidek.Dv NULL
134560c4fc1SPawel Jakub Dawidekto
135560c4fc1SPawel Jakub Dawidek.Fn pidfile_write ,
136f295618dSGuy Helmer.Fn pidfile_remove ,
137560c4fc1SPawel Jakub Dawidek.Fn pidfile_close
138f295618dSGuy Helmerand
139f295618dSGuy Helmer.Fn pidfile_fileno
140560c4fc1SPawel Jakub Dawidekfunctions.
141412fa8f1SPawel Jakub Dawidek.Bd -literal
142412fa8f1SPawel Jakub Dawidekstruct pidfh *pfh;
143412fa8f1SPawel Jakub Dawidekpid_t otherpid, childpid;
144412fa8f1SPawel Jakub Dawidek
1458b28aef2SPawel Jakub Dawidekpfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
146412fa8f1SPawel Jakub Dawidekif (pfh == NULL) {
147560c4fc1SPawel Jakub Dawidek	if (errno == EEXIST) {
148ef608a60SGiorgos Keramidas		errx(EXIT_FAILURE, "Daemon already running, pid: %jd.",
149ef608a60SGiorgos Keramidas		    (intmax_t)otherpid);
150560c4fc1SPawel Jakub Dawidek	}
151412fa8f1SPawel Jakub Dawidek	/* If we cannot create pidfile from other reasons, only warn. */
152412fa8f1SPawel Jakub Dawidek	warn("Cannot open or create pidfile");
153412fa8f1SPawel Jakub Dawidek}
154412fa8f1SPawel Jakub Dawidek
155412fa8f1SPawel Jakub Dawidekif (daemon(0, 0) == -1) {
156412fa8f1SPawel Jakub Dawidek	warn("Cannot daemonize");
157412fa8f1SPawel Jakub Dawidek	pidfile_remove(pfh);
158412fa8f1SPawel Jakub Dawidek	exit(EXIT_FAILURE);
159412fa8f1SPawel Jakub Dawidek}
160412fa8f1SPawel Jakub Dawidek
161412fa8f1SPawel Jakub Dawidekpidfile_write(pfh);
162412fa8f1SPawel Jakub Dawidek
163412fa8f1SPawel Jakub Dawidekfor (;;) {
164412fa8f1SPawel Jakub Dawidek	/* Do work. */
165412fa8f1SPawel Jakub Dawidek	childpid = fork();
166412fa8f1SPawel Jakub Dawidek	switch (childpid) {
167412fa8f1SPawel Jakub Dawidek	case -1:
168412fa8f1SPawel Jakub Dawidek		syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
169412fa8f1SPawel Jakub Dawidek		break;
170412fa8f1SPawel Jakub Dawidek	case 0:
171412fa8f1SPawel Jakub Dawidek		pidfile_close(pfh);
172412fa8f1SPawel Jakub Dawidek		/* Do child work. */
173412fa8f1SPawel Jakub Dawidek		break;
174412fa8f1SPawel Jakub Dawidek	default:
175ef608a60SGiorgos Keramidas		syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
176412fa8f1SPawel Jakub Dawidek		break;
177412fa8f1SPawel Jakub Dawidek	}
178412fa8f1SPawel Jakub Dawidek}
179412fa8f1SPawel Jakub Dawidek
180412fa8f1SPawel Jakub Dawidekpidfile_remove(pfh);
181412fa8f1SPawel Jakub Dawidekexit(EXIT_SUCCESS);
182412fa8f1SPawel Jakub Dawidek.Ed
183412fa8f1SPawel Jakub Dawidek.Sh ERRORS
184412fa8f1SPawel Jakub DawidekThe
185412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
186412fa8f1SPawel Jakub Dawidekfunction will fail if:
187412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
188412fa8f1SPawel Jakub Dawidek.It Bq Er EEXIST
1896b84cd58SRuslan ErmilovSome process already holds the lock on the given pidfile, meaning that a
190412fa8f1SPawel Jakub Dawidekdaemon is already running.
191e8cc80c0SPawel Jakub DawidekIf
192e8cc80c0SPawel Jakub Dawidek.Fa pidptr
193e8cc80c0SPawel Jakub Dawidekargument is not
194e8cc80c0SPawel Jakub Dawidek.Dv NULL
195e8cc80c0SPawel Jakub Dawidekthe function will use it to store a PID of an already running daemon or
196e8cc80c0SPawel Jakub Dawidek.Li -1
197e8cc80c0SPawel Jakub Dawidekin case daemon did not write its PID yet.
198412fa8f1SPawel Jakub Dawidek.It Bq Er ENAMETOOLONG
199412fa8f1SPawel Jakub DawidekSpecified pidfile's name is too long.
200412fa8f1SPawel Jakub Dawidek.It Bq Er EINVAL
201412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, but PID read
202412fa8f1SPawel Jakub Dawidekfrom there is invalid.
203412fa8f1SPawel Jakub Dawidek.El
204412fa8f1SPawel Jakub Dawidek.Pp
205412fa8f1SPawel Jakub DawidekThe
206412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
207412fa8f1SPawel Jakub Dawidekfunction may also fail and set
208412fa8f1SPawel Jakub Dawidek.Va errno
209412fa8f1SPawel Jakub Dawidekfor any errors specified for the
210412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
211412fa8f1SPawel Jakub Dawidek.Xr open 2 ,
2126b84cd58SRuslan Ermilovand
213412fa8f1SPawel Jakub Dawidek.Xr read 2
2146b84cd58SRuslan Ermilovcalls.
215412fa8f1SPawel Jakub Dawidek.Pp
216412fa8f1SPawel Jakub DawidekThe
217412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
218412fa8f1SPawel Jakub Dawidekfunction will fail if:
219412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
220412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
2216b84cd58SRuslan ErmilovImproper function use.
222412fa8f1SPawel Jakub DawidekProbably called before
223412fa8f1SPawel Jakub Dawidek.Fn pidfile_open .
224412fa8f1SPawel Jakub Dawidek.El
225412fa8f1SPawel Jakub Dawidek.Pp
226412fa8f1SPawel Jakub DawidekThe
227412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
228412fa8f1SPawel Jakub Dawidekfunction may also fail and set
229412fa8f1SPawel Jakub Dawidek.Va errno
230412fa8f1SPawel Jakub Dawidekfor any errors specified for the
231412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
232412fa8f1SPawel Jakub Dawidek.Xr ftruncate 2 ,
2336b84cd58SRuslan Ermilovand
234412fa8f1SPawel Jakub Dawidek.Xr write 2
2356b84cd58SRuslan Ermilovcalls.
236412fa8f1SPawel Jakub Dawidek.Pp
237412fa8f1SPawel Jakub DawidekThe
238412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
239412fa8f1SPawel Jakub Dawidekfunction may fail and set
240412fa8f1SPawel Jakub Dawidek.Va errno
241412fa8f1SPawel Jakub Dawidekfor any errors specified for the
2426b84cd58SRuslan Ermilov.Xr close 2
2436b84cd58SRuslan Ermilovand
244412fa8f1SPawel Jakub Dawidek.Xr fstat 2
2456b84cd58SRuslan Ermilovcalls.
246412fa8f1SPawel Jakub Dawidek.Pp
247412fa8f1SPawel Jakub DawidekThe
248412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
249412fa8f1SPawel Jakub Dawidekfunction will fail if:
250412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
251412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
2526b84cd58SRuslan ErmilovImproper function use.
253412fa8f1SPawel Jakub DawidekProbably called not from the process which made
254412fa8f1SPawel Jakub Dawidek.Fn pidfile_write .
255412fa8f1SPawel Jakub Dawidek.El
256412fa8f1SPawel Jakub Dawidek.Pp
257412fa8f1SPawel Jakub DawidekThe
258412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
259412fa8f1SPawel Jakub Dawidekfunction may also fail and set
260412fa8f1SPawel Jakub Dawidek.Va errno
261412fa8f1SPawel Jakub Dawidekfor any errors specified for the
262412fa8f1SPawel Jakub Dawidek.Xr close 2 ,
263412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
264412fa8f1SPawel Jakub Dawidek.Xr write 2 ,
2656b84cd58SRuslan Ermilovand
266412fa8f1SPawel Jakub Dawidek.Xr unlink 2
267cb7cd07aSDag-Erling Smørgravsystem calls and the
268cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
269cb7cd07aSDag-Erling Smørgravlibrary function.
270f295618dSGuy Helmer.Pp
271f295618dSGuy HelmerThe
272f295618dSGuy Helmer.Fn pidfile_fileno
273f295618dSGuy Helmerfunction will fail if:
274f295618dSGuy Helmer.Bl -tag -width Er
275f295618dSGuy Helmer.It Bq Er EDOOFUS
276f295618dSGuy HelmerImproper function use.
277f295618dSGuy HelmerProbably called not from the process which used
278f295618dSGuy Helmer.Fn pidfile_open .
279f295618dSGuy Helmer.El
280412fa8f1SPawel Jakub Dawidek.Sh SEE ALSO
281412fa8f1SPawel Jakub Dawidek.Xr open 2 ,
282cb7cd07aSDag-Erling Smørgrav.Xr daemon 3 ,
283cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
284412fa8f1SPawel Jakub Dawidek.Sh AUTHORS
285412fa8f1SPawel Jakub Dawidek.An -nosplit
286412fa8f1SPawel Jakub DawidekThe
2876b84cd58SRuslan Ermilov.Nm pidfile
288412fa8f1SPawel Jakub Dawidekfunctionality is based on ideas from
289412fa8f1SPawel Jakub Dawidek.An John-Mark Gurney Aq jmg@FreeBSD.org .
290412fa8f1SPawel Jakub Dawidek.Pp
291412fa8f1SPawel Jakub DawidekThe code and manual page was written by
292412fa8f1SPawel Jakub Dawidek.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
293