home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
446.lha
/
Popen
/
popen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-06
|
5KB
|
206 lines
/*
** popen.c
** Written by Rick Schaeffer (ricks@isc-br.isc-br.com)
NAME
popen, pclose - initiate I/O to/from a process
SYNOPSIS
#include <stdio.h>
FILE *popen(command, type)
char *command, *type;
pclose(stream)
FILE *stream;
DESCRIPTION
The arguments to popen are pointers to null-terminated
strings containing respectively a command line and an
I/O mode, either "r" for reading or "w" for writing. It
creates a pipe between the calling process and the command
to be executed. The value returned is a stream pointer that
can be used (as appropriate) to write to the standard input
of the command or read from its standard output.
A stream opened by popen **MUST** be closed by pclose, which
waits for the associated process to terminate and returns
the exit status of the command.
Because stdio files are shared, a type "r" command may be
used as an input filter, and a type "w" as an output filter.
DIAGNOSTICS
Popen returns a null pointer if files or processes cannot be
created.
Pclose returns -1 if stream is not associated with a
`popened' command.
*/
#include <stdio.h>
#include <string.h>
#include <exec/types.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <arp/arpbase.h>
#include <ios1.h>
struct ArpBase *ArpBase;
static struct Process *thistask;
static struct ProcessControlBlock pcb;
struct pstruct {
FILE *fptr;
struct ZombieMsg exitmsg;
};
struct pstruct poarray[6];
FILE *popen(cmd,mode)
char *cmd;
char *mode;
{
char *parms;
static char tempname[] = "pipe:pXXX.XXX";
char *pname,redir[20],*mktemp();
short i;
int pmode;
struct pstruct *poptr;
BPTR pfd;
if (thistask == NULL)
thistask = (struct Process *) FindTask(NULL);
if (ArpBase == NULL)
ArpBase = (struct ArpBase *) OpenLibrary(ArpName,ArpVersion);
if (ArpBase == NULL) {
fprintf(stderr,"Arp Open Failed\n");
return(NULL);
}
poptr = NULL;
for (i=0; i<6; i++) {
if (poarray[i].fptr == NULL) {
poptr = &poarray[i];
break;
}
}
if (poptr == NULL) {
fprintf(stderr,"popen: Unable to find an open pipe\n");
return(NULL);
}
if (strcmp(mode,"r") == 0)
pmode = MODE_NEWFILE;
else if (strcmp(mode,"w") == 0)
pmode = MODE_OLDFILE;
else {
fprintf(stderr,"popen: Mode must be 'r' or 'w'\n");
return(NULL);
}
tempname[5] = 'a' + i;
strcpy(redir,tempname);
pname = mktemp(redir); /* set up a pipe: file name */
setmem(&pcb, sizeof(struct ProcessControlBlock), 0);
/* Now get the child's stack and priority set up */
if (thistask->pr_CLI) {
struct CommandLineInterface *cli;
cli = (struct CommandLineInterface *) BADDR(thistask->pr_CLI);
pcb.pcb_StackSize = cli->cli_DefaultStack << 2;
}
else
pcb.pcb_StackSize = thistask->pr_StackSize;
pcb.pcb_Pri = thistask->pr_Task.tc_Node.ln_Pri;
/* Open the side of the pipe for the child */
pfd = Open(pname,pmode);
if (pfd == 0) {
fprintf(stderr,"popen: Unable to open pipe file\n");
return(NULL);
}
if (pmode == MODE_NEWFILE)
pcb.pcb_Output = pfd;
else
pcb.pcb_Input = pfd;
/* Locate the break between command and parameters */
parms = strpbrk(cmd," \t");
if (parms) {
*parms++ = 0;
parms = stpblk(parms);
if (parms && *parms == 0)
parms = NULL;
}
/* Create a port for the child's exit message */
poptr->exitmsg.zm_ExecMessage.mn_ReplyPort = CreatePort(NULL,0);
if (poptr->exitmsg.zm_ExecMessage.mn_ReplyPort == 0) {
fprintf(stderr,"popen: Couldn't create message port\n");
return(NULL);
}
pcb.pcb_LastGasp = &poptr->exitmsg;
if (ASyncRun(cmd,parms,&pcb) < 0) {
fprintf(stderr,"popen: AsyncRun failed\n");
DeletePort(poptr->exitmsg.zm_ExecMessage.mn_ReplyPort);
return(NULL);
}
/* Now open our side of the pipe */
poptr->fptr = fopen(pname,mode);
if (poptr->fptr == NULL) {
fprintf(stderr,"popen: Unable to open pipe file %s\n",pname);
DeletePort(poptr->exitmsg.zm_ExecMessage.mn_ReplyPort);
return(NULL);
}
return(poptr->fptr);
}
pclose(fptr)
FILE *fptr;
{
short i;
for (i=0; i<6; i++)
if (poarray[i].fptr == fptr)
break;
if (i > 5) {
fprintf(stderr,"popen: DISASTER...couldn't find file pointer in pclose\n");
exit(1);
}
fclose(fptr);
WaitPort(poarray[i].exitmsg.zm_ExecMessage.mn_ReplyPort);
poarray[i].fptr = NULL;
DeletePort(poarray[i].exitmsg.zm_ExecMessage.mn_ReplyPort);
return(poarray[i].exitmsg.zm_ReturnCode);
}
char *mktemp(template)
char *template;
{
register char *cp;
register unsigned long val;
cp = template;
cp += strlen(cp);
for (val = (unsigned long) FindTask(0L) ; ; )
if (*--cp == 'X') {
*cp = val%10 + '0';
val /= 10;
} else if (*cp != '.')
break;
if (*++cp != 0) {
*cp = 'A';
while (access(template, 0) == 0) {
if (*cp == 'Z') {
*template = 0;
break;
}
++*cp;
}
} else {
if (access(template, 0) == 0)
*template = 0;
}
return template;
}