2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1998
5 Copyright (C) Amitay Isaccs 2016
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/filesys.h"
24 #include "lib/util/blocking.h"
25 #include "lib/util/debug.h"
26 #include "lib/util/samba_util.h" /* For process_exists_by_pid() */
28 #include "lib/util/pidfile.h"
32 * @brief Pid file handling
35 int pidfile_path_create(const char *path
, int *outfd
)
46 fd
= open(path
, O_CREAT
|O_WRONLY
|O_NONBLOCK
, 0644);
51 if (! set_close_on_exec(fd
)) {
56 lck
= (struct flock
) {
62 ret
= fcntl(fd
, F_SETLK
, &lck
);
63 } while ((ret
== -1) && (errno
== EINTR
));
72 * PID file is locked by us so from here on we should unlink
77 ret
= ftruncate(fd
, 0);
78 } while ((ret
== -1) && (errno
== EINTR
));
85 len
= snprintf(tmp
, sizeof(tmp
), "%u\n", pid
);
90 if (len
>= sizeof(tmp
)) {
96 nwritten
= write(fd
, tmp
, len
);
97 } while ((nwritten
== -1) && (errno
== EINTR
));
99 if ((nwritten
== -1) || (nwritten
!= len
)) {
115 void pidfile_fd_close(int fd
)
119 .l_whence
= SEEK_SET
,
124 ret
= fcntl(fd
, F_SETLK
, &lck
);
125 } while ((ret
== -1) && (errno
== EINTR
));
129 } while ((ret
== -1) && (errno
== EINTR
));
134 * return the pid in a pidfile. return 0 if the process (or pidfile)
137 pid_t
pidfile_pid(const char *piddir
, const char *name
)
139 size_t len
= strlen(piddir
) + strlen(name
) + 6;
145 snprintf(pidFile
, sizeof(pidFile
), "%s/%s.pid", piddir
, name
);
147 fd
= open(pidFile
, O_NONBLOCK
| O_RDONLY
, 0644);
155 if (read(fd
, pidstr
, sizeof(pidstr
)-1) <= 0) {
159 ret
= (pid_t
)atoi(pidstr
);
161 DEBUG(1, ("Could not parse contents of pidfile %s\n",
166 if (!process_exists_by_pid(ret
)) {
167 DEBUG(10, ("Process with PID=%d does not exist.\n", (int)ret
));
171 if (fcntl_lock(fd
,F_SETLK
,0,1,F_RDLCK
)) {
172 /* we could get the lock - it can't be a Samba process */
173 DEBUG(10, ("Process with PID=%d is not a Samba process.\n",
179 DEBUG(10, ("Process with PID=%d is running.\n", (int)ret
));
188 * create a pid file in the pid directory. open it and leave it locked
190 void pidfile_create(const char *piddir
, const char *name
)
192 size_t len
= strlen(piddir
) + strlen(name
) + 6;
198 snprintf(pidFile
, sizeof(pidFile
), "%s/%s.pid", piddir
, name
);
200 pid
= pidfile_pid(piddir
, name
);
202 DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n",
203 name
, pidFile
, (int)pid
));
207 fd
= open(pidFile
, O_NONBLOCK
| O_CREAT
| O_WRONLY
, 0644);
209 DEBUG(0,("ERROR: can't open %s: Error was %s\n", pidFile
,
214 smb_set_close_on_exec(fd
);
216 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)==false) {
217 DEBUG(0,("ERROR: %s : fcntl lock of file %s failed. Error was %s\n",
218 name
, pidFile
, strerror(errno
)));
222 memset(buf
, 0, sizeof(buf
));
223 slprintf(buf
, sizeof(buf
) - 1, "%u\n", (unsigned int) getpid());
224 if (write(fd
, buf
, strlen(buf
)) != (ssize_t
)strlen(buf
)) {
225 DEBUG(0,("ERROR: can't write to file %s: %s\n",
226 pidFile
, strerror(errno
)));
230 /* Leave pid file open & locked for the duration... */
233 void pidfile_unlink(const char *piddir
, const char *name
)
236 char *pidFile
= NULL
;
238 if (asprintf(&pidFile
, "%s/%s.pid", piddir
, name
) < 0) {
239 DEBUG(0,("ERROR: Out of memory\n"));
242 ret
= unlink(pidFile
);
244 DEBUG(0,("Failed to delete pidfile %s. Error was %s\n",
245 pidFile
, strerror(errno
)));