|
|
1.1 ! root 1: /* ! 2: * Standard I/O library ! 3: * Make streams to or from a process. ! 4: * ! 5: * Modified for use with the COHERENT mail system. ! 6: * This version of popen closes all file descriptors ! 7: * above 2 (stderr) in the child process. ! 8: */ ! 9: ! 10: #include <stdio.h> ! 11: #include <signal.h> ! 12: ! 13: #define R 0 /* Pipe read descriptor index */ ! 14: #define W 1 /* Pipe write descriptor index */ ! 15: ! 16: void close_fds(); ! 17: ! 18: static int poppid[_NFILE]; ! 19: ! 20: FILE * ! 21: popen(command, type) ! 22: char *command, *type; ! 23: { ! 24: register mode; ! 25: register fd; ! 26: int pd[2]; ! 27: ! 28: if (pipe(pd) < 0) ! 29: return (NULL); ! 30: if (*type == 'w') { ! 31: mode = W; ! 32: fd = pd[W]; ! 33: } else { ! 34: mode = R; ! 35: fd = pd[R]; ! 36: } ! 37: if ((poppid[fd] = fork()) < 0) { ! 38: close(pd[R]); ! 39: close(pd[W]); ! 40: return (NULL); ! 41: } ! 42: if (poppid[fd] == 0) { /* Child */ ! 43: if (mode == W) { ! 44: close(pd[W]); ! 45: close(fileno(stdin)); ! 46: dup(pd[R]); ! 47: close(pd[R]); ! 48: } else { ! 49: close(pd[R]); ! 50: close(fileno(stdout)); ! 51: dup(pd[W]); ! 52: close(pd[W]); ! 53: } ! 54: ! 55: /* Clean up any file descriptors which may be laying around. */ ! 56: close_fds(); ! 57: ! 58: execl("/bin/sh", "sh", "-c", command, NULL); ! 59: exit(1); ! 60: } ! 61: if (mode == W) { ! 62: close(pd[R]); ! 63: return (fdopen(pd[W], "w")); ! 64: } else { ! 65: close(pd[W]); ! 66: return (fdopen(pd[R], "r")); ! 67: } ! 68: } ! 69: ! 70: pclose(stream) ! 71: FILE *stream; ! 72: { ! 73: register fd; ! 74: register pid, wpid; ! 75: int status; ! 76: int (*hupfun)(), (*intfun)(), (*quitfun)(); ! 77: ! 78: fd = fileno(stream); ! 79: pid = poppid[fd]; ! 80: poppid[fd] = 0; ! 81: if (pid==0 || fclose(stream)==EOF) ! 82: return (-1); ! 83: hupfun = signal(SIGHUP, SIG_IGN); ! 84: intfun = signal(SIGINT, SIG_IGN); ! 85: quitfun = signal(SIGQUIT, SIG_IGN); ! 86: while ((wpid = wait(&status))!=pid && wpid>=0) ! 87: ; ! 88: if (wpid < 0) ! 89: status = -1; ! 90: signal(SIGHUP, hupfun); ! 91: signal(SIGINT, intfun); ! 92: signal(SIGQUIT, quitfun); ! 93: return (status); ! 94: } ! 95: ! 96: /* Close all file descriptors above 2 (stderr). */ ! 97: void ! 98: close_fds() ! 99: { ! 100: int fd; ! 101: for (fd = fileno(stderr) + 1; fd <= _NFILE; ++fd) { ! 102: (void) close(fd); ! 103: } /* for fd = stderr to number_of_file_descriptors */ ! 104: } /* close_fds() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.