Annotation of researchv8dc/libc/stdio/popen.c, revision 1.1.1.1

1.1       root        1: /* @(#)popen.c 4.1 (Berkeley) 12/21/80 */
                      2: #include <stdio.h>
                      3: #include <signal.h>
                      4: #include <sys/param.h>
                      5: 
                      6: #define MAXFORKS       20
                      7: #define        tst(a,b)        (*mode == 'r'? (b) : (a))
                      8: #define        RDR     0
                      9: #define        WTR     1
                     10: 
                     11: struct a_fork {
                     12:        short   done;
                     13:        short   fd;
                     14:        int     pid;
                     15:        int     status;
                     16: };
                     17: static struct a_fork the_fork[MAXFORKS];
                     18: 
                     19: static FILE *
                     20: _popen(cmd,mode,paranoid)
                     21: char   *cmd;
                     22: char   *mode;
                     23: int    paranoid;
                     24: {
                     25:        int p[2];
                     26:        register myside, hisside, pid;
                     27:        register i, ind;
                     28: 
                     29:        for (ind = 0; ind < MAXFORKS; ind++)
                     30:                if (the_fork[ind].pid == 0)
                     31:                        break;
                     32:        if (ind == MAXFORKS)
                     33:                return NULL;
                     34:        if(pipe(p) < 0)
                     35:                return NULL;
                     36:        myside = tst(p[WTR], p[RDR]);
                     37:        hisside = tst(p[RDR], p[WTR]);
                     38:        switch (pid = vfork()) {
                     39:        case -1:
                     40:                return NULL;
                     41:        case 0:
                     42:                /* myside and hisside reverse roles in child */
                     43:                close(myside);
                     44:                dup2(hisside, tst(0, 1));
                     45:                setuid(getuid());
                     46:                setgid(getgid());
                     47:                for (i=NSYSFILE; i<_NFILE; i++)
                     48:                        close(i);
                     49:                if (paranoid)
                     50:                        execl("/bin/sh", "sh", "-c", "-p", cmd, 0);
                     51:                else
                     52:                        execl("/bin/sh", "sh", "-c", cmd, 0);
                     53:                _exit(1);
                     54:        default:
                     55:                the_fork[ind].pid = pid;
                     56:                the_fork[ind].fd = myside;
                     57:                the_fork[ind].done = 0;
                     58:                close(hisside);
                     59:                return(fdopen(myside, mode));
                     60:        }
                     61: }
                     62: 
                     63: FILE *
                     64: popen(cmd,mode)
                     65: char   *cmd;
                     66: char   *mode;
                     67: {
                     68:        return _popen(cmd, mode, 0);
                     69: }
                     70: 
                     71: FILE *
                     72: ppopen(cmd,mode)
                     73: char   *cmd;
                     74: char   *mode;
                     75: {
                     76:        return _popen(cmd, mode, 1);
                     77: }
                     78: 
                     79: pclose(ptr)
                     80: FILE *ptr;
                     81: {
                     82:        register f, r, ind, (*hstat)(), (*istat)(), (*qstat)();
                     83:        int status;
                     84: 
                     85:        f = fileno(ptr);
                     86:        fclose(ptr);
                     87:        for (ind = 0; ind < MAXFORKS; ind++)
                     88:                if (the_fork[ind].fd == f && the_fork[ind].pid != 0)
                     89:                        break;
                     90:        if (ind == MAXFORKS)
                     91:                return 0;
                     92:        if (!the_fork[ind].done) {
                     93:                istat = signal(SIGINT, SIG_IGN);
                     94:                qstat = signal(SIGQUIT, SIG_IGN);
                     95:                hstat = signal(SIGHUP, SIG_IGN);
                     96:                do {
                     97:                        r = wait(&status);
                     98:                        for (f = 0; f < MAXFORKS; f++)
                     99:                                if (the_fork[f].pid == r) {
                    100:                                        the_fork[f].done = 1;
                    101:                                        the_fork[f].status = status;
                    102:                                        break;
                    103:                                }
                    104:                } while(r != the_fork[ind].pid && r != -1);
                    105:                the_fork[ind].status = r == -1 ? -1 : status;
                    106:                signal(SIGINT, istat);
                    107:                signal(SIGQUIT, qstat);
                    108:                signal(SIGHUP, hstat);
                    109:        }
                    110:        the_fork[ind].pid = 0;
                    111:        return (the_fork[ind].status);
                    112: }

unix.superglobalmegacorp.com

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