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