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