diff options
Diffstat (limited to 'src/autoplay/child_process.cc')
| -rw-r--r-- | src/autoplay/child_process.cc | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/src/autoplay/child_process.cc b/src/autoplay/child_process.cc deleted file mode 100644 index 6486a0e..0000000 --- a/src/autoplay/child_process.cc +++ /dev/null @@ -1,188 +0,0 @@ -#include "child_process.h" - -#include <vector> -#include <cstdio> -#include <cstdlib> -#include <unistd.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> - -namespace util { - -void ChildProcess::ParseCommandline(vector<char *> *args) { - char *p = commandline_; - bool in_quote; - do { - // Find the start of a chunk. - while(*p && isspace(*p)) p++; - if (!*p) break; - args->push_back(p); - in_quote = false; - - // Find the end of the chunk. - while (*p) { - if (*p == '"') { - in_quote = !in_quote; - } else if (isspace(*p) && !in_quote) { - break; - } - p++; - } - if (!*p) break; - *p = '\0'; - p++; - } while(1); - args->push_back(NULL); -} - -static volatile bool _child_ready = false; -static void SignalHandler(int signo) { - printf("SIGNAL!\n"); - _child_ready = true; -} - -void ChildProcess::Start() { - Stop(); - vector<char *> args; - ParseCommandline(&args); - - if (args.size() > 1) { - if (pipe(read_pipe_) != 0) { - perror("pipe"); - exit(-1); - } - if (pipe(write_pipe_) != 0) { - perror("pipe"); - exit(-1); - } - - // Prepare a signal handler to tell us when the child process is - // ready. - _child_ready = false; - if (signal(SIGUSR1, SignalHandler) == SIG_ERR) { - perror("signal"); - exit(-1); - } - sigset_t zeromask, mask, orig; - sigemptyset(&zeromask); - sigemptyset(&mask); - sigaddset(&mask, SIGUSR1); - if (sigprocmask(SIG_BLOCK, &mask, &orig) < 0) { - perror("sigprocmask"); - exit(-1); - } - - // Fork. - pid_ = fork(); - if (pid_ < 0) { - perror("fork"); - exit(-1); - } - if (pid_ == 0) { - printf("In the child process...\n"); - - // In the child process we do not need the pipes for parent - // reads and writes. - close(write_pipe_[1]); - close(read_pipe_[0]); - if (dup2(write_pipe_[0], fileno(stdin)) < 0) { - perror("dup2"); - exit(-1); - } - close(write_pipe_[0]); - if (dup2(read_pipe_[1], fileno(stdout)) < 0) { - perror("dup2"); - exit(-1); - } - if (dup2(fileno(stdout), fileno(stderr)) < 0) { - perror("dup2"); - exit(-1); - } - close(read_pipe_[1]); - - // Tell the parent that the pipes are set up then exec the child - // image. - kill(getppid(), SIGUSR1); - execvp(args[0], &(args[0])); - perror("exec"); - exit(-1); - } else { - printf("In the parent process waiting...\n"); - while(!_child_ready) { - sigsuspend(&zeromask); - } - printf("PARENT WAKEUP!\n"); - _child_ready = false; - if (sigprocmask(SIG_SETMASK, &orig, NULL) < 0) { - perror("sigprocmask"); - exit(-1); - } - close(write_pipe_[0]); - close(read_pipe_[1]); - from_ = fdopen(read_pipe_[0], "r"); - to_ = fdopen(write_pipe_[1], "w"); - setbuf(from_, NULL); - setbuf(to_, NULL); - running_ = true; - name_ = args[0]; - } - } -} - -void ChildProcess::Stop() { - if (!running_) { - return; - } - fclose(to_); - fclose(from_); - close(write_pipe_[1]); - close(read_pipe_[0]); - kill(pid_, SIGTERM); - int x; - waitpid(pid_, &x, 0); -} - -void ChildProcess::Send(char *line) { - if (!running_) { - return; - } - fprintf(to_, "%s", line); - printf("%s sent: %s", name_, line); -} - -void ChildProcess::Receive(char *line, int size) { - if (!size) return; - *line = '\0'; - if (!running_) { - return; - } - if (!Poll()) { - return; - } - fgets(line, size, from_); - printf("%s recv: %s\n", name_, line); -} - -bool ChildProcess::Poll() { - fd_set myset; - FD_ZERO(&myset); - FD_SET(read_pipe_[0], &myset); - timeval mytime; - mytime.tv_sec = 0; - mytime.tv_usec = 0; - return select(read_pipe_[0] + 1, &myset, NULL, NULL, &mytime) > 0; -} - -void ChildProcess::Flush() { - static char line[1000]; - while (Poll()) { - Receive(line, 1000); - printf("flush: %s", line); - if (!line[0]) { - break; - } - } -} - -} // namespace |
