xref: /freebsd/lib/libutil/pidfile.3 (revision cb7cd07a0756ad4913c256d831461658e02e1249)
1412fa8f1SPawel Jakub Dawidek.\" Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
2412fa8f1SPawel Jakub Dawidek.\" All rights reserved.
3412fa8f1SPawel Jakub Dawidek.\"
4412fa8f1SPawel Jakub Dawidek.\" Redistribution and use in source and binary forms, with or without
5412fa8f1SPawel Jakub Dawidek.\" modification, are permitted provided that the following conditions
6412fa8f1SPawel Jakub Dawidek.\" are met:
7412fa8f1SPawel Jakub Dawidek.\" 1. Redistributions of source code must retain the above copyright
8412fa8f1SPawel Jakub Dawidek.\"    notice, this list of conditions and the following disclaimer.
9412fa8f1SPawel Jakub Dawidek.\" 2. Redistributions in binary form must reproduce the above copyright
10412fa8f1SPawel Jakub Dawidek.\"    notice, this list of conditions and the following disclaimer in the
11412fa8f1SPawel Jakub Dawidek.\"    documentation and/or other materials provided with the distribution.
12412fa8f1SPawel Jakub Dawidek.\"
13412fa8f1SPawel Jakub Dawidek.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
14412fa8f1SPawel Jakub Dawidek.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15412fa8f1SPawel Jakub Dawidek.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16412fa8f1SPawel Jakub Dawidek.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
17412fa8f1SPawel Jakub Dawidek.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18412fa8f1SPawel Jakub Dawidek.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19412fa8f1SPawel Jakub Dawidek.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20412fa8f1SPawel Jakub Dawidek.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21412fa8f1SPawel Jakub Dawidek.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22412fa8f1SPawel Jakub Dawidek.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23412fa8f1SPawel Jakub Dawidek.\" SUCH DAMAGE.
24412fa8f1SPawel Jakub Dawidek.\"
25412fa8f1SPawel Jakub Dawidek.\" $FreeBSD$
26412fa8f1SPawel Jakub Dawidek.\"
27cb7cd07aSDag-Erling Smørgrav.Dd October 20, 2008
28412fa8f1SPawel Jakub Dawidek.Dt PIDFILE 3
29412fa8f1SPawel Jakub Dawidek.Os
30412fa8f1SPawel Jakub Dawidek.Sh NAME
31412fa8f1SPawel Jakub Dawidek.Nm pidfile_open ,
32412fa8f1SPawel Jakub Dawidek.Nm pidfile_write ,
33412fa8f1SPawel Jakub Dawidek.Nm pidfile_close ,
34412fa8f1SPawel Jakub Dawidek.Nm pidfile_remove
356b84cd58SRuslan Ermilov.Nd "library for PID files handling"
36412fa8f1SPawel Jakub Dawidek.Sh LIBRARY
37412fa8f1SPawel Jakub Dawidek.Lb libutil
38412fa8f1SPawel Jakub Dawidek.Sh SYNOPSIS
39412fa8f1SPawel Jakub Dawidek.In sys/param.h
40412fa8f1SPawel Jakub Dawidek.In libutil.h
416b84cd58SRuslan Ermilov.Ft "struct pidfh *"
42412fa8f1SPawel Jakub Dawidek.Fn pidfile_open "const char *path" "mode_t mode" "pid_t *pidptr"
43412fa8f1SPawel Jakub Dawidek.Ft int
44412fa8f1SPawel Jakub Dawidek.Fn pidfile_write "struct pidfh *pfh"
45412fa8f1SPawel Jakub Dawidek.Ft int
46412fa8f1SPawel Jakub Dawidek.Fn pidfile_close "struct pidfh *pfh"
47412fa8f1SPawel Jakub Dawidek.Ft int
48412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove "struct pidfh *pfh"
49412fa8f1SPawel Jakub Dawidek.Sh DESCRIPTION
50412fa8f1SPawel Jakub DawidekThe
516b84cd58SRuslan Ermilov.Nm pidfile
526b84cd58SRuslan Ermilovfamily of functions allows daemons to handle PID files.
53412fa8f1SPawel Jakub DawidekIt uses
54cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
556b84cd58SRuslan Ermilovto lock a pidfile and detect already running daemons.
56412fa8f1SPawel Jakub Dawidek.Pp
57412fa8f1SPawel Jakub DawidekThe
58412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
596b84cd58SRuslan Ermilovfunction opens (or creates) a file specified by the
60412fa8f1SPawel Jakub Dawidek.Fa path
61cb7cd07aSDag-Erling Smørgravargument and locks it.
626b84cd58SRuslan ErmilovIf a file can not be locked, a PID of an already running daemon is returned in
636b84cd58SRuslan Ermilovthe
64412fa8f1SPawel Jakub Dawidek.Fa pidptr
656b84cd58SRuslan Ermilovargument (if it is not
666b84cd58SRuslan Ermilov.Dv NULL ) .
676b84cd58SRuslan ErmilovThe function does not write process' PID into the file here, so it can be
686b84cd58SRuslan Ermilovused before
696b84cd58SRuslan Ermilov.Fn fork Ns ing
706b84cd58SRuslan Ermilovand exit with a proper error message when needed.
716b84cd58SRuslan ErmilovIf the
72412fa8f1SPawel Jakub Dawidek.Fa path
736b84cd58SRuslan Ermilovargument is
746b84cd58SRuslan Ermilov.Dv NULL ,
756b84cd58SRuslan Ermilov.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid
76412fa8f1SPawel Jakub Dawidekfile will be used.
77412fa8f1SPawel Jakub Dawidek.Pp
78412fa8f1SPawel Jakub DawidekThe
79412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
806b84cd58SRuslan Ermilovfunction writes process' PID into a previously opened file.
81412fa8f1SPawel Jakub Dawidek.Pp
82412fa8f1SPawel Jakub DawidekThe
83412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
846b84cd58SRuslan Ermilovfunction closes a pidfile.
856b84cd58SRuslan ErmilovIt should be used after daemon
866b84cd58SRuslan Ermilov.Fn fork Ns s
876b84cd58SRuslan Ermilovto start a child process.
88412fa8f1SPawel Jakub Dawidek.Pp
89412fa8f1SPawel Jakub DawidekThe
90412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
916b84cd58SRuslan Ermilovfunction closes and removes a pidfile.
92412fa8f1SPawel Jakub Dawidek.Sh RETURN VALUES
93412fa8f1SPawel Jakub DawidekThe
94412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
956b84cd58SRuslan Ermilovfunction returns a valid pointer to a
966b84cd58SRuslan Ermilov.Vt pidfh
976b84cd58SRuslan Ermilovstructure on success, or
98412fa8f1SPawel Jakub Dawidek.Dv NULL
99412fa8f1SPawel Jakub Dawidekif an error occurs.
1006b84cd58SRuslan ErmilovIf an error occurs,
101412fa8f1SPawel Jakub Dawidek.Va errno
102412fa8f1SPawel Jakub Dawidekwill be set.
103412fa8f1SPawel Jakub Dawidek.Rv -std pidfile_write pidfile_close pidfile_remove
104412fa8f1SPawel Jakub Dawidek.Sh EXAMPLES
1056b84cd58SRuslan ErmilovThe following example shows in which order these functions should be used.
106560c4fc1SPawel Jakub DawidekNote that it is safe to pass
107560c4fc1SPawel Jakub Dawidek.Dv NULL
108560c4fc1SPawel Jakub Dawidekto
109560c4fc1SPawel Jakub Dawidek.Fn pidfile_write ,
110560c4fc1SPawel Jakub Dawidek.Fn pidfile_remove
111560c4fc1SPawel Jakub Dawidekand
112560c4fc1SPawel Jakub Dawidek.Fn pidfile_close
113560c4fc1SPawel Jakub Dawidekfunctions.
114412fa8f1SPawel Jakub Dawidek.Bd -literal
115412fa8f1SPawel Jakub Dawidekstruct pidfh *pfh;
116412fa8f1SPawel Jakub Dawidekpid_t otherpid, childpid;
117412fa8f1SPawel Jakub Dawidek
1188b28aef2SPawel Jakub Dawidekpfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
119412fa8f1SPawel Jakub Dawidekif (pfh == NULL) {
120560c4fc1SPawel Jakub Dawidek	if (errno == EEXIST) {
121ef608a60SGiorgos Keramidas		errx(EXIT_FAILURE, "Daemon already running, pid: %jd.",
122ef608a60SGiorgos Keramidas		    (intmax_t)otherpid);
123560c4fc1SPawel Jakub Dawidek	}
124412fa8f1SPawel Jakub Dawidek	/* If we cannot create pidfile from other reasons, only warn. */
125412fa8f1SPawel Jakub Dawidek	warn("Cannot open or create pidfile");
126412fa8f1SPawel Jakub Dawidek}
127412fa8f1SPawel Jakub Dawidek
128412fa8f1SPawel Jakub Dawidekif (daemon(0, 0) == -1) {
129412fa8f1SPawel Jakub Dawidek	warn("Cannot daemonize");
130412fa8f1SPawel Jakub Dawidek	pidfile_remove(pfh);
131412fa8f1SPawel Jakub Dawidek	exit(EXIT_FAILURE);
132412fa8f1SPawel Jakub Dawidek}
133412fa8f1SPawel Jakub Dawidek
134412fa8f1SPawel Jakub Dawidekpidfile_write(pfh);
135412fa8f1SPawel Jakub Dawidek
136412fa8f1SPawel Jakub Dawidekfor (;;) {
137412fa8f1SPawel Jakub Dawidek	/* Do work. */
138412fa8f1SPawel Jakub Dawidek	childpid = fork();
139412fa8f1SPawel Jakub Dawidek	switch (childpid) {
140412fa8f1SPawel Jakub Dawidek	case -1:
141412fa8f1SPawel Jakub Dawidek		syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
142412fa8f1SPawel Jakub Dawidek		break;
143412fa8f1SPawel Jakub Dawidek	case 0:
144412fa8f1SPawel Jakub Dawidek		pidfile_close(pfh);
145412fa8f1SPawel Jakub Dawidek		/* Do child work. */
146412fa8f1SPawel Jakub Dawidek		break;
147412fa8f1SPawel Jakub Dawidek	default:
148ef608a60SGiorgos Keramidas		syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
149412fa8f1SPawel Jakub Dawidek		break;
150412fa8f1SPawel Jakub Dawidek	}
151412fa8f1SPawel Jakub Dawidek}
152412fa8f1SPawel Jakub Dawidek
153412fa8f1SPawel Jakub Dawidekpidfile_remove(pfh);
154412fa8f1SPawel Jakub Dawidekexit(EXIT_SUCCESS);
155412fa8f1SPawel Jakub Dawidek.Ed
156412fa8f1SPawel Jakub Dawidek.Sh ERRORS
157412fa8f1SPawel Jakub DawidekThe
158412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
159412fa8f1SPawel Jakub Dawidekfunction will fail if:
160412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
161412fa8f1SPawel Jakub Dawidek.It Bq Er EEXIST
1626b84cd58SRuslan ErmilovSome process already holds the lock on the given pidfile, meaning that a
163412fa8f1SPawel Jakub Dawidekdaemon is already running.
164412fa8f1SPawel Jakub Dawidek.It Bq Er ENAMETOOLONG
165412fa8f1SPawel Jakub DawidekSpecified pidfile's name is too long.
166412fa8f1SPawel Jakub Dawidek.It Bq Er EINVAL
167412fa8f1SPawel Jakub DawidekSome process already holds the lock on the given pidfile, but PID read
168412fa8f1SPawel Jakub Dawidekfrom there is invalid.
169fefc6803SKonstantin Belousov.It Bq Er EAGAIN
170fefc6803SKonstantin BelousovSome process already holds the lock on the given pidfile, but the file
1713dca0939SSimon L. B. Nielsenis truncated.
1723dca0939SSimon L. B. NielsenMost likely, the existing daemon is writing new PID into
173fefc6803SKonstantin Belousovthe file.
174412fa8f1SPawel Jakub Dawidek.El
175412fa8f1SPawel Jakub Dawidek.Pp
176412fa8f1SPawel Jakub DawidekThe
177412fa8f1SPawel Jakub Dawidek.Fn pidfile_open
178412fa8f1SPawel Jakub Dawidekfunction may also fail and set
179412fa8f1SPawel Jakub Dawidek.Va errno
180412fa8f1SPawel Jakub Dawidekfor any errors specified for the
181412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
182412fa8f1SPawel Jakub Dawidek.Xr open 2 ,
1836b84cd58SRuslan Ermilovand
184412fa8f1SPawel Jakub Dawidek.Xr read 2
1856b84cd58SRuslan Ermilovcalls.
186412fa8f1SPawel Jakub Dawidek.Pp
187412fa8f1SPawel Jakub DawidekThe
188412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
189412fa8f1SPawel Jakub Dawidekfunction will fail if:
190412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
191412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
1926b84cd58SRuslan ErmilovImproper function use.
193412fa8f1SPawel Jakub DawidekProbably called before
194412fa8f1SPawel Jakub Dawidek.Fn pidfile_open .
195412fa8f1SPawel Jakub Dawidek.El
196412fa8f1SPawel Jakub Dawidek.Pp
197412fa8f1SPawel Jakub DawidekThe
198412fa8f1SPawel Jakub Dawidek.Fn pidfile_write
199412fa8f1SPawel Jakub Dawidekfunction may also fail and set
200412fa8f1SPawel Jakub Dawidek.Va errno
201412fa8f1SPawel Jakub Dawidekfor any errors specified for the
202412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
203412fa8f1SPawel Jakub Dawidek.Xr ftruncate 2 ,
2046b84cd58SRuslan Ermilovand
205412fa8f1SPawel Jakub Dawidek.Xr write 2
2066b84cd58SRuslan Ermilovcalls.
207412fa8f1SPawel Jakub Dawidek.Pp
208412fa8f1SPawel Jakub DawidekThe
209412fa8f1SPawel Jakub Dawidek.Fn pidfile_close
210412fa8f1SPawel Jakub Dawidekfunction may fail and set
211412fa8f1SPawel Jakub Dawidek.Va errno
212412fa8f1SPawel Jakub Dawidekfor any errors specified for the
2136b84cd58SRuslan Ermilov.Xr close 2
2146b84cd58SRuslan Ermilovand
215412fa8f1SPawel Jakub Dawidek.Xr fstat 2
2166b84cd58SRuslan Ermilovcalls.
217412fa8f1SPawel Jakub Dawidek.Pp
218412fa8f1SPawel Jakub DawidekThe
219412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
220412fa8f1SPawel Jakub Dawidekfunction will fail if:
221412fa8f1SPawel Jakub Dawidek.Bl -tag -width Er
222412fa8f1SPawel Jakub Dawidek.It Bq Er EDOOFUS
2236b84cd58SRuslan ErmilovImproper function use.
224412fa8f1SPawel Jakub DawidekProbably called not from the process which made
225412fa8f1SPawel Jakub Dawidek.Fn pidfile_write .
226412fa8f1SPawel Jakub Dawidek.El
227412fa8f1SPawel Jakub Dawidek.Pp
228412fa8f1SPawel Jakub DawidekThe
229412fa8f1SPawel Jakub Dawidek.Fn pidfile_remove
230412fa8f1SPawel Jakub Dawidekfunction may also fail and set
231412fa8f1SPawel Jakub Dawidek.Va errno
232412fa8f1SPawel Jakub Dawidekfor any errors specified for the
233412fa8f1SPawel Jakub Dawidek.Xr close 2 ,
234412fa8f1SPawel Jakub Dawidek.Xr fstat 2 ,
235412fa8f1SPawel Jakub Dawidek.Xr write 2 ,
2366b84cd58SRuslan Ermilovand
237412fa8f1SPawel Jakub Dawidek.Xr unlink 2
238cb7cd07aSDag-Erling Smørgravsystem calls and the
239cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
240cb7cd07aSDag-Erling Smørgravlibrary function.
241412fa8f1SPawel Jakub Dawidek.Sh SEE ALSO
242412fa8f1SPawel Jakub Dawidek.Xr open 2 ,
243cb7cd07aSDag-Erling Smørgrav.Xr daemon 3 ,
244cb7cd07aSDag-Erling Smørgrav.Xr flopen 3
245412fa8f1SPawel Jakub Dawidek.Sh AUTHORS
246412fa8f1SPawel Jakub Dawidek.An -nosplit
247412fa8f1SPawel Jakub DawidekThe
2486b84cd58SRuslan Ermilov.Nm pidfile
249412fa8f1SPawel Jakub Dawidekfunctionality is based on ideas from
250412fa8f1SPawel Jakub Dawidek.An John-Mark Gurney Aq jmg@FreeBSD.org .
251412fa8f1SPawel Jakub Dawidek.Pp
252412fa8f1SPawel Jakub DawidekThe code and manual page was written by
253412fa8f1SPawel Jakub Dawidek.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
254