Annotation of researchv10no/cmd/nupas/send/process.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <pwd.h>
                      3: #include <signal.h>
                      4: #include "mail.h"
                      5: #include "string.h"
                      6: #include "process.h"
                      7: 
                      8: /*
                      9:  *  the following is pretty safe because upas is very stingy
                     10:  *  in its file descriptor use.  system V fanatics should
                     11:  *  use the approriate system V system call to get the number
                     12:  *  of file descriptors
                     13:  */
                     14: #ifndef NOFILE
                     15: #define NOFILE 20
                     16: #endif
                     17: #ifndef NSYSFILE
                     18: #define NSYSFILE 3
                     19: #endif
                     20: 
                     21: extern char *malloc();
                     22: extern void exit();
                     23: extern char *getenv();
                     24: 
                     25: /* make a stream to a child process */
                     26: extern stream *
                     27: instream()
                     28: {
                     29:        stream *rv;
                     30:        int pfd[2];
                     31: 
                     32:        if ((rv = (stream *)malloc(sizeof(stream))) == NULL)
                     33:                return NULL;
                     34:        if (pipe(pfd) < 0)
                     35:                return NULL;
                     36:        if ((rv->fp = fdopen(pfd[1], "w")) == NULL){
                     37:                close(pfd[0]);
                     38:                close(pfd[1]);
                     39:                return NULL;
                     40:        }
                     41:        rv->fd = pfd[0];        
                     42:        return rv;
                     43: }
                     44: 
                     45: /* make a stream from a child process */
                     46: extern stream *
                     47: outstream()
                     48: {
                     49:        stream *rv;
                     50:        int pfd[2];
                     51: 
                     52:        if ((rv = (stream *)malloc(sizeof(stream))) == NULL)
                     53:                return NULL;
                     54:        if (pipe(pfd) < 0)
                     55:                return NULL;
                     56:        if ((rv->fp = fdopen(pfd[0], "r")) == NULL){
                     57:                close(pfd[0]);
                     58:                close(pfd[1]);
                     59:                return NULL;
                     60:        }
                     61:        rv->fd = pfd[1];        
                     62:        return rv;
                     63: }
                     64: 
                     65: extern void
                     66: stream_free(sp)
                     67:        stream *sp;
                     68: {
                     69:        close(sp->fd);
                     70:        fclose(sp->fp);
                     71:        free((char *)sp);
                     72: }
                     73: 
                     74: static char *env[] = { "IFS= \t\n", 0, 0, 0, 0 };
                     75: static string *spath;
                     76: static string *home;
                     77: static string *tz;
                     78: 
                     79: /* start a new process */
                     80: extern process *
                     81: proc_start(cmd, inp, outp, errp, uid)
                     82:        char *cmd;                      /* command to run */
                     83:        stream *inp, *outp, *errp;      /* streams to be used */
                     84: {
                     85:        struct passwd *pw;
                     86:        process *pp;
                     87:        int i;
                     88:        char *tzp;
                     89: 
                     90:        if ((pp = (process *)malloc(sizeof(process))) == NULL) {
                     91:                if (inp != NULL)
                     92:                        stream_free(inp);
                     93:                if (outp != NULL)
                     94:                        stream_free(outp);
                     95:                if (errp != NULL)
                     96:                        stream_free(errp);
                     97:                return NULL;
                     98:        }
                     99:        pp->std[0] = inp;
                    100:        pp->std[1] = outp;
                    101:        pp->std[2] = errp;
                    102:        switch (pp->pid = fork()) {
                    103:        case -1:
                    104:                proc_free(pp);
                    105:                return NULL;
                    106:        case 0:
                    107:                fflush(stdout);
                    108:                if (spath==NULL) {
                    109:                        spath = s_new();
                    110:                        s_append(spath, "PATH=");
                    111:                        s_append(spath, UPASROOT);
                    112:                        s_append(spath, ":/bin:/usr/bin");
                    113:                        home = s_new();
                    114:                        env[1] = s_to_c(spath);
                    115:                }
                    116:                uid=(uid<0)?getuid():uid;
                    117:                pw = getpwuid(uid);
                    118:                if (pw != NULL){
                    119:                        setlogname(pw->pw_name);
                    120:                        s_append(s_restart(home), "HOME=");
                    121:                        s_append(home, pw->pw_dir);
                    122:                        env[2] = s_to_c(home);
                    123:                } else
                    124:                        env[2] = "HOME=/";
                    125:                if (tz==NULL) {
                    126:                        if(tzp = getenv("TZ")){
                    127:                                tz = s_new();
                    128:                                s_append(tz, "TZ=");
                    129:                                s_append(tz, tzp);
                    130:                                env[3] = s_to_c(tz);
                    131:                        }
                    132:                }
                    133:                setgid(-1);
                    134:                setuid(uid);
                    135:                for (i=0; i<3; i++)
                    136:                        if (pp->std[i] != NULL)
                    137:                                fclose(pp->std[i]->fp);
                    138:                for (i=0; i<NSYSFILE; i++)
                    139:                        if (pp->std[i] != NULL)
                    140:                                dup2(pp->std[i]->fd, i);
                    141:                for (i = NSYSFILE; i < NOFILE; i++)
                    142:                        close(i);
                    143:                execle("/bin/sh", "sh", "-c", cmd, 0, env);
                    144:                perror("proc_start");
                    145:                exit(1);
                    146:        default:
                    147:                for (i=0; i<3; i++)
                    148:                        if (pp->std[i] != NULL) {
                    149:                                close(pp->std[i]->fd);
                    150:                                pp->std[i]->fd = -1;
                    151:                        }
                    152:                return pp;
                    153:        }
                    154: }
                    155: 
                    156: /* wait for a process to stop */
                    157: extern int
                    158: proc_wait(pp)
                    159:        process *pp;            /* description of process */
                    160: {
                    161:        int status=0;
                    162:        int pid;
                    163: 
                    164:        while((pid = wait(&status))>=0) {
                    165:                if (pid==pp->pid)
                    166:                        break;
                    167:        }
                    168:        pp->pid = -1;
                    169:        pp->status = status;
                    170:        return status;
                    171: }
                    172: 
                    173: /* free a process */
                    174: extern int
                    175: proc_free(pp)
                    176:        process *pp;
                    177: {
                    178:        int i;
                    179: 
                    180:        for (i = 0; i < 3; i++)
                    181:                if (pp->std[i])
                    182:                        stream_free(pp->std[i]);
                    183:        if (pp->pid >= 0){
                    184:                kill(pp->pid, SIGKILL);
                    185:                (void)proc_wait(pp);
                    186:        }
                    187:        free((char *)pp);
                    188:        return 0;
                    189: }

unix.superglobalmegacorp.com

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