xref: /freebsd/lib/libutil/pidfile.3 (revision 5bb3134a8c21cb87b30e135ef168483f0333dabb)
1.\" Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd May 10, 2020
28.Dt PIDFILE 3
29.Os
30.Sh NAME
31.Nm pidfile_open ,
32.Nm pidfile_write ,
33.Nm pidfile_close ,
34.Nm pidfile_remove
35.Nd "library for PID files handling"
36.Sh LIBRARY
37.Lb libutil
38.Sh SYNOPSIS
39.In libutil.h
40.Ft "struct pidfh *"
41.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr"
42.Ft int
43.Fn pidfile_write "struct pidfh *pfh"
44.Ft int
45.Fn pidfile_close "struct pidfh *pfh"
46.Ft int
47.Fn pidfile_remove "struct pidfh *pfh"
48.Ft int
49.Fn pidfile_fileno "struct pidfh *pfh"
50.Sh DESCRIPTION
51The
52.Nm pidfile
53family of functions allows daemons to handle PID files.
54It uses
55.Xr flopen 3
56to lock a pidfile and detect already running daemons.
57.Pp
58The
59.Fn pidfile_open
60function opens (or creates) a file specified by the
61.Fa path
62argument and locks it.
63If
64.Fa pidptr
65argument is not
66.Dv NULL
67and file can not be locked, the function will use it to store a PID of an
68already running daemon or
69.Li -1
70in case daemon did not write its PID yet.
71The function does not write process' PID into the file here, so it can be
72used before
73.Fn fork Ns ing
74and exit with a proper error message when needed.
75If the
76.Fa path
77argument is
78.Dv NULL ,
79.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid
80file will be used.
81The
82.Fn pidfile_open
83function sets the O_CLOEXEC close-on-exec flag when opening the pidfile.
84.Pp
85The
86.Fn pidfile_write
87function writes process' PID into a previously opened file.
88The file is truncated before write, so calling the
89.Fn pidfile_write
90function multiple times is supported.
91.Pp
92The
93.Fn pidfile_close
94function closes a pidfile.
95It should be used after daemon
96.Fn fork Ns s
97to start a child process.
98.Pp
99The
100.Fn pidfile_remove
101function closes and removes a pidfile.
102.Pp
103The
104.Fn pidfile_fileno
105function returns the file descriptor for the open pidfile.
106.Sh RETURN VALUES
107The
108.Fn pidfile_open
109function returns a valid pointer to a
110.Vt pidfh
111structure on success, or
112.Dv NULL
113if an error occurs.
114If an error occurs,
115.Va errno
116will be set.
117.Pp
118.Rv -std pidfile_write pidfile_close pidfile_remove
119.Pp
120The
121.Fn pidfile_fileno
122function returns the low-level file descriptor.
123It returns
124.Li -1
125and sets
126.Va errno
127if a NULL
128.Vt pidfh
129is specified, or if the pidfile is no longer open.
130.Sh EXAMPLES
131The following example shows in which order these functions should be used.
132Note that it is safe to pass
133.Dv NULL
134to
135.Fn pidfile_write ,
136.Fn pidfile_remove ,
137.Fn pidfile_close
138and
139.Fn pidfile_fileno
140functions.
141.Bd -literal
142struct pidfh *pfh;
143pid_t otherpid, childpid;
144
145pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
146if (pfh == NULL) {
147	if (errno == EEXIST) {
148		errx(EXIT_FAILURE, "Daemon already running, pid: %jd.",
149		    (intmax_t)otherpid);
150	}
151	/* If we cannot create pidfile from other reasons, only warn. */
152	warn("Cannot open or create pidfile");
153	/*
154	 * Even though pfh is NULL we can continue, as the other pidfile_*
155	 * function can handle such situation by doing nothing except setting
156	 * errno to EDOOFUS.
157	 */
158}
159
160if (daemon(0, 0) == -1) {
161	warn("Cannot daemonize");
162	pidfile_remove(pfh);
163	exit(EXIT_FAILURE);
164}
165
166pidfile_write(pfh);
167
168for (;;) {
169	/* Do work. */
170	childpid = fork();
171	switch (childpid) {
172	case -1:
173		syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
174		break;
175	case 0:
176		pidfile_close(pfh);
177		/* Do child work. */
178		break;
179	default:
180		syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
181		break;
182	}
183}
184
185pidfile_remove(pfh);
186exit(EXIT_SUCCESS);
187.Ed
188.Sh ERRORS
189The
190.Fn pidfile_open
191function will fail if:
192.Bl -tag -width Er
193.It Bq Er EEXIST
194Some process already holds the lock on the given pidfile, meaning that a
195daemon is already running.
196If
197.Fa pidptr
198argument is not
199.Dv NULL
200the function will use it to store a PID of an already running daemon or
201.Li -1
202in case daemon did not write its PID yet.
203.It Bq Er ENAMETOOLONG
204Specified pidfile's name is too long.
205.It Bq Er EINVAL
206Some process already holds the lock on the given pidfile, but PID read
207from there is invalid.
208.El
209.Pp
210The
211.Fn pidfile_open
212function may also fail and set
213.Va errno
214for any errors specified for the
215.Xr fstat 2 ,
216.Xr open 2 ,
217and
218.Xr read 2
219calls.
220.Pp
221The
222.Fn pidfile_write
223function will fail if:
224.Bl -tag -width Er
225.It Bq Er EDOOFUS
226Improper function use.
227Probably called before
228.Fn pidfile_open .
229.El
230.Pp
231The
232.Fn pidfile_write
233function may also fail and set
234.Va errno
235for any errors specified for the
236.Xr fstat 2 ,
237.Xr ftruncate 2 ,
238and
239.Xr write 2
240calls.
241.Pp
242The
243.Fn pidfile_close
244function may fail and set
245.Va errno
246for any errors specified for the
247.Xr close 2
248and
249.Xr fstat 2
250calls.
251.Pp
252The
253.Fn pidfile_remove
254function will fail if:
255.Bl -tag -width Er
256.It Bq Er EDOOFUS
257Improper function use.
258Probably called not from the process which made
259.Fn pidfile_write .
260.El
261.Pp
262The
263.Fn pidfile_remove
264function may also fail and set
265.Va errno
266for any errors specified for the
267.Xr close 2 ,
268.Xr fstat 2 ,
269.Xr write 2 ,
270and
271.Xr unlink 2
272system calls and the
273.Xr flopen 3
274library function.
275.Pp
276The
277.Fn pidfile_fileno
278function will fail if:
279.Bl -tag -width Er
280.It Bq Er EDOOFUS
281Improper function use.
282Probably called not from the process which used
283.Fn pidfile_open .
284.El
285.Sh SEE ALSO
286.Xr open 2 ,
287.Xr daemon 3 ,
288.Xr flopen 3
289.Sh HISTORY
290The functions
291.Fn pidfile_open ,
292.Fn pidfile_write ,
293.Fn pidfile_close
294and
295.Fn pidfile_remove
296first appeared in
297.Fx 5.5 .
298.Sh AUTHORS
299.An -nosplit
300The
301.Nm pidfile
302functionality is based on ideas from
303.An John-Mark Gurney Aq Mt jmg@FreeBSD.org .
304.Pp
305The code and manual page was written by
306.An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org .
307