Annotation of researchv10no/cmd/upas/send/process.c, revision 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.