1
/* Copyright (C) 2011 Codership Oy <info@codership.com> */
3
#include "garb_config.hpp"
4
#include "garb_recv_loop.hpp"
6
#include <galerautils.hpp>
10
#include <stdlib.h> // exit()
11
#include <unistd.h> // setsid(), chdir()
12
#include <fcntl.h> // open()
18
become_daemon () throw (gu::Exception)
20
if (pid_t pid = fork())
22
if (pid > 0) // parent
28
// I guess we want this to go to stderr as well;
29
std::cerr << "Failed to fork daemon process: "
30
<< errno << " (" << strerror(errno) << ")";
31
gu_throw_error(errno) << "Failed to fork daemon process";
37
if (setsid()<0) // become a new process leader, detach from terminal
39
gu_throw_error(errno) << "setsid() failed";
42
if (chdir("/")) // detach from potentially removable block devices
44
gu_throw_error(errno) << "chdir(\"/\") failed";
49
// A second fork ensures the process cannot acquire a controlling
51
if (pid_t pid = fork())
59
gu_throw_error(errno) << "Second fork failed";
63
// Close the standard streams. This decouples the daemon from the
64
// terminal that started it.
69
// Bind standard fds (0, 1, 2) to /dev/null
70
for (int fd = 0; fd < 3; ++fd)
72
if (open("/dev/null", O_RDONLY) < 0)
74
gu_throw_error(errno) << "Unable to open /dev/null for fd " << fd;
80
main (int argc, char* argv[])
82
Config config(argc, argv);
84
log_info << "Read config: " << config << std::endl;
86
if (config.daemon()) become_daemon();
88
RecvLoop loop (config);
93
} /* namespace garb */
96
main (int argc, char* argv[])
100
return garb::main (argc, argv);
102
catch (std::exception& e)
104
log_fatal << e.what();