@@ -32,6 +32,53 @@ WorkshopControlChannelServer::InvokeTemporaryError(const char *msg) noexcept
3232 handler.OnControlTemporaryError (std::make_exception_ptr (std::runtime_error (msg)));
3333}
3434
35+ inline bool
36+ WorkshopControlChannelServer::OnSpawn (std::vector<std::string> &&args)
37+ {
38+ if (args.size () < 2 || args.size () > 3 ) {
39+ InvokeTemporaryError (" malformed 'spawn' command on control channel" );
40+ return true ;
41+ }
42+
43+ const char *token = args[1 ].c_str ();
44+ const char *param = args.size () >= 3
45+ ? args[2 ].c_str ()
46+ : nullptr ;
47+
48+ try {
49+ auto pidfd = handler.OnControlSpawn (token, param);
50+ assert (pidfd.IsDefined ());
51+
52+ const struct iovec v[]{MakeIovec (AsBytes (" ok" sv))};
53+ MessageHeader msg{std::span{v}};
54+ ScmRightsBuilder<1 > b (msg);
55+
56+ b.push_back (pidfd.Get ());
57+
58+ b.Finish (msg);
59+ SendMessage (socket.GetSocket (), msg, MSG_NOSIGNAL);
60+ } catch (...) {
61+ const auto msg = GetFullMessage (std::current_exception ());
62+ InvokeTemporaryError (msg.c_str ());
63+
64+ const struct iovec v[] = {
65+ MakeIovec (AsBytes (" error " sv)),
66+ MakeIovec (AsBytes (msg)),
67+ };
68+
69+ try {
70+ SendMessage (socket.GetSocket (), MessageHeader{v},
71+ MSG_NOSIGNAL);
72+ } catch (...) {
73+ socket.Close ();
74+ handler.OnControlPermanentError (std::current_exception ());
75+ return false ;
76+ }
77+ }
78+
79+ return true ;
80+ }
81+
3582inline bool
3683WorkshopControlChannelServer::OnControl (std::vector<std::string> &&args) noexcept
3784{
@@ -87,48 +134,7 @@ WorkshopControlChannelServer::OnControl(std::vector<std::string> &&args) noexcep
87134 (void )socket.GetSocket ().WriteNoWait (AsBytes (payload));
88135 return true ;
89136 } else if (cmd == " spawn" sv) {
90- if (args.size () < 2 || args.size () > 3 ) {
91- InvokeTemporaryError (" malformed 'spawn' command on control channel" );
92- return true ;
93- }
94-
95- const char *token = args[1 ].c_str ();
96- const char *param = args.size () >= 3
97- ? args[2 ].c_str ()
98- : nullptr ;
99-
100- try {
101- auto pidfd = handler.OnControlSpawn (token, param);
102- assert (pidfd.IsDefined ());
103-
104- const struct iovec v[]{MakeIovec (AsBytes (" ok" sv))};
105- MessageHeader msg{std::span{v}};
106- ScmRightsBuilder<1 > b (msg);
107-
108- b.push_back (pidfd.Get ());
109-
110- b.Finish (msg);
111- SendMessage (socket.GetSocket (), msg, MSG_NOSIGNAL);
112- } catch (...) {
113- const auto msg = GetFullMessage (std::current_exception ());
114- InvokeTemporaryError (msg.c_str ());
115-
116- const struct iovec v[] = {
117- MakeIovec (AsBytes (" error " sv)),
118- MakeIovec (AsBytes (msg)),
119- };
120-
121- try {
122- SendMessage (socket.GetSocket (), MessageHeader{v},
123- MSG_NOSIGNAL);
124- } catch (...) {
125- socket.Close ();
126- handler.OnControlPermanentError (std::current_exception ());
127- return false ;
128- }
129- }
130-
131- return true ;
137+ return OnSpawn (std::move (args));
132138 } else {
133139 InvokeTemporaryError (" unknown command on control channel" );
134140 return true ;
0 commit comments