Changeset 34132f7 for filterproc.c
- Timestamp:
- Mar 11, 2012, 10:34:18 PM (13 years ago)
- Branches:
- release-1.8
- Children:
- 6a08f16
- Parents:
- 4a80a16
- git-author:
- David Benjamin <davidben@mit.edu> (01/23/12 00:38:29)
- git-committer:
- David Benjamin <davidben@mit.edu> (03/11/12 22:34:18)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
filterproc.c
r4a80a16 r34132f7 10 10 #include <glib.h> 11 11 12 int send_receive(int rfd, int wfd, const char *out, char **in) 12 /* Even in case of error, send_receive is responsible for closing wfd 13 * (to EOF the child) and rfd (for consistency). */ 14 static int send_receive(int rfd, int wfd, const char *out, char **in) 13 15 { 14 16 GString *str = g_string_new(""); … … 28 30 if(!out || !*out) { 29 31 /* Nothing to write. Close our end so the child doesn't hang waiting. */ 30 close(wfd); 32 close(wfd); wfd = -1; 31 33 out = NULL; 32 34 } … … 53 55 } 54 56 if(!out || !*out || fds[1].revents & (POLLERR | POLLHUP)) { 55 close(wfd); 57 close(wfd); wfd = -1; 56 58 out = NULL; 57 59 } … … 69 71 } 70 72 73 if (wfd >= 0) close(wfd); 74 close(rfd); 71 75 *in = g_string_free(str, err < 0); 72 76 return err; 73 77 } 74 78 75 int call_filter(const char * prog, const char *const *argv, const char *in, char **out, int *status)79 int call_filter(const char *const *argv, const char *in, char **out, int *status) 76 80 { 77 int err = 0; 78 pid_t pid; 79 int rfd[2]; 80 int wfd[2]; 81 int err; 82 GPid child_pid; 83 int child_stdin, child_stdout; 81 84 82 if((err = pipe(rfd))) goto out; 83 if((err = pipe(wfd))) goto out_close_rfd; 84 85 pid = fork(); 86 if(pid < 0) { 87 err = pid; 88 goto out_close_all; 89 } 90 if(pid) { 91 /* parent */ 92 close(rfd[1]); 93 close(wfd[0]); 94 err = send_receive(rfd[0], wfd[1], in, out); 95 if(err == 0) { 96 waitpid(pid, status, 0); 97 } 98 } else { 99 /* child */ 100 close(rfd[0]); 101 close(wfd[1]); 102 dup2(rfd[1], 1); 103 dup2(wfd[0], 0); 104 close(rfd[1]); 105 close(wfd[0]); 106 107 if(execvp(prog, (char *const *)argv)) { 108 _exit(-1); 109 } 85 if (!g_spawn_async_with_pipes(NULL, (char**)argv, NULL, 86 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, 87 NULL, NULL, 88 &child_pid, &child_stdin, &child_stdout, NULL, 89 NULL)) { 90 return 1; 110 91 } 111 92 112 out_close_all: 113 close(wfd[0]); 114 close(wfd[1]); 115 out_close_rfd: 116 close(rfd[0]); 117 close(rfd[1]); 118 out: 93 err = send_receive(child_stdout, child_stdin, in, out); 94 if (err == 0) { 95 waitpid(child_pid, status, 0); 96 } 119 97 return err; 120 98 }
Note: See TracChangeset
for help on using the changeset viewer.