src/​examples/​cpp03/​fork/​daemon.​cppsrc/​examples/​cpp11/​fork/​daemon.​cpp
⋮⋮
1 /​/​1 /​/​
2 /​/​·​daemon.​cpp2 /​/​·​daemon.​cpp
3 /​/​·​~~~~~~~~~~3 /​/​·​~~~~~~~~~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2018·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2018·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​
6 /​/​6 /​/​
7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying
8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​
9 /​/​9 /​/​
10 10
11 #include·​<asio/​io_context.​hpp>11 #include·​<asio/​io_context.​hpp>
12 #include·​<asio/​ip/​udp.​hpp>12 #include·​<asio/​ip/​udp.​hpp>
13 #include·​<asio/​signal_set.​hpp>13 #include·​<asio/​signal_set.​hpp>
14 #include·​<boost/​array.​hpp>14 #include·​<array>
15 #include·​<boost/​bind.​hpp>
16 #include·​<ctime>15 #include·​<ctime>
17 #include·​<iostream>16 #include·​<iostream>
18 #include·​<syslog.​h>17 #include·​<syslog.​h>
19 #include·​<unistd.​h>18 #include·​<unistd.​h>
20 19
21 using·​asio:​:​ip:​:​udp;​20 using·​asio:​:​ip:​:​udp;​
22 21
23 class·​udp_daytime_server22 class·​udp_daytime_server
24 {23 {
25 public:​24 public:​
26 ·​·​udp_daytime_server(as​io:​:​io_context&·​io_context)​25 ·​·​udp_daytime_server(as​io:​:​io_context&·​io_context)​
27 ·​·​·​·​:​·​socket_(io_context,​·​udp:​:​endpoint(udp:​:​v4()​,​·​13)​)​26 ·​·​·​·​:​·​socket_(io_context,​·​{udp:​:​v4()​,​·​13})​
28 ·​·​{27 ·​·​{
29 ·​·​·​·​start_receive()​;​28 ·​·​·​·​receive()​;​
30 ·​·​}29 ·​·​}
31 30
32 private:​31 private:​
33 ·​·​void·​start_receive()​32 ·​·​void·​receive()​
34 ·​·​{33 ·​·​{
35 ·​·​·​·​socket_.​async_receive_from(34 ·​·​·​·​socket_.​async_receive_from(
36 ·​·​·​·​·​·​·​·​asio:​:​buffer(recv_buffer_)​,​·​remote_endpoint_,​35 ·​·​·​·​·​·​·​·​asio:​:​buffer(recv_buffer_)​,​·​remote_endpoint_,​
37 ·​·​·​·​·​·​·​·​boost:​:​bind(&udp_daytime_ser​ver:​:​handle_receive,​·​this,​·​_1)​)​;​36 ·​·​·​·​·​·​·​·​[this](std:​:​error_code·​ec,​·​std:​:​size_t·​/​*n*/​)​
38 ·​·​}37 ·​·​·​·​·​·​·​·​{
39 38 ·​·​·​·​·​·​·​·​·​·​if·​(!ec)​
40 ·​·​void·​handle_receive(const·​asio:​:​error_code&·​ec)​39 ·​·​·​·​·​·​·​·​·​·​{
41 ·​·​{40 ·​·​·​·​·​·​·​·​·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​time_t,​·​time·​and·​ctime;​
42 ·​·​·​·​if·​(!ec)​41 ·​·​·​·​·​·​·​·​·​·​·​·​time_t·​now·​=·​time(0)​;​
43 ·​·​·​·​{42 ·​·​·​·​·​·​·​·​·​·​·​·​std:​:​string·​message·​=·​ctime(&now)​;​
44 ·​·​·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​time_t,​·​time·​and·​ctime;​43
45 ·​·​·​·​·​·​time_t·​now·​=·​time(0)​;​44 ·​·​·​·​·​·​·​·​·​·​·​·​std:​:​error_code·​ignored_ec;​
46 ·​·​·​·​·​·​std:​:​string·​message·​=·​ctime(&now)​;​45 ·​·​·​·​·​·​·​·​·​·​·​·​socket_.​send_to(asio:​:​buffer(message)​,​
47 46 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​remote_endpoint_,​·​0,​·​ignored_ec)​;​
48 ·​·​·​·​·​·​asio:​:​error_code·​ignored_ec;​47 ·​·​·​·​·​·​·​·​·​·​}
49 ·​·​·​·​·​·​socket_.​send_to(asio:​:​buffer(message)​,​
50 ·​·​·​·​·​·​·​·​·​·​remote_endpoint_,​·​0,​·​ignored_ec)​;​
51 ·​·​·​·​}
52 48
53 ·​·​·​·​start_receive()​;​49 ·​·​·​·​·​·​·​·​·​·​receive()​;​
50 ·​·​·​·​·​·​·​·​})​;​
54 ·​·​}51 ·​·​}
55 52
56 ·​·​udp:​:​socket·​socket_;​53 ·​·​udp:​:​socket·​socket_;​
57 ·​·​udp:​:​endpoint·​remote_endpoint_;​54 ·​·​udp:​:​endpoint·​remote_endpoint_;​
58 ·​·​boost:​:​array<char,​·​1>·​recv_buffer_;​55 ·​·​std:​:​array<char,​·​1>·​recv_buffer_;​
59 };​56 };​
60 57
61 int·​main()​58 int·​main()​
62 {59 {
63 ·​·​try60 ·​·​try
64 ·​·​{61 ·​·​{
65 ·​·​·​·​asio:​:​io_context·​io_context;​62 ·​·​·​·​asio:​:​io_context·​io_context;​
66 63
67 ·​·​·​·​/​/​·​Initialise·​the·​server·​before·​becoming·​a·​daemon.​·​If·​the·​process·​is64 ·​·​·​·​/​/​·​Initialise·​the·​server·​before·​becoming·​a·​daemon.​·​If·​the·​process·​is
68 ·​·​·​·​/​/​·​started·​from·​a·​shell,​·​this·​means·​any·​errors·​will·​be·​reported·​back·​to·​the65 ·​·​·​·​/​/​·​started·​from·​a·​shell,​·​this·​means·​any·​errors·​will·​be·​reported·​back·​to·​the
69 ·​·​·​·​/​/​·​user.​66 ·​·​·​·​/​/​·​user.​
70 ·​·​·​·​udp_daytime_server·​server(io_context)​;​67 ·​·​·​·​udp_daytime_server·​server(io_context)​;​
71 68
72 ·​·​·​·​/​/​·​Register·​signal·​handlers·​so·​that·​the·​daemon·​may·​be·​shut·​down.​·​You·​may69 ·​·​·​·​/​/​·​Register·​signal·​handlers·​so·​that·​the·​daemon·​may·​be·​shut·​down.​·​You·​may
73 ·​·​·​·​/​/​·​also·​want·​to·​register·​for·​other·​signals,​·​such·​as·​SIGHUP·​to·​trigger·​a70 ·​·​·​·​/​/​·​also·​want·​to·​register·​for·​other·​signals,​·​such·​as·​SIGHUP·​to·​trigger·​a
74 ·​·​·​·​/​/​·​re-​read·​of·​a·​configuration·​file.​71 ·​·​·​·​/​/​·​re-​read·​of·​a·​configuration·​file.​
75 ·​·​·​·​asio:​:​signal_set·​signals(io_context,​·​SIGINT,​·​SIGTERM)​;​72 ·​·​·​·​asio:​:​signal_set·​signals(io_context,​·​SIGINT,​·​SIGTERM)​;​
76 ·​·​·​·​signals.​async_wait(73 ·​·​·​·​signals.​async_wait(
77 ·​·​·​·​·​·​·​·​boost:​:​bind(&asio:​:​io_context:​:​stop,​·​&io_context)​)​;​74 ·​·​·​·​·​·​·​·​[&](std:​:​error_code·​/​*ec*/​,​·​int·​/​*signo*/​)​
75 ·​·​·​·​·​·​·​·​{
76 ·​·​·​·​·​·​·​·​·​·​io_context.​stop()​;​
77 ·​·​·​·​·​·​·​·​})​;​
78 78
79 ·​·​·​·​/​/​·​Inform·​the·​io_context·​that·​we·​are·​about·​to·​become·​a·​daemon.​·​The79 ·​·​·​·​/​/​·​Inform·​the·​io_context·​that·​we·​are·​about·​to·​become·​a·​daemon.​·​The
80 ·​·​·​·​/​/​·​io_context·​cleans·​up·​any·​internal·​resources,​·​such·​as·​threads,​·​that·​may80 ·​·​·​·​/​/​·​io_context·​cleans·​up·​any·​internal·​resources,​·​such·​as·​threads,​·​that·​may
81 ·​·​·​·​/​/​·​interfere·​with·​forking.​81 ·​·​·​·​/​/​·​interfere·​with·​forking.​
82 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​82 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​
83 83
84 ·​·​·​·​/​/​·​Fork·​the·​process·​and·​have·​the·​parent·​exit.​·​If·​the·​process·​was·​started84 ·​·​·​·​/​/​·​Fork·​the·​process·​and·​have·​the·​parent·​exit.​·​If·​the·​process·​was·​started
85 ·​·​·​·​/​/​·​from·​a·​shell,​·​this·​returns·​control·​to·​the·​user.​·​Forking·​a·​new·​process·​is85 ·​·​·​·​/​/​·​from·​a·​shell,​·​this·​returns·​control·​to·​the·​user.​·​Forking·​a·​new·​process·​is
86 ·​·​·​·​/​/​·​also·​a·​prerequisite·​for·​the·​subsequent·​call·​to·​setsid()​.​86 ·​·​·​·​/​/​·​also·​a·​prerequisite·​for·​the·​subsequent·​call·​to·​setsid()​.​
87 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​87 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​
88 ·​·​·​·​{88 ·​·​·​·​{
89 ·​·​·​·​·​·​if·​(pid·​>·​0)​89 ·​·​·​·​·​·​if·​(pid·​>·​0)​
90 ·​·​·​·​·​·​{90 ·​·​·​·​·​·​{
91 ·​·​·​·​·​·​·​·​/​/​·​We're·​in·​the·​parent·​process·​and·​need·​to·​exit.​91 ·​·​·​·​·​·​·​·​/​/​·​We're·​in·​the·​parent·​process·​and·​need·​to·​exit.​
92 ·​·​·​·​·​·​·​·​/​/​92 ·​·​·​·​·​·​·​·​/​/​
93 ·​·​·​·​·​·​·​·​/​/​·​When·​the·​exit()​·​function·​is·​used,​·​the·​program·​terminates·​without93 ·​·​·​·​·​·​·​·​/​/​·​When·​the·​exit()​·​function·​is·​used,​·​the·​program·​terminates·​without
94 ·​·​·​·​·​·​·​·​/​/​·​invoking·​local·​variables'·​destructors.​·​Only·​global·​variables·​are94 ·​·​·​·​·​·​·​·​/​/​·​invoking·​local·​variables'·​destructors.​·​Only·​global·​variables·​are
95 ·​·​·​·​·​·​·​·​/​/​·​destroyed.​·​As·​the·​io_context·​object·​is·​a·​local·​variable,​·​this·​means95 ·​·​·​·​·​·​·​·​/​/​·​destroyed.​·​As·​the·​io_context·​object·​is·​a·​local·​variable,​·​this·​means
96 ·​·​·​·​·​·​·​·​/​/​·​we·​do·​not·​have·​to·​call:​96 ·​·​·​·​·​·​·​·​/​/​·​we·​do·​not·​have·​to·​call:​
97 ·​·​·​·​·​·​·​·​/​/​97 ·​·​·​·​·​·​·​·​/​/​
98 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_parent)​;​98 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_parent)​;​
99 ·​·​·​·​·​·​·​·​/​/​99 ·​·​·​·​·​·​·​·​/​/​
100 ·​·​·​·​·​·​·​·​/​/​·​However,​·​this·​line·​should·​be·​added·​before·​each·​call·​to·​exit()​·​if100 ·​·​·​·​·​·​·​·​/​/​·​However,​·​this·​line·​should·​be·​added·​before·​each·​call·​to·​exit()​·​if
101 ·​·​·​·​·​·​·​·​/​/​·​using·​a·​global·​io_context·​object.​·​An·​additional·​call:​101 ·​·​·​·​·​·​·​·​/​/​·​using·​a·​global·​io_context·​object.​·​An·​additional·​call:​
102 ·​·​·​·​·​·​·​·​/​/​102 ·​·​·​·​·​·​·​·​/​/​
103 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​103 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​
104 ·​·​·​·​·​·​·​·​/​/​104 ·​·​·​·​·​·​·​·​/​/​
105 ·​·​·​·​·​·​·​·​/​/​·​should·​also·​precede·​the·​second·​fork()​.​105 ·​·​·​·​·​·​·​·​/​/​·​should·​also·​precede·​the·​second·​fork()​.​
106 ·​·​·​·​·​·​·​·​exit(0)​;​106 ·​·​·​·​·​·​·​·​exit(0)​;​
107 ·​·​·​·​·​·​}107 ·​·​·​·​·​·​}
108 ·​·​·​·​·​·​else108 ·​·​·​·​·​·​else
109 ·​·​·​·​·​·​{109 ·​·​·​·​·​·​{
110 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"First·​fork·​failed:​·​%m")​;​110 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"First·​fork·​failed:​·​%m")​;​
111 ·​·​·​·​·​·​·​·​return·​1;​111 ·​·​·​·​·​·​·​·​return·​1;​
112 ·​·​·​·​·​·​}112 ·​·​·​·​·​·​}
113 ·​·​·​·​}113 ·​·​·​·​}
114 114
115 ·​·​·​·​/​/​·​Make·​the·​process·​a·​new·​session·​leader.​·​This·​detaches·​it·​from·​the115 ·​·​·​·​/​/​·​Make·​the·​process·​a·​new·​session·​leader.​·​This·​detaches·​it·​from·​the
116 ·​·​·​·​/​/​·​terminal.​116 ·​·​·​·​/​/​·​terminal.​
117 ·​·​·​·​setsid()​;​117 ·​·​·​·​setsid()​;​
118 118
119 ·​·​·​·​/​/​·​A·​process·​inherits·​its·​working·​directory·​from·​its·​parent.​·​This·​could·​be119 ·​·​·​·​/​/​·​A·​process·​inherits·​its·​working·​directory·​from·​its·​parent.​·​This·​could·​be
120 ·​·​·​·​/​/​·​on·​a·​mounted·​filesystem,​·​which·​means·​that·​the·​running·​daemon·​would120 ·​·​·​·​/​/​·​on·​a·​mounted·​filesystem,​·​which·​means·​that·​the·​running·​daemon·​would
121 ·​·​·​·​/​/​·​prevent·​this·​filesystem·​from·​being·​unmounted.​·​Changing·​to·​the·​root121 ·​·​·​·​/​/​·​prevent·​this·​filesystem·​from·​being·​unmounted.​·​Changing·​to·​the·​root
122 ·​·​·​·​/​/​·​directory·​avoids·​this·​problem.​122 ·​·​·​·​/​/​·​directory·​avoids·​this·​problem.​
123 ·​·​·​·​chdir("/​")​;​123 ·​·​·​·​chdir("/​")​;​
124 124
125 ·​·​·​·​/​/​·​The·​file·​mode·​creation·​mask·​is·​also·​inherited·​from·​the·​parent·​process.​125 ·​·​·​·​/​/​·​The·​file·​mode·​creation·​mask·​is·​also·​inherited·​from·​the·​parent·​process.​
126 ·​·​·​·​/​/​·​We·​don't·​want·​to·​restrict·​the·​permissions·​on·​files·​created·​by·​the126 ·​·​·​·​/​/​·​We·​don't·​want·​to·​restrict·​the·​permissions·​on·​files·​created·​by·​the
127 ·​·​·​·​/​/​·​daemon,​·​so·​the·​mask·​is·​cleared.​127 ·​·​·​·​/​/​·​daemon,​·​so·​the·​mask·​is·​cleared.​
128 ·​·​·​·​umask(0)​;​128 ·​·​·​·​umask(0)​;​
129 129
130 ·​·​·​·​/​/​·​A·​second·​fork·​ensures·​the·​process·​cannot·​acquire·​a·​controlling·​terminal.​130 ·​·​·​·​/​/​·​A·​second·​fork·​ensures·​the·​process·​cannot·​acquire·​a·​controlling·​terminal.​
131 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​131 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​
132 ·​·​·​·​{132 ·​·​·​·​{
133 ·​·​·​·​·​·​if·​(pid·​>·​0)​133 ·​·​·​·​·​·​if·​(pid·​>·​0)​
134 ·​·​·​·​·​·​{134 ·​·​·​·​·​·​{
135 ·​·​·​·​·​·​·​·​exit(0)​;​135 ·​·​·​·​·​·​·​·​exit(0)​;​
136 ·​·​·​·​·​·​}136 ·​·​·​·​·​·​}
137 ·​·​·​·​·​·​else137 ·​·​·​·​·​·​else
138 ·​·​·​·​·​·​{138 ·​·​·​·​·​·​{
139 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Second·​fork·​failed:​·​%m")​;​139 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Second·​fork·​failed:​·​%m")​;​
140 ·​·​·​·​·​·​·​·​return·​1;​140 ·​·​·​·​·​·​·​·​return·​1;​
141 ·​·​·​·​·​·​}141 ·​·​·​·​·​·​}
142 ·​·​·​·​}142 ·​·​·​·​}
143 143
144 ·​·​·​·​/​/​·​Close·​the·​standard·​streams.​·​This·​decouples·​the·​daemon·​from·​the·​terminal144 ·​·​·​·​/​/​·​Close·​the·​standard·​streams.​·​This·​decouples·​the·​daemon·​from·​the·​terminal
145 ·​·​·​·​/​/​·​that·​started·​it.​145 ·​·​·​·​/​/​·​that·​started·​it.​
146 ·​·​·​·​close(0)​;​146 ·​·​·​·​close(0)​;​
147 ·​·​·​·​close(1)​;​147 ·​·​·​·​close(1)​;​
148 ·​·​·​·​close(2)​;​148 ·​·​·​·​close(2)​;​
149 149
150 ·​·​·​·​/​/​·​We·​don't·​want·​the·​daemon·​to·​have·​any·​standard·​input.​150 ·​·​·​·​/​/​·​We·​don't·​want·​the·​daemon·​to·​have·​any·​standard·​input.​
151 ·​·​·​·​if·​(open("/​dev/​null",​·​O_RDONLY)​·​<·​0)​151 ·​·​·​·​if·​(open("/​dev/​null",​·​O_RDONLY)​·​<·​0)​
152 ·​·​·​·​{152 ·​·​·​·​{
153 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​open·​/​dev/​null:​·​%m")​;​153 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​open·​/​dev/​null:​·​%m")​;​
154 ·​·​·​·​·​·​return·​1;​154 ·​·​·​·​·​·​return·​1;​
155 ·​·​·​·​}155 ·​·​·​·​}
156 156
157 ·​·​·​·​/​/​·​Send·​standard·​output·​to·​a·​log·​file.​157 ·​·​·​·​/​/​·​Send·​standard·​output·​to·​a·​log·​file.​
158 ·​·​·​·​const·​char*·​output·​=·​"/​tmp/​asio.​daemon.​out";​158 ·​·​·​·​const·​char*·​output·​=·​"/​tmp/​asio.​daemon.​out";​
159 ·​·​·​·​const·​int·​flags·​=·​O_WRONLY·​|·​O_CREAT·​|·​O_APPEND;​159 ·​·​·​·​const·​int·​flags·​=·​O_WRONLY·​|·​O_CREAT·​|·​O_APPEND;​
160 ·​·​·​·​const·​mode_t·​mode·​=·​S_IRUSR·​|·​S_IWUSR·​|·​S_IRGRP·​|·​S_IROTH;​160 ·​·​·​·​const·​mode_t·​mode·​=·​S_IRUSR·​|·​S_IWUSR·​|·​S_IRGRP·​|·​S_IROTH;​
161 ·​·​·​·​if·​(open(output,​·​flags,​·​mode)​·​<·​0)​161 ·​·​·​·​if·​(open(output,​·​flags,​·​mode)​·​<·​0)​
162 ·​·​·​·​{162 ·​·​·​·​{
163 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​open·​output·​file·​%s:​·​%m",​·​output)​;​163 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​open·​output·​file·​%s:​·​%m",​·​output)​;​
164 ·​·​·​·​·​·​return·​1;​164 ·​·​·​·​·​·​return·​1;​
165 ·​·​·​·​}165 ·​·​·​·​}
166 166
167 ·​·​·​·​/​/​·​Also·​send·​standard·​error·​to·​the·​same·​log·​file.​167 ·​·​·​·​/​/​·​Also·​send·​standard·​error·​to·​the·​same·​log·​file.​
168 ·​·​·​·​if·​(dup(1)​·​<·​0)​168 ·​·​·​·​if·​(dup(1)​·​<·​0)​
169 ·​·​·​·​{169 ·​·​·​·​{
170 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​dup·​output·​descriptor:​·​%m")​;​170 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​dup·​output·​descriptor:​·​%m")​;​
171 ·​·​·​·​·​·​return·​1;​171 ·​·​·​·​·​·​return·​1;​
172 ·​·​·​·​}172 ·​·​·​·​}
173 173
174 ·​·​·​·​/​/​·​Inform·​the·​io_context·​that·​we·​have·​finished·​becoming·​a·​daemon.​·​The174 ·​·​·​·​/​/​·​Inform·​the·​io_context·​that·​we·​have·​finished·​becoming·​a·​daemon.​·​The
175 ·​·​·​·​/​/​·​io_context·​uses·​this·​opportunity·​to·​create·​any·​internal·​file·​descriptors175 ·​·​·​·​/​/​·​io_context·​uses·​this·​opportunity·​to·​create·​any·​internal·​file·​descriptors
176 ·​·​·​·​/​/​·​that·​need·​to·​be·​private·​to·​the·​new·​process.​176 ·​·​·​·​/​/​·​that·​need·​to·​be·​private·​to·​the·​new·​process.​
177 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_child)​;​177 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_child)​;​
178 178
179 ·​·​·​·​/​/​·​The·​io_context·​can·​now·​be·​used·​normally.​179 ·​·​·​·​/​/​·​The·​io_context·​can·​now·​be·​used·​normally.​
180 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​started")​;​180 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​started")​;​
181 ·​·​·​·​io_context.​run()​;​181 ·​·​·​·​io_context.​run()​;​
182 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​stopped")​;​182 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​stopped")​;​
183 ·​·​}183 ·​·​}
184 ·​·​catch·​(std:​:​exception&·​e)​184 ·​·​catch·​(std:​:​exception&·​e)​
185 ·​·​{185 ·​·​{
186 ·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Exception:​·​%s",​·​e.​what()​)​;​186 ·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Exception:​·​%s",​·​e.​what()​)​;​
187 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​std:​:​endl;​187 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​std:​:​endl;​
188 ·​·​}188 ·​·​}
189 }189 }