Back to index

radiance  4R0+20100331
unix_process.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: unix_process.c,v 3.9 2009/12/12 23:08:13 greg Exp $";
00003 #endif
00004 /*
00005  * Routines to communicate with separate process via dual pipes
00006  * Unix version
00007  *
00008  * External symbols declared in standard.h
00009  */
00010 
00011 #include "copyright.h"
00012 
00013 #include <sys/types.h>
00014 #include <sys/wait.h>
00015 #include <fcntl.h>
00016 #include <stdlib.h>
00017 
00018 #include "rtprocess.h"
00019 #include "rtio.h"
00020 
00021 
00022 int
00023 open_process(        /* open communication to separate process */
00024 SUBPROC *pd,
00025 char   *av[]
00026 )
00027 {
00028        char   *compath;
00029        int    p0[2], p1[2];
00030 
00031        pd->running = 0; /* not yet */
00032                                    /* find executable */
00033        compath = getpath(av[0], getenv("PATH"), 1);
00034        if (compath == 0)
00035               return(0);
00036        if (pipe(p0) < 0 || pipe(p1) < 0)
00037               return(-1);
00038        if ((pd->pid = fork()) == 0) {            /* if child */
00039               close(p0[1]);
00040               close(p1[0]);
00041               if (p0[0] != 0) {    /* connect p0 to stdin */
00042                      dup2(p0[0], 0);
00043                      close(p0[0]);
00044               }
00045               if (p1[1] != 1) {    /* connect p1 to stdout */
00046                      dup2(p1[1], 1);
00047                      close(p1[1]);
00048               }
00049               execv(compath, av);  /* exec command */
00050               perror(compath);
00051               _exit(127);
00052        }
00053        if (pd->pid == -1)
00054               return(-1);
00055        close(p0[0]);
00056        close(p1[1]);
00057        pd->r = p1[0];
00058        pd->w = p0[1];
00059        /*
00060         * Close write stream on exec to avoid multiprocessing deadlock.
00061         * No use in read stream without it, so set flag there as well.
00062         * GW: This bug took me two days to figure out!!
00063         */
00064        fcntl(pd->r, F_SETFD, FD_CLOEXEC);
00065        fcntl(pd->w, F_SETFD, FD_CLOEXEC);
00066        pd->running = 1;
00067        return(PIPE_BUF);
00068 }
00069 
00070 
00071 
00072 int
00073 close_process(              /* close pipes and wait for process */
00074 SUBPROC *pd
00075 )
00076 {
00077        int    status;
00078 
00079        if (!pd->running)
00080               return(0);
00081        close(pd->w);
00082        pd->running = 0;
00083        if (waitpid(pd->pid, &status, 0) == pd->pid) {
00084               close(pd->r);
00085               return(status>>8 & 0xff);
00086        }
00087        return(-1);          /* ? unknown status */
00088 }
00089 
00090