suricata
util-pidfile.c
Go to the documentation of this file.
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 */
42int SCPidfileCreate(const char *pidfile)
43{
44 SCEnter();
45
46 int pidfd = 0;
47 char val[16];
48
49 size_t len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid());
50 if (len <= 0) {
51 SCLogError("Pid error (%s)", strerror(errno));
52 SCReturnInt(-1);
53 }
54
55 pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
56 if (pidfd < 0) {
57 SCLogError("unable to set pidfile '%s': %s", pidfile, strerror(errno));
58 SCReturnInt(-1);
59 }
60
61 ssize_t r = write(pidfd, val, (unsigned int)len);
62 if (r == -1) {
63 SCLogError("unable to write pidfile: %s", strerror(errno));
64 close(pidfd);
65 SCReturnInt(-1);
66 } else if ((size_t)r != len) {
67 SCLogError("unable to write pidfile: wrote"
68 " %" PRIdMAX " of %" PRIuMAX " bytes.",
69 (intmax_t)r, (uintmax_t)len);
70 close(pidfd);
71 SCReturnInt(-1);
72 }
73
74 close(pidfd);
75 SCReturnInt(0);
76}
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 */
83void SCPidfileRemove(const char *pid_filename)
84{
85 if (pid_filename != NULL) {
86 /* we ignore the result, the user may have removed the file already. */
87 (void)unlink(pid_filename);
88 }
89}
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 */
105int SCPidfileTestRunning(const char *pid_filename)
106{
107 /* Check if the existing process is still alive. */
108 FILE *pf;
109
110 pf = fopen(pid_filename, "r");
111 if (pf == NULL) {
112 if (access(pid_filename, F_OK) == 0) {
113 SCLogError("pid file '%s' exists and can not be read. Aborting!", pid_filename);
114 return -1;
115 } else {
116 return 0;
117 }
118 }
119
120#ifndef OS_WIN32
121 pid_t pidv;
122 if (fscanf(pf, "%d", &pidv) == 1 && kill(pidv, 0) == 0) {
123 SCLogError("pid file '%s' exists and Suricata appears to be running. "
124 "Aborting!",
125 pid_filename);
126 } else
127#endif
128 {
129 SCLogError("pid file '%s' exists but appears stale. "
130 "Make sure Suricata is not running and then remove %s. "
131 "Aborting!",
132 pid_filename, pid_filename);
133 }
134
135 fclose(pf);
136 return -1;
137}
uint8_t len
#define SCEnter(...)
Definition util-debug.h:277
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
int SCPidfileTestRunning(const char *pid_filename)
Check the Suricata pid file (used at the startup)
int SCPidfileCreate(const char *pidfile)
Write a pid file (used at the startup) This commonly needed by the init scripts.
void SCPidfileRemove(const char *pid_filename)
Remove the pid file (used at the startup)
#define O_NOFOLLOW
Definition win32-misc.h:30