Annotation of coherent/a/tmp/smail/popen.c, revision 1.1.1.1

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() */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.