ctdb-tests: Strengthen some tests
[samba.git] / ctdb / common / pidfile.c
1 /*
2    Create and remove pidfile
3
4    Copyright (C) Amitay Isaacs  2016
5
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.
10
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.
15
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/>.
18 */
19
20 #include "replace.h"
21 #include "system/filesys.h"
22
23 #include <talloc.h>
24
25 #include "lib/util/blocking.h"
26 #include "lib/util/pidfile.h"
27
28 #include "common/pidfile.h"
29
30 struct pidfile_context {
31         const char *pidfile;
32         int fd;
33         pid_t pid;
34 };
35
36 static int pidfile_context_destructor(struct pidfile_context *pid_ctx);
37
38 int pidfile_context_create(TALLOC_CTX *mem_ctx, const char *pidfile,
39                            struct pidfile_context **result)
40 {
41         struct pidfile_context *pid_ctx;
42         int fd, ret = 0;
43
44         pid_ctx = talloc_zero(mem_ctx, struct pidfile_context);
45         if (pid_ctx == NULL) {
46                 return ENOMEM;
47         }
48
49         pid_ctx->pidfile = talloc_strdup(pid_ctx, pidfile);
50         if (pid_ctx->pidfile == NULL) {
51                 ret = ENOMEM;
52                 goto fail;
53         }
54
55         pid_ctx->pid = getpid();
56
57         ret = pidfile_path_create(pid_ctx->pidfile, &fd);
58         if (ret != 0) {
59                 return ret;
60         }
61
62         pid_ctx->fd = fd;
63
64         talloc_set_destructor(pid_ctx, pidfile_context_destructor);
65
66         *result = pid_ctx;
67         return 0;
68
69 fail:
70         talloc_free(pid_ctx);
71         return ret;
72 }
73
74 static int pidfile_context_destructor(struct pidfile_context *pid_ctx)
75 {
76         if (getpid() != pid_ctx->pid) {
77                 return 0;
78         }
79
80         (void) unlink(pid_ctx->pidfile);
81
82         pidfile_fd_close(pid_ctx->fd);
83
84         return 0;
85 }