home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!mcsun!uknet!doc.ic.ac.uk!ibmassc!yktnews!admin!newsgate.watson.ibm.com!news.ans.net!malgudi.oar.net!zaphod.mps.ohio-state.edu!sdd.hp.com!uakari.primate.wisc.edu!ames!pacbell.com!UB.com!igor!fensende!mcuddy
- From: mcuddy@fensende.Rational.COM (Mike Cuddy)
- Newsgroups: comp.sys.amiga.programmer
- Subject: Re: Emulating UNIX pipes on Amiga (GCC?)
- Message-ID: <mcuddy.714255917@fensende>
- Date: 19 Aug 92 20:25:17 GMT
- References: <KENTD.92Aug19091130@zappa.FtCollins.NCR.com>
- Sender: news@Rational.COM
- Lines: 282
-
- kentd@FtCollins.NCR.com (Kent Dalton) writes:
-
- >Does anybody know how Amiga GCC 2.1/ixemlib implements pipes? I am
- >porting a program which extensively uses pipes and the file handles
- >provided by the GCC popen function are behaving like they are pointed at
- >/dev/null. Does it even work at all?
-
- I don't know about GCC pipes, but here's some code that works for me using
- amigados 2 and the pipe: device...
-
- (there are a couple of routines missing... StringNew() and StringDelete()
- you can use malloc() and free())
-
- -----pipe.h-----
- /*
- ** pipe.h -- functions for dealing with named pipes
- */
- #ifndef _H_PIPE
- #define _H_PIPE
-
- typedef struct pipe_f {
- struct FileHandle *p_write;
- struct FileHandle *p_read;
- } Pipe;
-
- #define PIPE_NOREAD (1<<1)
- /* open a pair of file descriptors on the same file in PIPE: */
- int OpenPipe(Pipe *pipe,char *name, char **filename, int flags);
-
- #define PIPE_SUBS (1<<0) /* replace '%' with pipe filename */
- /* open a pipe to write data to another program */
- struct FileHandle *PipeTo(char *progname, long flags, struct FileHandle *output);
-
- /* open a pipe to read data from another program */
- struct FileHandle *PipeFrom(char *progname, long flags, struct FileHandle *input);
-
- #endif
-
- -----pipe.c-----
- /*
- ** pipe.c: handle pipes..
- */
-
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <stdio.h>
- #include <clib/dos_protos.h>
- #include <pragmas/dos_lib.h>
- #include <string.h>
- #include "strstuff.h"
- #include "pipe.h"
-
- /*
- ** fill in (Pipe *)pipe with a read file descriptor and a write file
- ** descriptor. if flags & PIPE_NOREAD, don't open a read pipe
- */
- int OpenPipe(Pipe *pipe,char *name,char **filename, int flags)
- {
- char buf[32];
- static int counter = 0;
-
- Forbid(); counter++; Permit(); /* keep it pure.. ;-) */
- sprintf(buf,"PIPE:%X.%d",FindTask(0),counter);
- if (name) strncat(buf,name,sizeof(buf) - strlen(buf));
- if (filename) {
- *filename = StringSave(buf);
- if (*filename == NULL) return(NULL);
- }
-
- /* make a temp file name in PIPE: and returns 2 file descriptors */
- pipe->p_write = (struct FileHandle *)Open(buf,MODE_NEWFILE);
- if (pipe->p_write == NULL) {
- #ifdef TEST_PIPE
- printf("can't open write pipe %s\n",buf);
- #endif
- return(-1);
- }
- if (!(flags & PIPE_NOREAD)) {
- pipe->p_read = (struct FileHandle *)Open(buf,MODE_OLDFILE);
- if (pipe->p_read == NULL) {
- #ifdef TEST_PIPE
- printf("can't open write pipe %s\n",buf);
- #endif
- Close((BPTR)(pipe->p_write)); return(-1);
- }
- } else pipe->p_read = NULL;
- return(0);
- }
-
- void ClosePipe(Pipe *pipe)
- {
- #ifdef TEST_PIPE
- printf("closing pipe");
- #endif
- if (pipe->p_read) Close((BPTR)pipe->p_read);
- pipe->p_read = NULL;
- if (pipe->p_write) Close((BPTR)pipe->p_write);
- pipe->p_write = NULL;
- }
-
- struct FileHandle *PipeTo(char *progname, long flags, struct FileHandle *output)
- {
- Pipe pipe;
- long err;
- char *pipefn = NULL;
- char *substname = NULL;
- /*
- ** runs another program asynchronously, returns a file descriptor
- ** to write to
- */
- if (output == NULL) {
- output = (struct FileHandle *)Open("CONSOLE:",MODE_NEWFILE);
- if (output == NULL) {
- #ifdef TEST_PIPE
- printf("can't open CONSOLE: for output\n");
- #endif
- return(NULL); /* couldn't open console */
- }
- }
- if (OpenPipe(&pipe,NULL,flags & PIPE_SUBS ? &pipefn : NULL,flags & PIPE_SUBS ? PIPE_NOREAD : 0)==-1)
- return(NULL);
-
- if (flags & PIPE_SUBS) {
- int count = 0;
- char *p;
-
- if (pipefn == NULL) return(NULL);
- p = progname;
- while (*p) if (*p++ == '%') count++;
- if (count != 0) {
- char *out;
- substname = StringNew(strlen(progname)+count*strlen(pipefn));
- if (substname == NULL) {
- StringDelete(pipefn);
- ClosePipe(&pipe);
- return(NULL);
- }
- out = substname;
- p = progname;
- while(*p) {
- if (*p == '%') {
- char *q = pipefn;
- while (*q) *out++ = *q++; /* copy file name */
- p++;
- } else {
- *out++ = *p++;
- }
- }
- *out = 0; /* Null terminate substituted command line */
- progname = substname;
- StringDelete(pipefn);
- }
- }
-
- #ifdef TEST_PIPE
- printf("calling SystemTags(%s)\n",progname);
- #endif
- err = SystemTags(progname, SYS_Input, pipe.p_read,
- SYS_Asynch, 1,
- SYS_Output, output,
- SYS_UserShell, 1,
- TAG_DONE);
-
- if (substname) StringDelete(substname);
-
- if (err) {
- #ifdef TEST_PIPE
- printf("couldn't SystemTags.\n");
- #endif
- ClosePipe(&pipe);
- Close((BPTR)output);
- return(NULL);
- }
- return(pipe.p_write);
- }
-
- struct FileHandle *PipeFrom(char *progname, long flags, struct FileHandle *input)
- {
- Pipe pipe;
- long err;
- char *pipefn = NULL;
- char *substname = NULL;
- /*
- ** runs another program asynchronously, returns a file descriptor
- ** to write to
- */
- if (input == NULL) {
- input = (struct FileHandle *)Open("CONSOLE:",MODE_OLDFILE);
- if (input == NULL) {
- #ifdef TEST_PIPE
- printf("can't open CONSOLE: for input\n");
- #endif
- return(NULL); /* couldn't open console */
- }
- }
- if (OpenPipe(&pipe,NULL,flags & PIPE_SUBS ? &pipefn : NULL, flags)==-1)
- return(NULL);
-
- if (flags & PIPE_SUBS) {
- int count = 0;
- char *p;
-
- if (pipefn == NULL) return(NULL);
- p = progname;
- while (*p) if (*p++ == '%') count++;
- if (count != 0) {
- char *out;
- substname = StringNew(strlen(progname)+count*strlen(pipefn));
- if (substname == NULL) {
- StringDelete(pipefn);
- ClosePipe(&pipe);
- return(NULL);
- }
- out = substname;
- p = progname;
- while(*p) {
- if (*p == '%') {
- char *q = pipefn;
- while (*q) *out++ = *q++; /* copy file name */
- p++;
- } else {
- *out++ = *p++;
- }
- }
- *out = 0; /* Null terminate substituted command line */
- progname = substname;
- StringDelete(pipefn);
- }
- }
-
- err = SystemTags(progname, SYS_Input, input,
- SYS_Asynch, 1,
- SYS_Output, pipe.p_write,
- SYS_UserShell, 1,
- TAG_DONE);
- #ifdef TEST_PIPE
- printf("calling SystemTags(%s)\n",progname);
- #endif
-
- if (substname) StringDelete(substname);
-
- if (err) {
- #ifdef TEST_PIPE
- printf("couldn't SystemTags.\n");
- #endif
- ClosePipe(&pipe);
- Close((BPTR)input);
- return(NULL);
- }
- return(pipe.p_read);
- }
-
- #ifdef TEST_PIPE
- char buf[1024];
-
- main(int argc,char **argv)
- {
- struct FileHandle *r, *w;
- char *str;
- int bytes;
-
- /* test pipe functions.. */
-
- /* open a read pipe to 'type' */
- r = PipeFrom("ls -al", PIPE_SUBS, NULL);
-
- /* open a write pipe to 'type' */
- /* we set PIPE_NOREAD because we let more use redirection and
- ** if we open the read side of the pipe, more will not be able to.
- */
- w = PipeTo(argv[1] ? argv[1] : "more <%",PIPE_SUBS|PIPE_NOREAD,(struct FileHandle *)Output());
-
- while ((bytes = Read((BPTR)r,buf,sizeof(buf))) > 0) {
- Write((BPTR)w,buf,bytes);
- }
- str = "That's all folks!\n\n*** END OF FILE***\n";
- Write((BPTR)w,str,strlen(str));
- Close((BPTR)r);
- Close((BPTR)w);
- return(0);
- }
- #endif
-