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