Annotation of researchv10no/lbin/mailx/popen.c, revision 1.1.1.1

1.1       root        1: #ident "@(#)popen.c    1.3 'attmail mail(1) command'"
                      2: #ident "@(#)mailx:popen.c      1.4.1.1"
                      3: /*     Copyright (c) 1984 AT&T */
                      4: /*       All Rights Reserved   */
                      5: 
                      6: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
                      7: /*     The copyright notice above does not evidence any        */
                      8: /*     actual or intended publication of such source code.     */
                      9: 
                     10: #ident "@(#)mailx:popen.c      1.4"
                     11: /*
                     12:  * mailx -- a modified version of a University of California at Berkeley
                     13:  *     mail program
                     14:  *
                     15:  * npopen() and npclose()
                     16:  *
                     17:  * stolen from C library, modified to use SHELL variable
                     18:  */
                     19: /*
                     20:  * adb
                     21:  * entirely replaced with code stolen from V9 stdio library
                     22:  *
                     23:  */
                     24: 
                     25: #include <stdio.h>
                     26: #include <signal.h>
                     27: #include <sys/param.h>
                     28: 
                     29: #ifndef NSYSFILE
                     30: #define NSYSFILE       4
                     31: #endif
                     32: 
                     33: #define MAXFORKS       20
                     34: #define        tst(a,b)        (*mode == 'r'? (b) : (a))
                     35: #define        RDR     0
                     36: #define        WTR     1
                     37: 
                     38: struct a_fork {
                     39:        short   done;
                     40:        short   fd;
                     41:        int     pid;
                     42:        int     status;
                     43: };
                     44: static struct a_fork the_fork[MAXFORKS];
                     45: 
                     46: static FILE *
                     47: _popen(cmd,mode,paranoid,args,env)
                     48: char   *cmd;
                     49: char   *mode;
                     50: int    paranoid;
                     51: char   **args, **env;
                     52: {
                     53:        int p[2];
                     54:        register myside, hisside, pid;
                     55:        register i, ind;
                     56:        char *Shell, *value();
                     57: 
                     58:        if ((Shell = value("SHELL")) == NULL || *Shell=='\0')
                     59:                Shell = "/bin/sh";
                     60: 
                     61:        for (ind = 0; ind < MAXFORKS; ind++)
                     62:                if (the_fork[ind].pid == 0)
                     63:                        break;
                     64:        if (ind == MAXFORKS)
                     65:                return NULL;
                     66:        if(pipe(p) < 0)
                     67:                return NULL;
                     68:        myside = tst(p[WTR], p[RDR]);
                     69:        hisside = tst(p[RDR], p[WTR]);
                     70:        switch (pid = fork()) {
                     71:        case -1:
                     72:                return NULL;
                     73:        case 0:
                     74:                /* myside and hisside reverse roles in child */
                     75:                close(myside);
                     76:                dup2(hisside, tst(0, 1));
                     77:                if (paranoid!=2) {
                     78:                        /* a hack for "safety" against incautious SUIDs */
                     79:                        setuid(getuid());
                     80:                        setgid(getgid());
                     81:                }
                     82:                for (i=NSYSFILE; i<_NFILE; i++)
                     83:                        close(i);
                     84:                if (paranoid==2)
                     85:                        execve(cmd, args, env);
                     86:                else if (paranoid==1)
                     87:                        execl(Shell, "sh", "-c", "-p", cmd, 0);
                     88:                else
                     89:                        execl(Shell, "sh", "-c", cmd, 0);
                     90:                _exit(1);
                     91:        default:
                     92:                the_fork[ind].pid = pid;
                     93:                the_fork[ind].fd = myside;
                     94:                the_fork[ind].done = 0;
                     95:                close(hisside);
                     96:                return(fdopen(myside, mode));
                     97:        }
                     98: }
                     99: 
                    100: FILE *
                    101: npopen(cmd,mode)
                    102: char   *cmd;
                    103: char   *mode;
                    104: {
                    105:        return _popen(cmd, mode, 0, (char **)NULL, (char **)NULL);
                    106: }
                    107: 
                    108: npclose(ptr)
                    109: FILE *ptr;
                    110: {
                    111:        register f, r, ind;
                    112:        register void (*hstat)(), (*istat)(), (*qstat)();
                    113:        int status;
                    114: 
                    115:        f = fileno(ptr);
                    116:        fclose(ptr);
                    117:        for (ind = 0; ind < MAXFORKS; ind++)
                    118:                if (the_fork[ind].fd == f && the_fork[ind].pid != 0)
                    119:                        break;
                    120:        if (ind == MAXFORKS)
                    121:                return 0;
                    122:        if (!the_fork[ind].done) {
                    123:                istat = (void (*)())signal(SIGINT,  SIG_IGN);
                    124:                qstat = (void (*)())signal(SIGQUIT, SIG_IGN);
                    125:                hstat = (void (*)())signal(SIGHUP, SIG_IGN);
                    126:                do {
                    127:                        r = wait(&status);
                    128:                        for (f = 0; f < MAXFORKS; f++)
                    129:                                if (the_fork[f].pid == r) {
                    130:                                        the_fork[f].done = 1;
                    131:                                        the_fork[f].status = status;
                    132:                                        break;
                    133:                                }
                    134:                } while(r != the_fork[ind].pid && r != -1);
                    135:                the_fork[ind].status = r == -1 ? -1 : status;
                    136:                signal(SIGINT, istat);
                    137:                signal(SIGQUIT, qstat);
                    138:                signal(SIGHUP, hstat);
                    139:        }
                    140:        the_fork[ind].pid = 0;
                    141:        return (the_fork[ind].status);
                    142: }

unix.superglobalmegacorp.com

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