diff options
Diffstat (limited to 'process.cpp')
-rw-r--r-- | process.cpp | 80 |
1 files changed, 66 insertions, 14 deletions
diff --git a/process.cpp b/process.cpp index d245449..41325c3 100644 --- a/process.cpp +++ b/process.cpp @@ -52,9 +52,11 @@ void Process::run() { dup2(child_out, STDOUT_FILENO); close(infd); close(outfd); + close(child_in); + close(child_out); execlp(execname.data(), execname.data(), NULL); - cerr << endl << "ERROR: Error executing player file '" << execname << "'" << endl; + cout << endl << "ERROR: Error executing player file '" << execname << "'" << endl; exit(255); } @@ -63,19 +65,58 @@ void Process::run() { close(child_out); } -void Process::wait() { - if (pid == -1) return; +int Process::waitPoll() { + if (pid == -1) return exitStatus; + + while (true) { + int status; + int ret = waitpid(pid, &status, WNOHANG); + if (ret < 0) { + if (errno == ECHILD) return exitStatus; + perror("waitpid"); + return -1; + } + if (ret == 0) { + // Nothing changed yet + return -1; + } + + if (WIFEXITED(status)) { + cleanup(); + exitStatus = WEXITSTATUS(status); + return exitStatus; + } + + if (WIFSIGNALED(status)) { + cleanup(); + exitStatus = 1000 + WTERMSIG(status); + return exitStatus; + } + } +} + +int Process::wait() { + if (pid == -1) return exitStatus; + while (true) { int status; if (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; - if (errno == ECHILD) break; + if (errno == ECHILD) return exitStatus; perror("waitpid"); - break; + return -1; } + if (WIFEXITED(status)) { - pid = -1; - break; + cleanup(); + exitStatus = WEXITSTATUS(status); + return exitStatus; + } + + if (WIFSIGNALED(status)) { + cleanup(); + exitStatus = 1000 + WTERMSIG(status); + return exitStatus; } } } @@ -101,7 +142,7 @@ bool Process::writeLine(const string_view line) { ssize_t nw = write(infd, str.data() + cursor, str.size() - cursor); if (nw < 0) { if (errno == EINTR) continue; - perror("write"); + // perror("write"); return false; } cursor += nw; @@ -112,7 +153,7 @@ bool Process::writeLine(const string_view line) { optional<string> Process::readLine() { if (pid == -1) { - cerr << "-- readLine on pid==-1 --" << endl; + cout << "-- readLine on pid==-1 --" << endl; return nullopt; } @@ -132,7 +173,7 @@ optional<string> Process::readLine() { return nullopt; } if (nr == 0) { // EOF - cerr << "-- eof in readLine --" << endl; + cout << "-- eof in readLine --" << endl; return nullopt; } s.resize(nr); @@ -148,16 +189,27 @@ optional<string> Process::readLine() { } } -void Process::terminate() { +int Process::terminate() { // TODO: send only SIGTERM, then wait a little while, then send // SIGKILL if necessary if (pid != -1) { - kill(pid, SIGKILL); // force kill - wait(); - pid = -1; + int ret = waitPoll(); + if (ret == -1) { + kill(pid, SIGKILL); // force kill + ret = wait(); + } + cleanup(); + return ret; } + return exitStatus; } pid_t Process::getPid() const { return pid; } + +void Process::cleanup() { + pid = -1; + close(infd); + close(outfd); +} |