#include #include #include #include #include #ifdef __MINGW32__ #include #include #define pipe(fds) _pipe(fds, 4096, O_BINARY|O_NOINHERIT) #endif static FILE *do_popen(struct Popen *state, int wr, const char *program, const char **args) { int which = wr ? 0 : 1; const char *dir = wr ? "w" : "r"; int pfd, cfd; int pipe_fds[2]; const char *argv[2]; state->fp = NULL; state->pid = -1; if (pipe(pipe_fds) < 0) return NULL; cfd = pipe_fds[wr ? 0 : 1]; pfd = pipe_fds[wr ? 1 : 0]; if (!args) { argv[0] = program; argv[1] = NULL; args = argv; } state->pid = G_spawn_ex( program, SF_ARGVEC, args, SF_REDIRECT_DESCRIPTOR, which, cfd, SF_CLOSE_DESCRIPTOR, pfd, SF_BACKGROUND, NULL); if (state->pid == -1) { close(pipe_fds[0]); close(pipe_fds[1]); return NULL; } close(cfd); state->fp = fdopen(pfd, dir); return state->fp; } void G_popen_clear(struct Popen *state) { state->fp = NULL; state->pid = -1; } FILE *G_popen_write(struct Popen *state, const char *program, const char **args) { return do_popen(state, 1, program, args); } FILE *G_popen_read(struct Popen *state, const char *program, const char **args) { return do_popen(state, 0, program, args); } void G_popen_close(struct Popen *state) { if (state->fp) fclose(state->fp); if (state->pid != -1) G_wait(state->pid); }