Skip to content

Commit 10713cb

Browse files
committed
Core: add support for a PID file
1 parent d63d4e0 commit 10713cb

File tree

1 file changed

+69
-8
lines changed

1 file changed

+69
-8
lines changed

src/core/main.cpp

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@
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

Comments
 (0)