4141#include < iostream>
4242#include < string>
4343#include < vector>
44+ #include < sys/types.h> // getpid()
4445#include < unistd.h>
4546
4647#include < ipfixcol2.h>
4748#include < iostream>
49+ #include < fstream>
4850#include " configurator/config_file.hpp"
4951#include " configurator/configurator.hpp"
5052
@@ -53,6 +55,9 @@ extern "C" {
5355#include < build_config.h>
5456}
5557
58+ /* * Internal identification of the module */
59+ static const char *module = " Configurator" ;
60+
5661/* *
5762 * \brief Print information about version of the collector to standard output
5863 */
@@ -77,17 +82,18 @@ print_help()
7782 std::cout
7883 << " IPFIX Collector daemon\n "
7984 << " Usage: ipfixcol [-c FILE] [-d PATH] [-vVh]\n "
80- << " -c FILE Path to the startup configuration file (default: "
81- << IPX_DEFAULT_STARTUP_CONFIG << " )\n "
82- << " -p PATH Add path to a directory with plugins or to a file (default: "
83- << IPX_DEFAULT_PLUGINS_DIR << " )\n "
84- << " -e DIR Path to a directory with definitions of IPFIX Information Elements "
85- << " (default: " << fds_api_cfg_dir () << " )\n "
85+ << " -c FILE Path to the startup configuration file\n "
86+ << " (default: " << IPX_DEFAULT_STARTUP_CONFIG << " )\n "
87+ << " -p PATH Add path to a directory with plugins or to a file\n "
88+ << " (default: " << IPX_DEFAULT_PLUGINS_DIR << " )\n "
89+ << " -e DIR Path to a directory with definitions of IPFIX Information Elements\n "
90+ << " (default: " << fds_api_cfg_dir () << " )\n "
8691 << " -h Show this help message and exit\n "
8792 << " -V Show version information and exit\n "
8893 << " -v Be verbose (in addition, show warning messages)\n "
8994 << " -vv Be more verbose (like previous + info messages)\n "
90- << " -vvv Be even more verbose (like previous + debug messages)\n " ;
95+ << " -vvv Be even more verbose (like previous + debug messages)\n "
96+ << " -P FILE Path to a PID file (without this option, no PID file is created)\n " ;
9197}
9298
9399/* *
@@ -107,6 +113,47 @@ increase_verbosity()
107113 ipx_verb_level_set (level);
108114}
109115
116+ /* *
117+ * \brief Create a PID file (contains Process ID)
118+ * \param[in] file PID file
119+ * \return #IPX_OK on success
120+ * \return #IPX_ERR_DENIED if it is not possible to create the file
121+ */
122+ static int
123+ pid_create (const char *file)
124+ {
125+ IPX_INFO (module , " Creating PID file '%s'" , file);
126+ std::ofstream pid_file (file, std::ofstream::out);
127+ if (pid_file.fail ()) {
128+ IPX_WARNING (module , " Failed to create a PID file '%s'!" , file);
129+ return IPX_ERR_DENIED;
130+ }
131+
132+ pid_file << getpid ();
133+ pid_file.close ();
134+ return IPX_OK;
135+ }
136+
137+ /* *
138+ * \brief Remove a PID file (contains Process ID)
139+ * \param[in] file PID file
140+ * \return #IPX_OK on success
141+ * \return #IPX_ERR_DENIED if it is not possible to remove the file
142+ */
143+ static int
144+ pid_remove (const char *file)
145+ {
146+ IPX_INFO (module , " Removing PID file '%s'" , file);
147+ if (unlink (file) == -1 ) {
148+ const char *err_str;
149+ ipx_strerror (errno, err_str);
150+ IPX_WARNING (module , " Failed to remove a PID file '%s': %s" , file, err_str);
151+ return IPX_ERR_DENIED;
152+ }
153+
154+ return IPX_OK;
155+ }
156+
110157/* *
111158 * \brief Main function
112159 * \param[in] argc Number of arguments
@@ -117,12 +164,13 @@ int main(int argc, char *argv[])
117164{
118165 const char *cfg_startup = nullptr ;
119166 const char *cfg_iedir = nullptr ;
167+ const char *pid_file = nullptr ;
120168 ipx_configurator conf;
121169
122170 // Parse configuration
123171 int opt;
124172 opterr = 0 ; // Disable default error messages
125- while ((opt = getopt (argc, argv, " c:vVhp:e:" )) != -1 ) {
173+ while ((opt = getopt (argc, argv, " c:vVhp:e:P: " )) != -1 ) {
126174 switch (opt) {
127175 case ' c' : // Configuration file
128176 cfg_startup = optarg;
@@ -142,6 +190,9 @@ int main(int argc, char *argv[])
142190 case ' e' :
143191 cfg_iedir = optarg;
144192 break ;
193+ case ' P' :
194+ pid_file = optarg;
195+ break ;
145196 default : // ?
146197 std::cerr << " Unknown parameter '" << static_cast <char >(optopt) << " '!" << std::endl;
147198 return EXIT_FAILURE;
@@ -162,6 +213,11 @@ int main(int argc, char *argv[])
162213 conf.finder .path_add (IPX_DEFAULT_PLUGINS_DIR);
163214 conf.iemgr_set_dir (cfg_iedir);
164215
216+ // Create a PID file
217+ if (pid_file != nullptr && pid_create (pid_file) != IPX_OK) {
218+ pid_file = nullptr ; // Prevent removing the file
219+ }
220+
165221 // Pass control to the parser of the configuration file
166222 int rc;
167223 try {
@@ -174,6 +230,11 @@ int main(int argc, char *argv[])
174230 return EXIT_FAILURE;
175231 }
176232
233+ // Destroy a PID file
234+ if (pid_file != nullptr ) {
235+ pid_remove (pid_file);
236+ }
237+
177238 // Destroy the pipeline configurator
178239 return rc;
179240}
0 commit comments