diff --git a/src/Makefile.am b/src/Makefile.am index 716b0a23e1..dcef0963ff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -117,6 +117,7 @@ detect-http-client-body.c detect-http-client-body.h \ util-print.c util-print.h \ util-fmemopen.c util-fmemopen.h \ util-cpu.c util-cpu.h \ +util-pidfile.c util-pidfile.h \ util-mpm.c util-mpm.h \ util-spm.c util-spm.h util-clock.h \ util-spm-bs.c util-spm-bs.h \ diff --git a/src/suricata-common.h b/src/suricata-common.h index 278a9283c7..5df2e38feb 100644 --- a/src/suricata-common.h +++ b/src/suricata-common.h @@ -22,6 +22,7 @@ #include #include #include +#include #if HAVE_SYS_SYSCALL_H #include diff --git a/src/suricata.c b/src/suricata.c index 20aeca8b63..9ab6bfe6f3 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -21,6 +21,7 @@ #include "util-pool.h" #include "util-byte.h" #include "util-cpu.h" +#include "util-pidfile.h" #include "detect-parse.h" #include "detect-engine.h" @@ -371,6 +372,7 @@ void usage(const char *progname) printf("\t--list-unittests : list unit tests\n"); printf("\t--fatal-unittests : enable fatal failure on unittest error\n"); #endif /* UNITTESTS */ + printf("\t--pidfile : write pid to this file (only for daemon mode)\n"); printf("\t--init-errors-fatal : enable fatal failure on signature init error\n"); printf("\t--dump-config : show the running configuration\n"); printf("\t--pfring-int : run in pfring mode\n"); @@ -392,6 +394,7 @@ int main(int argc, char **argv) char *sig_file = NULL; char *nfq_id = NULL; char *conf_filename = NULL; + char *pid_filename = NULL; #ifdef UNITTESTS char *regex_arg = NULL; #endif @@ -425,6 +428,7 @@ int main(int argc, char **argv) {"pfring-cluster-type", required_argument, 0, 0}, {"unittest-filter", required_argument, 0, 'U'}, {"list-unittests", 0, &list_unittests, 1}, + {"pidfile", required_argument, 0, 0}, {"init-errors-fatal", 0, 0, 0}, {"fatal-unittests", 0, 0, 0}, {NULL, 0, NULL, 0} @@ -472,6 +476,9 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); #endif /* UNITTESTS */ } + else if(strcmp((long_opts[option_index]).name, "pidfile") == 0) { + pid_filename = optarg; + } else if(strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) { #ifdef UNITTESTS if (ConfSet("unittests.failure_fatal", "1", 0) != 1) { @@ -803,7 +810,17 @@ int main(int argc, char **argv) } #endif /* UNITTESTS */ - if (daemon) Daemonize(); + if (daemon == 1) { + Daemonize(); + if (pid_filename != NULL) { + if (SCPidfileCreate(pid_filename) != 0) + pid_filename = NULL; + } + } else { + if (pid_filename != NULL) + SCLogWarning(SC_ERR_PIDLOG, "The pidfile file option apply only to daemon modes"); + pid_filename = NULL; + } #ifndef OS_WIN32 /* registering signals we use */ @@ -989,6 +1006,8 @@ int main(int argc, char **argv) #endif #endif + SCPidfileRemove(pid_filename); + /** \todo review whats needed here */ #ifdef __SC_CUDA_SUPPORT__ if (PatternMatchDefaultMatcher() == MPM_B2G_CUDA) { diff --git a/src/util-error.c b/src/util-error.c index 6d65d1a62a..4864ff0cbc 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -18,6 +18,7 @@ const char * SCErrorToString(SCError err) switch (err) { CASE_CODE (SC_OK); CASE_CODE (SC_ERR_MEM_ALLOC); + CASE_CODE (SC_ERR_PIDLOG); CASE_CODE (SC_ERR_PCRE_MATCH); CASE_CODE (SC_ERR_PCRE_GET_SUBSTRING); CASE_CODE (SC_ERR_PCRE_COMPILE); diff --git a/src/util-error.h b/src/util-error.h index cc32e86c78..8961305d8d 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -13,6 +13,7 @@ typedef enum { SC_OK, SC_ERR_MEM_ALLOC, + SC_ERR_PIDLOG, SC_ERR_PCRE_MATCH, SC_ERR_PCRE_GET_SUBSTRING, SC_ERR_PCRE_COMPILE, diff --git a/src/util-pidfile.c b/src/util-pidfile.c new file mode 100644 index 0000000000..1aa2c65b8a --- /dev/null +++ b/src/util-pidfile.c @@ -0,0 +1,48 @@ +/* Copyright (c) 2010 Open Infomation Security Foundation */ + +/** + * Copyright (c) 2009 Open Information Security Foundation + * + * \author Pablo Rincon Crespo + * Adaptation of Steve Grubbs patch to our conding guidelines + * (thanks for the patch Steve ;) + */ + +#include "suricata-common.h" +#include "util-pidfile.h" + +/** + * \brief Write a pid file (used at the startup) + * This commonly needed by the init scripts + * \param pointer to the name of the pid file to write (optarg) + * \retval 0 if succes; -1 on failure + */ +int SCPidfileCreate(const char *pidfile) +{ + SCEnter(); + int pidfd, len; + char val[16]; + + len = snprintf(val, sizeof(val), "%u\n", getpid()); + if (len <= 0) { + SCLogError(SC_ERR_PIDLOG, "Pid error (%s)", strerror(errno)); + SCReturnInt(-1); + } + pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644); + if (pidfd < 0) { + SCLogError(SC_ERR_PIDLOG, "Unable to set pidfile (%s)", strerror(errno)); + SCReturnInt(-1); + } + write(pidfd, val, (unsigned int)len); + close(pidfd); + SCReturnInt(0); +} + +/** + * \brief Remove the pid file (used at the startup) + * \param pointer to the name of the pid file to write (optarg) + */ +void SCPidfileRemove(const char *pid_filename) { + if (pid_filename != NULL) + unlink(pid_filename); +} diff --git a/src/util-pidfile.h b/src/util-pidfile.h new file mode 100644 index 0000000000..6c162d29a9 --- /dev/null +++ b/src/util-pidfile.h @@ -0,0 +1,6 @@ +#ifndef __UTIL_PID_H__ +#define __UTIL_PID_H__ + +int SCPidfileCreate(const char *); +void SCPidfileRemove(const char *); +#endif