2 Create and remove pidfile
4 Copyright (C) Amitay Isaacs 2016
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
25 #include "common/pidfile.h"
27 struct pidfile_context
{
33 static int pidfile_context_destructor(struct pidfile_context
*pid_ctx
);
35 int pidfile_create(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
36 struct pidfile_context
**result
)
38 struct pidfile_context
*pid_ctx
;
45 pid_ctx
= talloc_zero(mem_ctx
, struct pidfile_context
);
46 if (pid_ctx
== NULL
) {
50 pid_ctx
->pidfile
= talloc_strdup(pid_ctx
, pidfile
);
51 if (pid_ctx
->pidfile
== NULL
) {
56 pid_ctx
->pid
= getpid();
58 fd
= open(pidfile
, O_CREAT
|O_WRONLY
|O_NONBLOCK
, 0644);
66 lck
= (struct flock
) {
72 ret
= fcntl(fd
, F_SETLK
, &lck
);
73 } while ((ret
== -1) && (errno
== EINTR
));
81 ret
= ftruncate(fd
, 0);
82 } while ((ret
== -1) && (errno
== EINTR
));
89 len
= snprintf(tmp
, sizeof(tmp
), "%u\n", pid_ctx
->pid
);
96 nwritten
= write(fd
, tmp
, len
);
97 } while ((nwritten
== -1) && (errno
== EINTR
));
99 if ((nwritten
== -1) || (nwritten
!= len
)) {
104 talloc_set_destructor(pid_ctx
, pidfile_context_destructor
);
114 talloc_free(pid_ctx
);
118 static int pidfile_context_destructor(struct pidfile_context
*pid_ctx
)
123 if (getpid() != pid_ctx
->pid
) {
127 lck
= (struct flock
) {
129 .l_whence
= SEEK_SET
,
132 (void) unlink(pid_ctx
->pidfile
);
135 ret
= fcntl(pid_ctx
->fd
, F_SETLK
, &lck
);
136 } while ((ret
== -1) && (errno
== EINTR
));
139 ret
= close(pid_ctx
->fd
);
140 } while ((ret
== -1) && (errno
== EINTR
));