~jheiss/galera/galera

« back to all changes in this revision

Viewing changes to garb/garb_main.cpp

  • Committer: Alex Yurchenko
  • Date: 2011-08-20 23:37:05 UTC
  • Revision ID: ayurchen@void-20110820233705-532t7g9ip8ss24sv
References lp:828648 - synced with SVN branch 0.8 r2321

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2011 Codership Oy <info@codership.com> */
 
2
 
 
3
#include "garb_config.hpp"
 
4
#include "garb_recv_loop.hpp"
 
5
 
 
6
#include <galerautils.hpp>
 
7
 
 
8
#include <iostream>
 
9
 
 
10
#include <stdlib.h> // exit()
 
11
#include <unistd.h> // setsid(), chdir()
 
12
#include <fcntl.h>  // open()
 
13
 
 
14
namespace garb
 
15
{
 
16
 
 
17
void
 
18
become_daemon () throw (gu::Exception)
 
19
{
 
20
    if (pid_t pid = fork())
 
21
    {
 
22
        if (pid > 0) // parent
 
23
        {
 
24
            exit(0);
 
25
        }
 
26
        else
 
27
        {
 
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";
 
32
        }
 
33
    }
 
34
 
 
35
    // child
 
36
 
 
37
    if (setsid()<0) // become a new process leader, detach from terminal
 
38
    {
 
39
        gu_throw_error(errno) << "setsid() failed";
 
40
    }
 
41
 
 
42
    if (chdir("/")) // detach from potentially removable block devices
 
43
    {
 
44
        gu_throw_error(errno) << "chdir(\"/\") failed";
 
45
    }
 
46
 
 
47
    // umask(0);
 
48
 
 
49
    // A second fork ensures the process cannot acquire a controlling
 
50
    // terminal.
 
51
    if (pid_t pid = fork())
 
52
    {
 
53
        if (pid > 0)
 
54
        {
 
55
            exit(0);
 
56
        }
 
57
        else
 
58
        {
 
59
            gu_throw_error(errno) << "Second fork failed";
 
60
        }
 
61
    }
 
62
 
 
63
    // Close the standard streams. This decouples the daemon from the
 
64
    // terminal that started it.
 
65
    close(0);
 
66
    close(1);
 
67
    close(2);
 
68
 
 
69
    // Bind standard fds (0, 1, 2) to /dev/null
 
70
    for (int fd = 0; fd < 3; ++fd)
 
71
    {
 
72
        if (open("/dev/null", O_RDONLY) < 0)
 
73
        {
 
74
            gu_throw_error(errno) << "Unable to open /dev/null for fd " << fd;
 
75
        }
 
76
    }
 
77
}
 
78
 
 
79
int
 
80
main (int argc, char* argv[])
 
81
{
 
82
    Config config(argc, argv);
 
83
 
 
84
    log_info << "Read config: " <<  config << std::endl;
 
85
 
 
86
    if (config.daemon()) become_daemon();
 
87
 
 
88
    RecvLoop loop (config);
 
89
 
 
90
    return 0;
 
91
}
 
92
 
 
93
} /* namespace garb */
 
94
 
 
95
int
 
96
main (int argc, char* argv[])
 
97
{
 
98
    try
 
99
    {
 
100
        return garb::main (argc, argv);
 
101
    }
 
102
    catch (std::exception& e)
 
103
    {
 
104
        log_fatal << e.what();
 
105
        return 1;
 
106
    }
 
107
}
 
108