Path: news.uiowa.edu!chi-news.cic.net!newsxfer2.itd.umich.edu!newsxfer.itd.umich.edu!news.itd.umich.edu!mcafee From: mcafee@umich.edu (Sean McAfee) Newsgroups: comp.sys.apple2.gno Subject: Re: Why no popen()? Could this be the reason? Date: 22 Jan 1996 14:36:17 GMT Organization: University of Michigan Lines: 107 Message-ID: <4e07d1$s34@lastactionhero.rs.itd.umich.edu> References: <4dq5d4$m9u@lastactionhero.rs.itd.umich.edu> <4durq7$1b0@apollo.csd.net> NNTP-Posting-Host: verne.ifs.umich.edu In article <4durq7$1b0@apollo.csd.net>, Jawaid Bazyar wrote: > Without seeing the code for your popen, I couldn't guess what the problem >is. Well, OK. I was just wondering if there was a reason popen() isn't around, since it's rather conspicuous by its absence. Here's my code. It's VERY crude, but I just wanted a quick-fix to get gnuplot compiled. #include #include #include #include #include #include static int fd[2]; static int openfd; static char *myargv[20]; static char *combuf; static struct flist { FILE *stream; int pid; struct flist *next; } *listp, *head = NULL, *tail = NULL; FILE *popen(const char *command, const char *mode) { FILE *stream; int i, j, pid, done = 0, myargc = 1; char c, *cp; void doit(void); if (mode[1] || mode[0]!='r' && mode[0]!='w') return NULL; openfd = mode[0]=='w'; /* openfd is the end of the pipe the parent should keep open */ i = strpos(command, ' '); combuf = malloc(i+1); strncpy(combuf, command, i); /* this code puts the command name combuf[i] = '\0'; into combuf[] and myargv[0] */ myargv[0] = malloc(i+1); strncpy(myargv[0], command, i); myargv[0][i] = '\0'; j = i+1; do { i = strpos(command+j, ' '); if (i==-1) { i = strlen(command+j); done = 1; } cp = malloc(i+1); /* This loop parses the words */ strncpy(cp, command+j, i); /* in the command line into */ cp[i] = '\0'; /* the myargv[] array */ myargv[myargc++] = cp; j += i+1; } while (!done); myargv[myargc] = NULL; pipe(fd); pid = fork(doit); close(fd[1-openfd]); stream = fdopen(fd[openfd], mode); listp = malloc(sizeof(struct flist)); /* Put the stream and pid */ listp->stream = stream; /* a list for later */ listp->pid = pid; /* retrieval by pclose() */ listp->next = NULL; if (head) { tail->next = listp; tail = listp; } else head = tail = listp; return stream; } int pclose(FILE *stream) { union wait waitbuf; fclose(stream); for (listp=head; listp && listp->stream == stream; listp=listp->next) ; if (!listp) return -1; wait(&waitbuf); return waitbuf.w_status; } static void doit(void) { dup2(fd[1-openfd], fileno(openfd ? stdin : stdout)); close(fd[0]); close(fd[1]); execvp(combuf, myargv); }