/src/suricata7/src/util-pidfile.c
Line | Count | Source |
1 | | /* Copyright (C) 2007-2010 Open Information Security Foundation |
2 | | * |
3 | | * You can copy, redistribute or modify this Program under the terms of |
4 | | * the GNU General Public License version 2 as published by the Free |
5 | | * Software Foundation. |
6 | | * |
7 | | * This program is distributed in the hope that it will be useful, |
8 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | | * GNU General Public License for more details. |
11 | | * |
12 | | * You should have received a copy of the GNU General Public License |
13 | | * version 2 along with this program; if not, write to the Free Software |
14 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
15 | | * 02110-1301, USA. |
16 | | */ |
17 | | |
18 | | /** |
19 | | * \file |
20 | | * |
21 | | * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com> |
22 | | * \author Victor Julien <victor@inliniac.net> |
23 | | * |
24 | | * Utility code for dealing with a pidfile. |
25 | | * Adaptation of Steve Grubbs patch to our coding guidelines |
26 | | * (thanks for the patch Steve ;) |
27 | | */ |
28 | | |
29 | | #include "suricata-common.h" |
30 | | #include "util-pidfile.h" |
31 | | #include "util-debug.h" |
32 | | |
33 | | /** |
34 | | * \brief Write a pid file (used at the startup) |
35 | | * This commonly needed by the init scripts |
36 | | * |
37 | | * \param pointer to the name of the pid file to write (optarg) |
38 | | * |
39 | | * \retval 0 if succes |
40 | | * \retval -1 on failure |
41 | | */ |
42 | | int SCPidfileCreate(const char *pidfile) |
43 | 0 | { |
44 | 0 | SCEnter(); |
45 | |
|
46 | 0 | int pidfd = 0; |
47 | 0 | char val[16]; |
48 | |
|
49 | 0 | size_t len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid()); |
50 | 0 | if (len <= 0) { |
51 | 0 | SCLogError("Pid error (%s)", strerror(errno)); |
52 | 0 | SCReturnInt(-1); |
53 | 0 | } |
54 | | |
55 | 0 | pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644); |
56 | 0 | if (pidfd < 0) { |
57 | 0 | SCLogError("unable to set pidfile '%s': %s", pidfile, strerror(errno)); |
58 | 0 | SCReturnInt(-1); |
59 | 0 | } |
60 | | |
61 | 0 | ssize_t r = write(pidfd, val, (unsigned int)len); |
62 | 0 | if (r == -1) { |
63 | 0 | SCLogError("unable to write pidfile: %s", strerror(errno)); |
64 | 0 | close(pidfd); |
65 | 0 | SCReturnInt(-1); |
66 | 0 | } else if ((size_t)r != len) { |
67 | 0 | SCLogError("unable to write pidfile: wrote" |
68 | 0 | " %" PRIdMAX " of %" PRIuMAX " bytes.", |
69 | 0 | (intmax_t)r, (uintmax_t)len); |
70 | 0 | close(pidfd); |
71 | 0 | SCReturnInt(-1); |
72 | 0 | } |
73 | | |
74 | 0 | close(pidfd); |
75 | 0 | SCReturnInt(0); |
76 | 0 | } |
77 | | |
78 | | /** |
79 | | * \brief Remove the pid file (used at the startup) |
80 | | * |
81 | | * \param pointer to the name of the pid file to write (optarg) |
82 | | */ |
83 | | void SCPidfileRemove(const char *pid_filename) |
84 | 0 | { |
85 | 0 | if (pid_filename != NULL) { |
86 | | /* we ignore the result, the user may have removed the file already. */ |
87 | 0 | (void)unlink(pid_filename); |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | | /** |
92 | | * \brief Check the Suricata pid file (used at the startup) |
93 | | * |
94 | | * This commonly needed by the init scripts. |
95 | | * |
96 | | * This function will fail if the PID file exists, but tries to log a |
97 | | * meaningful message if appears Suricata is running, or if the PID |
98 | | * file appears to be stale. |
99 | | * |
100 | | * \param pointer to the name of the pid file to write (optarg) |
101 | | * |
102 | | * \retval 0 if succes |
103 | | * \retval -1 on failure |
104 | | */ |
105 | | int SCPidfileTestRunning(const char *pid_filename) |
106 | 0 | { |
107 | | /* Check if the existing process is still alive. */ |
108 | 0 | FILE *pf; |
109 | |
|
110 | 0 | pf = fopen(pid_filename, "r"); |
111 | 0 | if (pf == NULL) { |
112 | 0 | if (access(pid_filename, F_OK) == 0) { |
113 | 0 | SCLogError("pid file '%s' exists and can not be read. Aborting!", pid_filename); |
114 | 0 | return -1; |
115 | 0 | } else { |
116 | 0 | return 0; |
117 | 0 | } |
118 | 0 | } |
119 | | |
120 | 0 | #ifndef OS_WIN32 |
121 | 0 | pid_t pidv; |
122 | 0 | if (fscanf(pf, "%d", &pidv) == 1 && kill(pidv, 0) == 0) { |
123 | 0 | SCLogError("pid file '%s' exists and Suricata appears to be running. " |
124 | 0 | "Aborting!", |
125 | 0 | pid_filename); |
126 | 0 | } else |
127 | 0 | #endif |
128 | 0 | { |
129 | 0 | SCLogError("pid file '%s' exists but appears stale. " |
130 | 0 | "Make sure Suricata is not running and then remove %s. " |
131 | 0 | "Aborting!", |
132 | 0 | pid_filename, pid_filename); |
133 | 0 | } |
134 | |
|
135 | 0 | fclose(pf); |
136 | 0 | return -1; |
137 | 0 | } |