Annotation of researchv9/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,args,env)
                     21: char   *cmd;
                     22: char   *mode;
                     23: int    paranoid;
                     24: char   **args, **env;
                     25: {
                     26:        int p[2];
                     27:        register myside, hisside, pid;
                     28:        register i, ind;
                     29: 
                     30:        for (ind = 0; ind < MAXFORKS; ind++)
                     31:                if (the_fork[ind].pid == 0)
                     32:                        break;
                     33:        if (ind == MAXFORKS)
                     34:                return NULL;
                     35:        if(pipe(p) < 0)
                     36:                return NULL;
                     37:        myside = tst(p[WTR], p[RDR]);
                     38:        hisside = tst(p[RDR], p[WTR]);
                     39:        switch (pid = vfork()) {
                     40:        case -1:
                     41:                return NULL;
                     42:        case 0:
                     43:                /* myside and hisside reverse roles in child */
                     44:                close(myside);
                     45:                dup2(hisside, tst(0, 1));
                     46:                if (paranoid!=2) {
                     47:                        /* a hack for "safety" against incautious SUIDs */
                     48:                        setuid(getuid());
                     49:                        setgid(getgid());
                     50:                }
                     51:                for (i=NSYSFILE; i<_NFILE; i++)
                     52:                        close(i);
                     53:                if (paranoid==2)
                     54:                        execve(cmd, args, env);
                     55:                else if (paranoid==1)
                     56:                        execl("/bin/sh", "sh", "-c", "-p", cmd, 0);
                     57:                else
                     58:                        execl("/bin/sh", "sh", "-c", cmd, 0);
                     59:                _exit(1);
                     60:        default:
                     61:                the_fork[ind].pid = pid;
                     62:                the_fork[ind].fd = myside;
                     63:                the_fork[ind].done = 0;
                     64:                close(hisside);
                     65:                return(fdopen(myside, mode));
                     66:        }
                     67: }
                     68: 
                     69: FILE *
                     70: popen(cmd,mode)
                     71: char   *cmd;
                     72: char   *mode;
                     73: {
                     74:        return _popen(cmd, mode, 0, (char **)NULL, (char **)NULL);
                     75: }
                     76: 
                     77: FILE *
                     78: ppopen(cmd,mode)
                     79: char   *cmd;
                     80: char   *mode;
                     81: {
                     82:        return _popen(cmd, mode, 1, (char **)NULL, (char **)NULL);
                     83: }
                     84: 
                     85: FILE *
                     86: vepopen(cmd,mode,args,env)
                     87: char   *cmd;
                     88: char   *mode;
                     89: char   **args;
                     90: char   **env;
                     91: {
                     92:        return(_popen(cmd, mode, 2, args, env));
                     93: }
                     94: 
                     95: pclose(ptr)
                     96: FILE *ptr;
                     97: {
                     98:        register f, r, ind, (*hstat)(), (*istat)(), (*qstat)();
                     99:        int status;
                    100: 
                    101:        f = fileno(ptr);
                    102:        fclose(ptr);
                    103:        for (ind = 0; ind < MAXFORKS; ind++)
                    104:                if (the_fork[ind].fd == f && the_fork[ind].pid != 0)
                    105:                        break;
                    106:        if (ind == MAXFORKS)
                    107:                return 0;
                    108:        if (!the_fork[ind].done) {
                    109:                istat = signal(SIGINT, SIG_IGN);
                    110:                qstat = signal(SIGQUIT, SIG_IGN);
                    111:                hstat = signal(SIGHUP, SIG_IGN);
                    112:                do {
                    113:                        r = wait(&status);
                    114:                        for (f = 0; f < MAXFORKS; f++)
                    115:                                if (the_fork[f].pid == r) {
                    116:                                        the_fork[f].done = 1;
                    117:                                        the_fork[f].status = status;
                    118:                                        break;
                    119:                                }
                    120:                } while(r != the_fork[ind].pid && r != -1);
                    121:                the_fork[ind].status = r == -1 ? -1 : status;
                    122:                signal(SIGINT, istat);
                    123:                signal(SIGQUIT, qstat);
                    124:                signal(SIGHUP, hstat);
                    125:        }
                    126:        the_fork[ind].pid = 0;
                    127:        return (the_fork[ind].status);
                    128: }

unix.superglobalmegacorp.com

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