home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
mint
/
mntlib16.lzh
/
MNTLIB16
/
POPEN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-03
|
3KB
|
115 lines
/* popen(): open a file handle to a process. Works only under MiNT.
* Written by Eric R. Smith, based on the TOS version by Kai-Uwe Bloem.
*/
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
__EXTERN int wait __PROTO((int *));
struct _pipe {
int pid; /* process id of child */
FILE *pfile; /* created file descriptor */
struct _pipe *pnext; /* next pipe in the list. */
};
static struct _pipe *__pipes = NULL; /* head of pipe list */
FILE *popen(command, type)
const char *command, *type;
{
struct _pipe *p; /* the new pipe's list entry */
int pipfd[2]; /* pipe file handles */
int savefd; /* saved file descriptor for parent */
int kidfd; /* file descriptor changed in child */
/* 1 for "r", 0 for "w" */
char *shell;
FILE *pipefile = 0;
extern int __mint;
if (__mint == 0) {
errno = EINVAL;
return (FILE *)0;
}
shell = getenv("SHELL");
if (!shell)
shell = "sh";
/* get space for the new pipe. If we can't get it then that's that */
p = (struct _pipe *) malloc(sizeof(struct _pipe));
if (p == NULL) return (FILE *)0;
/* initialize the new pipe entry */
kidfd = (*type == 'r') ? 1 : 0;
savefd = dup(kidfd);
if (savefd < 0 || pipe(pipfd) != 0) { /* can't create pipe?? */
free(p);
return (FILE *)0;
}
dup2(pipfd[kidfd], kidfd);
close(pipfd[kidfd]);
p->pid = spawnlp(P_NOWAIT, shell, shell, "-c", command, (char *)0);
dup2(savefd, kidfd);
close(savefd);
if (p->pid > 0) { /* command ran all right */
/* note: 1-kidfd tells us which handle to use in the parent */
pipefile = fdopen(pipfd[1 - kidfd], type);
}
if (pipefile) {
p->pfile = pipefile;
p->pnext = __pipes;
__pipes = p;
}
else {
free(p);
}
return pipefile;
}
/* close a pipe created by popen().
*/
int pclose(fp)
FILE *fp;
{
struct _pipe *p, /* the pipe's list element */
*q; /* predecessor of p in the list */
int status = -1; /* return status of the command */
int pid;
/* search the pipe list for a pipe matching the FILE descriptor */
for (p = __pipes, q = NULL; p && p->pfile != fp; q = p, p = p->pnext);
if (p == NULL) /* Never had a popen() for this file... */
return status; /* this pclose call makes no sense ! */
fclose(p->pfile); /* close the connection */
/* now wait for the command to finish */
do {
pid = wait(&status);
} while (pid >= 0 && pid != p->pid);
/* remove the pipe from the list */
if (q) /* not the first in the list, unlink it from previous pipe */
q->pnext = p->pnext;
else /* first in the list, set new list head */
__pipes = __pipes->pnext;
/* Now free the pipe entry */
free(p);
return status;
}