1 #include "child_process.h"
13 void ChildProcess::ParseCommandline(vector<char *> *args) {
14 char *p = commandline_;
17 // Find the start of a chunk.
18 while(*p && isspace(*p)) p++;
23 // Find the end of the chunk.
27 } else if (isspace(*p) && !in_quote) {
36 args->push_back(NULL);
39 static volatile bool _child_ready = false;
40 static void SignalHandler(int signo) {
45 void ChildProcess::Start() {
48 ParseCommandline(&args);
50 if (args.size() > 1) {
51 if (pipe(read_pipe_) != 0) {
55 if (pipe(write_pipe_) != 0) {
60 // Prepare a signal handler to tell us when the child process is
63 if (signal(SIGUSR1, SignalHandler) == SIG_ERR) {
67 sigset_t zeromask, mask, orig;
68 sigemptyset(&zeromask);
70 sigaddset(&mask, SIGUSR1);
71 if (sigprocmask(SIG_BLOCK, &mask, &orig) < 0) {
72 perror("sigprocmask");
83 printf("In the child process...\n");
85 // In the child process we do not need the pipes for parent
87 close(write_pipe_[1]);
89 if (dup2(write_pipe_[0], fileno(stdin)) < 0) {
93 close(write_pipe_[0]);
94 if (dup2(read_pipe_[1], fileno(stdout)) < 0) {
98 if (dup2(fileno(stdout), fileno(stderr)) < 0) {
102 close(read_pipe_[1]);
104 // Tell the parent that the pipes are set up then exec the child
106 kill(getppid(), SIGUSR1);
107 execvp(args[0], &(args[0]));
111 printf("In the parent process waiting...\n");
112 while(!_child_ready) {
113 sigsuspend(&zeromask);
115 printf("PARENT WAKEUP!\n");
116 _child_ready = false;
117 if (sigprocmask(SIG_SETMASK, &orig, NULL) < 0) {
118 perror("sigprocmask");
121 close(write_pipe_[0]);
122 close(read_pipe_[1]);
123 from_ = fdopen(read_pipe_[0], "r");
124 to_ = fdopen(write_pipe_[1], "w");
133 void ChildProcess::Stop() {
139 close(write_pipe_[1]);
140 close(read_pipe_[0]);
143 waitpid(pid_, &x, 0);
146 void ChildProcess::Send(char *line) {
150 fprintf(to_, "%s", line);
151 printf("%s sent: %s", name_, line);
154 void ChildProcess::Receive(char *line, int size) {
163 fgets(line, size, from_);
164 printf("%s recv: %s\n", name_, line);
167 bool ChildProcess::Poll() {
170 FD_SET(read_pipe_[0], &myset);
174 return select(read_pipe_[0] + 1, &myset, NULL, NULL, &mytime) > 0;
177 void ChildProcess::Flush() {
178 static char line[1000];
181 printf("flush: %s", line);