xref: /freebsd/lib/libutil/pidfile.3 (revision 822923447e454b30d310cb46903c9ddeca9f0a7a)
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 August 22, 2005
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.Sh DESCRIPTION
50The
51.Nm libpidfile
52library provides functions for daemons to handle file with PID.
53It uses
54.Xr flock 2
55to lock pidfile and detect already running daemons.
56.Pp
57The
58.Fn pidfile_open
59function opens (or creates) a file specified by
60.Fa path
61argument and locks it with
62.Xr flock 2
63syscall.
64If file can not be locked, PID of already running daemon is returned in
65.Fa pidptr
66argument (if it is not NULL).
67The function doesn't write process' PID into the file here, so it can be
68used before fork()ing and exit with proper error message when needed.
69If
70.Fa path
71argument is NULL,
72.Pa /var/run/<progname>.pid
73file will be used.
74.Pp
75The
76.Fn pidfile_write
77function write process' PID into previously opened file.
78.Pp
79The
80.Fn pidfile_close
81function closes pidfile.
82It should be used after daemon fork()s to start a child process.
83.Pp
84The
85.Fn pidfile_remove
86function closes and removes pidfile.
87.Sh RETURN VALUES
88The
89.Fn pidfile_open
90function return a valid pointer to a pidfh structure on success or
91.Dv NULL
92if an error occurs.
93If an error does occur,
94.Va errno
95will be set.
96.Rv -std pidfile_write pidfile_close pidfile_remove
97.Sh EXAMPLES
98The following example shows in which order those functions should be used.
99.Bd -literal
100struct pidfh *pfh;
101pid_t otherpid, childpid;
102
103pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
104if (pfh == NULL) {
105	if (errno == EEXIST)
106		errx(EXIT_FAILURE, "Daemon already running, pid: %d.", otherpid);
107	/* If we cannot create pidfile from other reasons, only warn. */
108	warn("Cannot open or create pidfile");
109}
110
111if (daemon(0, 0) == -1) {
112	warn("Cannot daemonize");
113	pidfile_remove(pfh);
114	exit(EXIT_FAILURE);
115}
116
117pidfile_write(pfh);
118
119for (;;) {
120	/* Do work. */
121	childpid = fork();
122	switch (childpid) {
123	case -1:
124		syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
125		break;
126	case 0:
127		pidfile_close(pfh);
128		/* Do child work. */
129		break;
130	default:
131		syslog(LOG_INFO, "Child %d started.", childpid);
132		break;
133	}
134}
135
136pidfile_remove(pfh);
137exit(EXIT_SUCCESS);
138.Ed
139.Sh ERRORS
140The
141.Fn pidfile_open
142function will fail if:
143.Bl -tag -width Er
144.It Bq Er EEXIST
145Some process already holds the lock on the given pidfile, which means,
146daemon is already running.
147.It Bq Er ENAMETOOLONG
148Specified pidfile's name is too long.
149.It Bq Er EINVAL
150Some process already holds the lock on the given pidfile, but PID read
151from there is invalid.
152.El
153.Pp
154The
155.Fn pidfile_open
156function may also fail and set
157.Va errno
158for any errors specified for the
159.Xr fstat 2 ,
160.Xr open 2 ,
161.Xr read 2
162routines.
163.Pp
164The
165.Fn pidfile_write
166function will fail if:
167.Bl -tag -width Er
168.It Bq Er EDOOFUS
169Inproper function use.
170Probably called before
171.Fn pidfile_open .
172.El
173.Pp
174The
175.Fn pidfile_write
176function may also fail and set
177.Va errno
178for any errors specified for the
179.Xr fstat 2 ,
180.Xr ftruncate 2 ,
181.Xr write 2
182routines.
183.Pp
184The
185.Fn pidfile_close
186function may fail and set
187.Va errno
188for any errors specified for the
189.Xr close 2 ,
190.Xr fstat 2
191routines.
192.Pp
193The
194.Fn pidfile_remove
195function will fail if:
196.Bl -tag -width Er
197.It Bq Er EDOOFUS
198Inproper function use.
199Probably called not from the process which made
200.Fn pidfile_write .
201.El
202.Pp
203The
204.Fn pidfile_remove
205function may also fail and set
206.Va errno
207for any errors specified for the
208.Xr close 2 ,
209.Xr flock 2 ,
210.Xr fstat 2 ,
211.Xr write 2 ,
212.Xr unlink 2
213routines.
214.Pp
215.Sh SEE ALSO
216.Xr flock 2 ,
217.Xr open 2 ,
218.Xr daemon 3
219.Sh AUTHORS
220.An -nosplit
221The
222.Xr pidfile 3
223functionality is based on ideas from
224.An John-Mark Gurney Aq jmg@FreeBSD.org .
225.Pp
226The code and manual page was written by
227.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
228