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-​2023·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2023·​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/​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,​36 ·​·​·​·​·​·​·​·​[this](std:​:​error_code·​ec,​·​std:​:​size_t·​/​*n*/​)​
38 ·​·​·​·​·​·​·​·​·​·​this,​·​boost:​:​placeholders:​:​_1)​)​;​37 ·​·​·​·​·​·​·​·​{
39 ·​·​}38 ·​·​·​·​·​·​·​·​·​·​if·​(!ec)​
39 ·​·​·​·​·​·​·​·​·​·​{
40 ·​·​·​·​·​·​·​·​·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​time_t,​·​time·​and·​ctime;​
41 ·​·​·​·​·​·​·​·​·​·​·​·​time_t·​now·​=·​time(0)​;​
42 ·​·​·​·​·​·​·​·​·​·​·​·​std:​:​string·​message·​=·​ctime(&now)​;​
40 43
41 ·​·​void·​handle_receive(const·​asio:​:​error_code&·​ec)​44 ·​·​·​·​·​·​·​·​·​·​·​·​std:​:​error_code·​ignored_ec;​
42 ·​·​{45 ·​·​·​·​·​·​·​·​·​·​·​·​socket_.​send_to(asio:​:​buffer(message)​,​
43 ·​·​·​·​if·​(!ec)​46 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​remote_endpoint_,​·​0,​·​ignored_ec)​;​
44 ·​·​·​·​{47 ·​·​·​·​·​·​·​·​·​·​}
45 ·​·​·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​time_t,​·​time·​and·​ctime;​
46 ·​·​·​·​·​·​time_t·​now·​=·​time(0)​;​
47 ·​·​·​·​·​·​std:​:​string·​message·​=·​ctime(&now)​;​
48 48
49 ·​·​·​·​·​·​asio:​:​error_code·​ignored_ec;​49 ·​·​·​·​·​·​·​·​·​·​receive()​;​
50 ·​·​·​·​·​·​socket_.​send_to(asio:​:​buffer(message)​,​50 ·​·​·​·​·​·​·​·​})​;​
51 ·​·​·​·​·​·​·​·​·​·​remote_endpoint_,​·​0,​·​ignored_ec)​;​
52 ·​·​·​·​}
53
54 ·​·​·​·​start_receive()​;​
55 ·​·​}51 ·​·​}
56 52
57 ·​·​udp:​:​socket·​socket_;​53 ·​·​udp:​:​socket·​socket_;​
58 ·​·​udp:​:​endpoint·​remote_endpoint_;​54 ·​·​udp:​:​endpoint·​remote_endpoint_;​
59 ·​·​boost:​:​array<char,​·​1>·​recv_buffer_;​55 ·​·​std:​:​array<char,​·​1>·​recv_buffer_;​
60 };​56 };​
61 57
62 int·​main()​58 int·​main()​
63 {59 {
64 ·​·​try60 ·​·​try
65 ·​·​{61 ·​·​{
66 ·​·​·​·​asio:​:​io_context·​io_context;​62 ·​·​·​·​asio:​:​io_context·​io_context;​
67 63
68 ·​·​·​·​/​/​·​Initialise·​the·​server·​before·​becoming·​a·​daemon.​·​If·​the·​process·​is64 ·​·​·​·​/​/​·​Initialise·​the·​server·​before·​becoming·​a·​daemon.​·​If·​the·​process·​is
69 ·​·​·​·​/​/​·​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
70 ·​·​·​·​/​/​·​user.​66 ·​·​·​·​/​/​·​user.​
71 ·​·​·​·​udp_daytime_server·​server(io_context)​;​67 ·​·​·​·​udp_daytime_server·​server(io_context)​;​
72 68
73 ·​·​·​·​/​/​·​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
74 ·​·​·​·​/​/​·​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
75 ·​·​·​·​/​/​·​re-​read·​of·​a·​configuration·​file.​71 ·​·​·​·​/​/​·​re-​read·​of·​a·​configuration·​file.​
76 ·​·​·​·​asio:​:​signal_set·​signals(io_context,​·​SIGINT,​·​SIGTERM)​;​72 ·​·​·​·​asio:​:​signal_set·​signals(io_context,​·​SIGINT,​·​SIGTERM)​;​
77 ·​·​·​·​signals.​async_wait(73 ·​·​·​·​signals.​async_wait(
78 ·​·​·​·​·​·​·​·​boost:​:​bind(&asio:​:​io_context:​:​stop,​·​&io_context)​)​;​74 ·​·​·​·​·​·​·​·​[&](std:​:​error_code·​/​*ec*/​,​·​int·​/​*signo*/​)​
75 ·​·​·​·​·​·​·​·​{
76 ·​·​·​·​·​·​·​·​·​·​io_context.​stop()​;​
77 ·​·​·​·​·​·​·​·​})​;​
79 78
80 ·​·​·​·​/​/​·​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
81 ·​·​·​·​/​/​·​io_context·​cleans·​up·​any·​internal·​resources,​·​such·​as·​threads,​·​that·​may80 ·​·​·​·​/​/​·​io_context·​cleans·​up·​any·​internal·​resources,​·​such·​as·​threads,​·​that·​may
82 ·​·​·​·​/​/​·​interfere·​with·​forking.​81 ·​·​·​·​/​/​·​interfere·​with·​forking.​
83 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​82 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​
84 83
85 ·​·​·​·​/​/​·​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
86 ·​·​·​·​/​/​·​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
87 ·​·​·​·​/​/​·​also·​a·​prerequisite·​for·​the·​subsequent·​call·​to·​setsid()​.​86 ·​·​·​·​/​/​·​also·​a·​prerequisite·​for·​the·​subsequent·​call·​to·​setsid()​.​
88 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​87 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​
89 ·​·​·​·​{88 ·​·​·​·​{
90 ·​·​·​·​·​·​if·​(pid·​>·​0)​89 ·​·​·​·​·​·​if·​(pid·​>·​0)​
91 ·​·​·​·​·​·​{90 ·​·​·​·​·​·​{
92 ·​·​·​·​·​·​·​·​/​/​·​We're·​in·​the·​parent·​process·​and·​need·​to·​exit.​91 ·​·​·​·​·​·​·​·​/​/​·​We're·​in·​the·​parent·​process·​and·​need·​to·​exit.​
93 ·​·​·​·​·​·​·​·​/​/​92 ·​·​·​·​·​·​·​·​/​/​
94 ·​·​·​·​·​·​·​·​/​/​·​When·​the·​exit()​·​function·​is·​used,​·​the·​program·​terminates·​without93 ·​·​·​·​·​·​·​·​/​/​·​When·​the·​exit()​·​function·​is·​used,​·​the·​program·​terminates·​without
95 ·​·​·​·​·​·​·​·​/​/​·​invoking·​local·​variables'·​destructors.​·​Only·​global·​variables·​are94 ·​·​·​·​·​·​·​·​/​/​·​invoking·​local·​variables'·​destructors.​·​Only·​global·​variables·​are
96 ·​·​·​·​·​·​·​·​/​/​·​destroyed.​·​As·​the·​io_context·​object·​is·​a·​local·​variable,​·​this·​means95 ·​·​·​·​·​·​·​·​/​/​·​destroyed.​·​As·​the·​io_context·​object·​is·​a·​local·​variable,​·​this·​means
97 ·​·​·​·​·​·​·​·​/​/​·​we·​do·​not·​have·​to·​call:​96 ·​·​·​·​·​·​·​·​/​/​·​we·​do·​not·​have·​to·​call:​
98 ·​·​·​·​·​·​·​·​/​/​97 ·​·​·​·​·​·​·​·​/​/​
99 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_parent)​;​98 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_parent)​;​
100 ·​·​·​·​·​·​·​·​/​/​99 ·​·​·​·​·​·​·​·​/​/​
101 ·​·​·​·​·​·​·​·​/​/​·​However,​·​this·​line·​should·​be·​added·​before·​each·​call·​to·​exit()​·​if100 ·​·​·​·​·​·​·​·​/​/​·​However,​·​this·​line·​should·​be·​added·​before·​each·​call·​to·​exit()​·​if
102 ·​·​·​·​·​·​·​·​/​/​·​using·​a·​global·​io_context·​object.​·​An·​additional·​call:​101 ·​·​·​·​·​·​·​·​/​/​·​using·​a·​global·​io_context·​object.​·​An·​additional·​call:​
103 ·​·​·​·​·​·​·​·​/​/​102 ·​·​·​·​·​·​·​·​/​/​
104 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​103 ·​·​·​·​·​·​·​·​/​/​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_prepare)​;​
105 ·​·​·​·​·​·​·​·​/​/​104 ·​·​·​·​·​·​·​·​/​/​
106 ·​·​·​·​·​·​·​·​/​/​·​should·​also·​precede·​the·​second·​fork()​.​105 ·​·​·​·​·​·​·​·​/​/​·​should·​also·​precede·​the·​second·​fork()​.​
107 ·​·​·​·​·​·​·​·​exit(0)​;​106 ·​·​·​·​·​·​·​·​exit(0)​;​
108 ·​·​·​·​·​·​}107 ·​·​·​·​·​·​}
109 ·​·​·​·​·​·​else108 ·​·​·​·​·​·​else
110 ·​·​·​·​·​·​{109 ·​·​·​·​·​·​{
111 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"First·​fork·​failed:​·​%m")​;​110 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"First·​fork·​failed:​·​%m")​;​
112 ·​·​·​·​·​·​·​·​return·​1;​111 ·​·​·​·​·​·​·​·​return·​1;​
113 ·​·​·​·​·​·​}112 ·​·​·​·​·​·​}
114 ·​·​·​·​}113 ·​·​·​·​}
115 114
116 ·​·​·​·​/​/​·​Make·​the·​process·​a·​new·​session·​leader.​·​This·​detaches·​it·​from·​the115 ·​·​·​·​/​/​·​Make·​the·​process·​a·​new·​session·​leader.​·​This·​detaches·​it·​from·​the
117 ·​·​·​·​/​/​·​terminal.​116 ·​·​·​·​/​/​·​terminal.​
118 ·​·​·​·​setsid()​;​117 ·​·​·​·​setsid()​;​
119 118
120 ·​·​·​·​/​/​·​A·​process·​inherits·​its·​working·​directory·​from·​its·​parent.​·​This·​could·​be119 ·​·​·​·​/​/​·​A·​process·​inherits·​its·​working·​directory·​from·​its·​parent.​·​This·​could·​be
121 ·​·​·​·​/​/​·​on·​a·​mounted·​filesystem,​·​which·​means·​that·​the·​running·​daemon·​would120 ·​·​·​·​/​/​·​on·​a·​mounted·​filesystem,​·​which·​means·​that·​the·​running·​daemon·​would
122 ·​·​·​·​/​/​·​prevent·​this·​filesystem·​from·​being·​unmounted.​·​Changing·​to·​the·​root121 ·​·​·​·​/​/​·​prevent·​this·​filesystem·​from·​being·​unmounted.​·​Changing·​to·​the·​root
123 ·​·​·​·​/​/​·​directory·​avoids·​this·​problem.​122 ·​·​·​·​/​/​·​directory·​avoids·​this·​problem.​
124 ·​·​·​·​chdir("/​")​;​123 ·​·​·​·​chdir("/​")​;​
125 124
126 ·​·​·​·​/​/​·​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.​
127 ·​·​·​·​/​/​·​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
128 ·​·​·​·​/​/​·​daemon,​·​so·​the·​mask·​is·​cleared.​127 ·​·​·​·​/​/​·​daemon,​·​so·​the·​mask·​is·​cleared.​
129 ·​·​·​·​umask(0)​;​128 ·​·​·​·​umask(0)​;​
130 129
131 ·​·​·​·​/​/​·​A·​second·​fork·​ensures·​the·​process·​cannot·​acquire·​a·​controlling·​terminal.​130 ·​·​·​·​/​/​·​A·​second·​fork·​ensures·​the·​process·​cannot·​acquire·​a·​controlling·​terminal.​
132 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​131 ·​·​·​·​if·​(pid_t·​pid·​=·​fork()​)​
133 ·​·​·​·​{132 ·​·​·​·​{
134 ·​·​·​·​·​·​if·​(pid·​>·​0)​133 ·​·​·​·​·​·​if·​(pid·​>·​0)​
135 ·​·​·​·​·​·​{134 ·​·​·​·​·​·​{
136 ·​·​·​·​·​·​·​·​exit(0)​;​135 ·​·​·​·​·​·​·​·​exit(0)​;​
137 ·​·​·​·​·​·​}136 ·​·​·​·​·​·​}
138 ·​·​·​·​·​·​else137 ·​·​·​·​·​·​else
139 ·​·​·​·​·​·​{138 ·​·​·​·​·​·​{
140 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Second·​fork·​failed:​·​%m")​;​139 ·​·​·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Second·​fork·​failed:​·​%m")​;​
141 ·​·​·​·​·​·​·​·​return·​1;​140 ·​·​·​·​·​·​·​·​return·​1;​
142 ·​·​·​·​·​·​}141 ·​·​·​·​·​·​}
143 ·​·​·​·​}142 ·​·​·​·​}
144 143
145 ·​·​·​·​/​/​·​Close·​the·​standard·​streams.​·​This·​decouples·​the·​daemon·​from·​the·​terminal144 ·​·​·​·​/​/​·​Close·​the·​standard·​streams.​·​This·​decouples·​the·​daemon·​from·​the·​terminal
146 ·​·​·​·​/​/​·​that·​started·​it.​145 ·​·​·​·​/​/​·​that·​started·​it.​
147 ·​·​·​·​close(0)​;​146 ·​·​·​·​close(0)​;​
148 ·​·​·​·​close(1)​;​147 ·​·​·​·​close(1)​;​
149 ·​·​·​·​close(2)​;​148 ·​·​·​·​close(2)​;​
150 149
151 ·​·​·​·​/​/​·​We·​don't·​want·​the·​daemon·​to·​have·​any·​standard·​input.​150 ·​·​·​·​/​/​·​We·​don't·​want·​the·​daemon·​to·​have·​any·​standard·​input.​
152 ·​·​·​·​if·​(open("/​dev/​null",​·​O_RDONLY)​·​<·​0)​151 ·​·​·​·​if·​(open("/​dev/​null",​·​O_RDONLY)​·​<·​0)​
153 ·​·​·​·​{152 ·​·​·​·​{
154 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​open·​/​dev/​null:​·​%m")​;​153 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​open·​/​dev/​null:​·​%m")​;​
155 ·​·​·​·​·​·​return·​1;​154 ·​·​·​·​·​·​return·​1;​
156 ·​·​·​·​}155 ·​·​·​·​}
157 156
158 ·​·​·​·​/​/​·​Send·​standard·​output·​to·​a·​log·​file.​157 ·​·​·​·​/​/​·​Send·​standard·​output·​to·​a·​log·​file.​
159 ·​·​·​·​const·​char*·​output·​=·​"/​tmp/​asio.​daemon.​out";​158 ·​·​·​·​const·​char*·​output·​=·​"/​tmp/​asio.​daemon.​out";​
160 ·​·​·​·​const·​int·​flags·​=·​O_WRONLY·​|·​O_CREAT·​|·​O_APPEND;​159 ·​·​·​·​const·​int·​flags·​=·​O_WRONLY·​|·​O_CREAT·​|·​O_APPEND;​
161 ·​·​·​·​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;​
162 ·​·​·​·​if·​(open(output,​·​flags,​·​mode)​·​<·​0)​161 ·​·​·​·​if·​(open(output,​·​flags,​·​mode)​·​<·​0)​
163 ·​·​·​·​{162 ·​·​·​·​{
164 ·​·​·​·​·​·​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)​;​
165 ·​·​·​·​·​·​return·​1;​164 ·​·​·​·​·​·​return·​1;​
166 ·​·​·​·​}165 ·​·​·​·​}
167 166
168 ·​·​·​·​/​/​·​Also·​send·​standard·​error·​to·​the·​same·​log·​file.​167 ·​·​·​·​/​/​·​Also·​send·​standard·​error·​to·​the·​same·​log·​file.​
169 ·​·​·​·​if·​(dup(1)​·​<·​0)​168 ·​·​·​·​if·​(dup(1)​·​<·​0)​
170 ·​·​·​·​{169 ·​·​·​·​{
171 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​dup·​output·​descriptor:​·​%m")​;​170 ·​·​·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Unable·​to·​dup·​output·​descriptor:​·​%m")​;​
172 ·​·​·​·​·​·​return·​1;​171 ·​·​·​·​·​·​return·​1;​
173 ·​·​·​·​}172 ·​·​·​·​}
174 173
175 ·​·​·​·​/​/​·​Inform·​the·​io_context·​that·​we·​have·​finished·​becoming·​a·​daemon.​·​The174 ·​·​·​·​/​/​·​Inform·​the·​io_context·​that·​we·​have·​finished·​becoming·​a·​daemon.​·​The
176 ·​·​·​·​/​/​·​io_context·​uses·​this·​opportunity·​to·​create·​any·​internal·​file·​descriptors175 ·​·​·​·​/​/​·​io_context·​uses·​this·​opportunity·​to·​create·​any·​internal·​file·​descriptors
177 ·​·​·​·​/​/​·​that·​need·​to·​be·​private·​to·​the·​new·​process.​176 ·​·​·​·​/​/​·​that·​need·​to·​be·​private·​to·​the·​new·​process.​
178 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_child)​;​177 ·​·​·​·​io_context.​notify_fork(asio:​:​io_context:​:​fork_child)​;​
179 178
180 ·​·​·​·​/​/​·​The·​io_context·​can·​now·​be·​used·​normally.​179 ·​·​·​·​/​/​·​The·​io_context·​can·​now·​be·​used·​normally.​
181 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​started")​;​180 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​started")​;​
182 ·​·​·​·​io_context.​run()​;​181 ·​·​·​·​io_context.​run()​;​
183 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​stopped")​;​182 ·​·​·​·​syslog(LOG_INFO·​|·​LOG_USER,​·​"Daemon·​stopped")​;​
184 ·​·​}183 ·​·​}
185 ·​·​catch·​(std:​:​exception&·​e)​184 ·​·​catch·​(std:​:​exception&·​e)​
186 ·​·​{185 ·​·​{
187 ·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Exception:​·​%s",​·​e.​what()​)​;​186 ·​·​·​·​syslog(LOG_ERR·​|·​LOG_USER,​·​"Exception:​·​%s",​·​e.​what()​)​;​
188 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​std:​:​endl;​187 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​std:​:​endl;​
189 ·​·​}188 ·​·​}
190 }189 }