xref: /freebsd/lib/libutil/pidfile.3 (revision 9a14aa017b21c292740c00ee098195cd46642730)
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 sys/param.h
40.In libutil.h
41.Ft "struct pidfh *"
42.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr"
43.Ft int
44.Fn pidfile_write "struct pidfh *pfh"
45.Ft int
46.Fn pidfile_close "struct pidfh *pfh"
47.Ft int
48.Fn pidfile_remove "struct pidfh *pfh"
49.Ft int
50.Fn pidfile_fileno "struct pidfh *pfh"
51.Sh DESCRIPTION
52The
53.Nm pidfile
54family of functions allows daemons to handle PID files.
55It uses
56.Xr flopen 3
57to lock a pidfile and detect already running daemons.
58.Pp
59The
60.Fn pidfile_open
61function opens (or creates) a file specified by the
62.Fa path
63argument and locks it.
64If
65.Fa pidptr
66argument is not
67.Dv NULL
68and file can not be locked, the function will use it to store a PID of an
69already running daemon or
70.Li -1
71in case daemon did not write its PID yet.
72The function does not write process' PID into the file here, so it can be
73used before
74.Fn fork Ns ing
75and exit with a proper error message when needed.
76If the
77.Fa path
78argument is
79.Dv NULL ,
80.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid
81file will be used.
82The
83.Fn pidfile_open
84function sets the O_CLOEXEC close-on-exec flag when opening the pidfile.
85.Pp
86The
87.Fn pidfile_write
88function writes process' PID into a previously opened file.
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
153if (daemon(0, 0) == -1) {
154	warn("Cannot daemonize");
155	pidfile_remove(pfh);
156	exit(EXIT_FAILURE);
157}
158
159pidfile_write(pfh);
160
161for (;;) {
162	/* Do work. */
163	childpid = fork();
164	switch (childpid) {
165	case -1:
166		syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
167		break;
168	case 0:
169		pidfile_close(pfh);
170		/* Do child work. */
171		break;
172	default:
173		syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
174		break;
175	}
176}
177
178pidfile_remove(pfh);
179exit(EXIT_SUCCESS);
180.Ed
181.Sh ERRORS
182The
183.Fn pidfile_open
184function will fail if:
185.Bl -tag -width Er
186.It Bq Er EEXIST
187Some process already holds the lock on the given pidfile, meaning that a
188daemon is already running.
189If
190.Fa pidptr
191argument is not
192.Dv NULL
193the function will use it to store a PID of an already running daemon or
194.Li -1
195in case daemon did not write its PID yet.
196.It Bq Er ENAMETOOLONG
197Specified pidfile's name is too long.
198.It Bq Er EINVAL
199Some process already holds the lock on the given pidfile, but PID read
200from there is invalid.
201.El
202.Pp
203The
204.Fn pidfile_open
205function may also fail and set
206.Va errno
207for any errors specified for the
208.Xr fstat 2 ,
209.Xr open 2 ,
210and
211.Xr read 2
212calls.
213.Pp
214The
215.Fn pidfile_write
216function will fail if:
217.Bl -tag -width Er
218.It Bq Er EDOOFUS
219Improper function use.
220Probably called before
221.Fn pidfile_open .
222.El
223.Pp
224The
225.Fn pidfile_write
226function may also fail and set
227.Va errno
228for any errors specified for the
229.Xr fstat 2 ,
230.Xr ftruncate 2 ,
231and
232.Xr write 2
233calls.
234.Pp
235The
236.Fn pidfile_close
237function may fail and set
238.Va errno
239for any errors specified for the
240.Xr close 2
241and
242.Xr fstat 2
243calls.
244.Pp
245The
246.Fn pidfile_remove
247function will fail if:
248.Bl -tag -width Er
249.It Bq Er EDOOFUS
250Improper function use.
251Probably called not from the process which made
252.Fn pidfile_write .
253.El
254.Pp
255The
256.Fn pidfile_remove
257function may also fail and set
258.Va errno
259for any errors specified for the
260.Xr close 2 ,
261.Xr fstat 2 ,
262.Xr write 2 ,
263and
264.Xr unlink 2
265system calls and the
266.Xr flopen 3
267library function.
268.Pp
269The
270.Fn pidfile_fileno
271function will fail if:
272.Bl -tag -width Er
273.It Bq Er EDOOFUS
274Improper function use.
275Probably called not from the process which used
276.Fn pidfile_open .
277.El
278.Sh SEE ALSO
279.Xr open 2 ,
280.Xr daemon 3 ,
281.Xr flopen 3
282.Sh AUTHORS
283.An -nosplit
284The
285.Nm pidfile
286functionality is based on ideas from
287.An John-Mark Gurney Aq jmg@FreeBSD.org .
288.Pp
289The code and manual page was written by
290.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
291