Changeset 97cdbaf5 for filterproc.c
- Timestamp:
- Mar 11, 2012, 10:57:35 PM (13 years ago)
- Branches:
- master, release-1.10, release-1.9
- Children:
- a03a409
- Parents:
- 1f39ded
- git-author:
- David Benjamin <davidben@mit.edu> (01/23/12 00:38:29)
- git-committer:
- David Benjamin <davidben@mit.edu> (03/11/12 22:57:35)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
filterproc.c
r1f39ded r97cdbaf5 3 3 #include <poll.h> 4 4 5 int send_receive(int rfd, int wfd, const char *out, char **in) 5 /* Even in case of error, send_receive is responsible for closing wfd 6 * (to EOF the child) and rfd (for consistency). */ 7 static int send_receive(int rfd, int wfd, const char *out, char **in) 6 8 { 7 9 GString *str = g_string_new(""); … … 21 23 if(!out || !*out) { 22 24 /* Nothing to write. Close our end so the child doesn't hang waiting. */ 23 close(wfd); 25 close(wfd); wfd = -1; 24 26 out = NULL; 25 27 } … … 46 48 } 47 49 if(!out || !*out || fds[1].revents & (POLLERR | POLLHUP)) { 48 close(wfd); 50 close(wfd); wfd = -1; 49 51 out = NULL; 50 52 } … … 62 64 } 63 65 66 if (wfd >= 0) close(wfd); 67 close(rfd); 64 68 *in = g_string_free(str, err < 0); 65 69 return err; 66 70 } 67 71 68 int call_filter(const char * prog, const char *const *argv, const char *in, char **out, int *status)72 int call_filter(const char *const *argv, const char *in, char **out, int *status) 69 73 { 70 int err = 0; 71 pid_t pid; 72 int rfd[2]; 73 int wfd[2]; 74 int err; 75 GPid child_pid; 76 int child_stdin, child_stdout; 74 77 75 if((err = pipe(rfd))) goto out; 76 if((err = pipe(wfd))) goto out_close_rfd; 77 78 pid = fork(); 79 if(pid < 0) { 80 err = pid; 81 goto out_close_all; 82 } 83 if(pid) { 84 /* parent */ 85 close(rfd[1]); 86 close(wfd[0]); 87 err = send_receive(rfd[0], wfd[1], in, out); 88 if(err == 0) { 89 waitpid(pid, status, 0); 90 } 91 } else { 92 /* child */ 93 close(rfd[0]); 94 close(wfd[1]); 95 dup2(rfd[1], 1); 96 dup2(wfd[0], 0); 97 close(rfd[1]); 98 close(wfd[0]); 99 100 if(execvp(prog, (char *const *)argv)) { 101 _exit(-1); 102 } 78 if (!g_spawn_async_with_pipes(NULL, (char**)argv, NULL, 79 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, 80 NULL, NULL, 81 &child_pid, &child_stdin, &child_stdout, NULL, 82 NULL)) { 83 return 1; 103 84 } 104 85 105 out_close_all: 106 close(wfd[0]); 107 close(wfd[1]); 108 out_close_rfd: 109 close(rfd[0]); 110 close(rfd[1]); 111 out: 86 err = send_receive(child_stdout, child_stdin, in, out); 87 if (err == 0) { 88 waitpid(child_pid, status, 0); 89 } 112 90 return err; 113 91 }
Note: See TracChangeset
for help on using the changeset viewer.