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 
32 /**
33  * \brief Write a pid file (used at the startup)
34  * This commonly needed by the init scripts
35  *
36  * \param pointer to the name of the pid file to write (optarg)
37  *
38  * \retval 0 if succes
39  * \retval -1 on failure
40  */
41 int SCPidfileCreate(const char *pidfile)
42 {
43  SCEnter();
44 
45  int pidfd = 0;
46  char val[16];
47 
48  size_t len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid());
49  if (len <= 0) {
50  SCLogError(SC_ERR_PIDFILE_SNPRINTF, "Pid error (%s)", strerror(errno));
51  SCReturnInt(-1);
52  }
53 
54  pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
55  if (pidfd < 0) {
56  SCLogError(SC_ERR_PIDFILE_OPEN, "unable to set pidfile '%s': %s",
57  pidfile,
58  strerror(errno));
59  SCReturnInt(-1);
60  }
61 
62  ssize_t r = write(pidfd, val, (unsigned int)len);
63  if (r == -1) {
64  SCLogError(SC_ERR_PIDFILE_WRITE, "unable to write pidfile: %s", strerror(errno));
65  close(pidfd);
66  SCReturnInt(-1);
67  } else if ((size_t)r != len) {
68  SCLogError(SC_ERR_PIDFILE_WRITE, "unable to write pidfile: wrote"
69  " %"PRIdMAX" of %"PRIuMAX" bytes.", (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  */
83 void 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  */
105 int SCPidfileTestRunning(const char *pid_filename)
106 {
107  if (access(pid_filename, F_OK) == 0) {
108  /* Check if the existing process is still alive. */
109  FILE *pf;
110 
111  // coverity[toctou : FALSE]
112  pf = fopen(pid_filename, "r");
113  if (pf == NULL) {
115  "pid file '%s' exists and can not be read. Aborting!",
116  pid_filename);
117  return -1;
118  }
119 
120 #ifndef OS_WIN32
121  pid_t pidv;
122  if (fscanf(pf, "%d", &pidv) == 1 && kill(pidv, 0) == 0) {
124  "pid file '%s' exists and Suricata appears to be running. "
125  "Aborting!", pid_filename);
126  } else
127 #endif
128  {
130  "pid file '%s' exists but appears stale. "
131  "Make sure Suricata is not running and then remove %s. "
132  "Aborting!",
133  pid_filename, pid_filename);
134  }
135 
136  fclose(pf);
137  return -1;
138  }
139  return 0;
140 }
#define O_NOFOLLOW
Definition: win32-misc.h:35
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void SCPidfileRemove(const char *pid_filename)
Remove the pid file (used at the startup)
Definition: util-pidfile.c:83
int SCPidfileTestRunning(const char *pid_filename)
Check the Suricata pid file (used at the startup)
Definition: util-pidfile.c:105
#define SCEnter(...)
Definition: util-debug.h:337
#define SCReturnInt(x)
Definition: util-debug.h:341
int SCPidfileCreate(const char *pidfile)
Write a pid file (used at the startup) This commonly needed by the init scripts.
Definition: util-pidfile.c:41
uint8_t len