e5ef5ead68b12e4ddafb4e510941763f750c226d
2 #include "Connection.hpp"
3 #include "ForkAndExec.hpp"
8 Server::Server(string binary_
, Server::argv_t args_
)
9 : binary
{move(binary_
)}
16 if (holds_alternative
<string
>(socket_or_port
)) {
17 unlink(get
<string
>(socket_or_port
).c_str());
21 static inline string
extractArg(const Server::arg_t
&arg_cont
, const string
&func_arg
) {
22 if (holds_alternative
<string
>(arg_cont
)) {
23 return get
<string
>(arg_cont
);
25 return get
<Server::arg_func_t
>(arg_cont
)(func_arg
);
29 static inline void pushArg(vector
<char *> &arr
, const string
&arg
) {
30 auto len
= arg
.size();
31 auto str
= arg
.data(), end
= str
+ len
+ 1;
32 auto ptr
= new char[len
+ 1];
37 optional
<string
> Server::handleArg(vector
<char *> &arr
, const string
&arg
, const arg_func_t
&next_arg
) {
39 if (arg
== "-p" || arg
== "--port") {
40 auto port
= next_arg(arg
);
44 socket_or_port
= stoi(port
);
46 } else if (arg
== "-s" || arg
== "--unix-socket") {
47 auto sock
= next_arg(arg
);
49 socket_or_port
= sock
;
56 vector
<char *> Server::createArgv() {
62 for (auto it
= args
.cbegin(); it
!= args
.cend(); ++it
) {
63 if (holds_alternative
<arg_t
>(*it
)) {
65 auto arg
= extractArg(get
<arg_t
>(*it
), binary
);
66 handleArg(arr
, arg
, [&it
](const string
&arg_
) {
67 return extractArg(get
<arg_t
>(*++it
), arg_
);
71 auto &[one
, two
] = get
<arg_pair_t
>(*it
);
72 auto arg_one
= extractArg(one
, binary
);
73 auto arg_two
= extractArg(two
, arg_one
);
75 auto next
= handleArg(arr
, arg_one
, [&arg_two
](const string
&) {
79 if (!next
.has_value()) {
80 pushArg(arr
, arg_two
);
85 arr
.push_back(nullptr);
90 optional
<pid_t
> Server::start() {
95 auto argv
= createArgv();
96 auto child
= ForkAndExec
{binary
.c_str(), argv
.data()}();
98 for (auto argp
: argv
) {
102 if (child
.has_value()) {
109 bool Server::isListening() {
110 Connection
conn(socket_or_port
);
115 return conn
.isOpen();
118 bool Server::stop() {
122 if (signalled
[SIGTERM
]) {
123 return signal(SIGKILL
);
125 return signal(SIGTERM
);
129 bool Server::signal(int signo
) {
133 signalled
[signo
] += 1;
134 return 0 <= kill(pid
, signo
);
137 bool Server::check() {
141 bool Server::wait(int flags
) {
142 if (pid
&& pid
== waitpid(pid
, &status
, flags
)) {
149 bool Server::tryWait() {
150 return wait(WNOHANG
);
153 Server::Server(const Server
&s
) {
156 socket_or_port
= s
.socket_or_port
;
159 Server
&Server::operator=(const Server
&s
) {
162 socket_or_port
= s
.socket_or_port
;
166 pid_t
Server::getPid() const {
170 const string
&Server::getBinary() const {
174 const Server::argv_t
&Server::getArgs() const {
178 const socket_or_port_t
&Server::getSocketOrPort() const {
179 return socket_or_port
;