home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sys / amiga / programm / 12474 < prev    next >
Encoding:
Text File  |  1992-08-19  |  7.4 KB  |  293 lines

  1. 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
  2. From: mcuddy@fensende.Rational.COM (Mike Cuddy)
  3. Newsgroups: comp.sys.amiga.programmer
  4. Subject: Re: Emulating UNIX pipes on Amiga (GCC?)
  5. Message-ID: <mcuddy.714255917@fensende>
  6. Date: 19 Aug 92 20:25:17 GMT
  7. References: <KENTD.92Aug19091130@zappa.FtCollins.NCR.com>
  8. Sender: news@Rational.COM
  9. Lines: 282
  10.  
  11. kentd@FtCollins.NCR.com (Kent Dalton) writes:
  12.  
  13. >Does anybody know how Amiga GCC 2.1/ixemlib implements pipes? I am
  14. >porting a program which extensively uses pipes and the file handles
  15. >provided by the GCC popen function are behaving like they are pointed at
  16. >/dev/null. Does it even work at all?
  17.  
  18. I don't know about GCC pipes, but here's some code that works for me using
  19. amigados 2 and the pipe: device...
  20.  
  21. (there are a couple of routines missing... StringNew() and StringDelete()
  22. you can use malloc() and free())
  23.  
  24. -----pipe.h-----
  25. /*
  26. ** pipe.h -- functions for dealing with named pipes 
  27. */
  28. #ifndef _H_PIPE
  29. #define _H_PIPE
  30.  
  31. typedef struct pipe_f {
  32.     struct FileHandle *p_write;
  33.     struct FileHandle *p_read;
  34. } Pipe;
  35.  
  36. #define PIPE_NOREAD (1<<1)
  37. /* open a pair of file descriptors on the same file in PIPE: */
  38. int OpenPipe(Pipe *pipe,char *name, char **filename, int flags);
  39.  
  40. #define PIPE_SUBS (1<<0)    /* replace '%' with pipe filename */
  41. /* open a pipe to write data to another program */
  42. struct FileHandle *PipeTo(char *progname, long flags, struct FileHandle *output);
  43.  
  44. /* open a pipe to read data from another program */
  45. struct FileHandle *PipeFrom(char *progname, long flags, struct FileHandle *input);
  46.  
  47. #endif
  48.  
  49. -----pipe.c-----
  50. /*
  51. ** pipe.c: handle pipes..
  52. */
  53.  
  54. #include <dos/dos.h>
  55. #include <dos/dostags.h>
  56. #include <stdio.h>
  57. #include <clib/dos_protos.h>
  58. #include <pragmas/dos_lib.h> 
  59. #include <string.h>
  60. #include "strstuff.h"
  61. #include "pipe.h"
  62.  
  63. /* 
  64. ** fill in (Pipe *)pipe with a read file descriptor and a write file
  65. ** descriptor.  if flags & PIPE_NOREAD, don't open a read pipe 
  66. */
  67. int OpenPipe(Pipe *pipe,char *name,char **filename, int flags)
  68. {
  69.     char buf[32];
  70.     static int counter = 0;
  71.  
  72.     Forbid(); counter++; Permit();    /* keep it pure.. ;-) */
  73.     sprintf(buf,"PIPE:%X.%d",FindTask(0),counter);
  74.     if (name) strncat(buf,name,sizeof(buf) - strlen(buf));
  75.     if (filename) {
  76.         *filename = StringSave(buf);
  77.     if (*filename == NULL) return(NULL);
  78.     }
  79.     
  80.     /* make a temp file name in PIPE:  and returns 2 file descriptors */
  81.     pipe->p_write = (struct FileHandle *)Open(buf,MODE_NEWFILE);
  82.     if (pipe->p_write == NULL) {
  83. #ifdef TEST_PIPE
  84.     printf("can't open write pipe %s\n",buf);
  85. #endif
  86.         return(-1);
  87.     }
  88.     if (!(flags & PIPE_NOREAD)) {
  89.     pipe->p_read = (struct FileHandle *)Open(buf,MODE_OLDFILE);
  90.     if (pipe->p_read == NULL) { 
  91. #ifdef TEST_PIPE
  92.         printf("can't open write pipe %s\n",buf);
  93. #endif
  94.         Close((BPTR)(pipe->p_write)); return(-1); 
  95.     }
  96.     } else pipe->p_read = NULL;
  97.     return(0);
  98. }
  99.  
  100. void ClosePipe(Pipe *pipe)
  101. {
  102. #ifdef TEST_PIPE
  103.     printf("closing pipe");
  104. #endif
  105.     if (pipe->p_read) Close((BPTR)pipe->p_read); 
  106.     pipe->p_read = NULL;
  107.     if (pipe->p_write) Close((BPTR)pipe->p_write);
  108.     pipe->p_write = NULL;
  109. }
  110.  
  111. struct FileHandle *PipeTo(char *progname, long flags, struct FileHandle *output)
  112. {
  113.     Pipe pipe;
  114.     long err;
  115.     char *pipefn = NULL;
  116.     char *substname = NULL;
  117.     /* 
  118.     ** runs another program asynchronously, returns a file descriptor
  119.     ** to write to 
  120.     */
  121.     if (output == NULL) {
  122.         output = (struct FileHandle *)Open("CONSOLE:",MODE_NEWFILE);
  123.     if (output == NULL) {
  124. #ifdef TEST_PIPE
  125.         printf("can't open CONSOLE: for output\n");
  126. #endif
  127.         return(NULL);    /* couldn't open console */
  128.     }
  129.     }
  130.     if (OpenPipe(&pipe,NULL,flags & PIPE_SUBS ? &pipefn : NULL,flags & PIPE_SUBS ? PIPE_NOREAD : 0)==-1) 
  131.         return(NULL); 
  132.  
  133.     if (flags & PIPE_SUBS) {
  134.     int count = 0;
  135.     char *p;
  136.  
  137.         if (pipefn == NULL) return(NULL);
  138.     p = progname;
  139.     while (*p) if (*p++ == '%') count++;
  140.     if (count != 0) {
  141.         char *out;
  142.         substname = StringNew(strlen(progname)+count*strlen(pipefn));
  143.         if (substname == NULL) {
  144.             StringDelete(pipefn);
  145.         ClosePipe(&pipe);
  146.         return(NULL);
  147.         }
  148.         out = substname;
  149.         p = progname;
  150.         while(*p) {
  151.             if (*p == '%') {
  152.             char *q = pipefn;
  153.             while (*q) *out++ = *q++;    /* copy file name */
  154.             p++;
  155.         } else {
  156.             *out++ = *p++;
  157.         }
  158.         }
  159.         *out = 0;    /* Null terminate substituted command line */
  160.         progname = substname;
  161.         StringDelete(pipefn);
  162.     }
  163.     }
  164.  
  165. #ifdef TEST_PIPE
  166.     printf("calling SystemTags(%s)\n",progname);
  167. #endif
  168.     err = SystemTags(progname, SYS_Input, pipe.p_read,
  169.             SYS_Asynch, 1, 
  170.             SYS_Output, output,
  171.             SYS_UserShell, 1,
  172.             TAG_DONE);
  173.  
  174.     if (substname) StringDelete(substname);
  175.  
  176.     if (err) {
  177. #ifdef TEST_PIPE
  178.         printf("couldn't SystemTags.\n");
  179. #endif
  180.         ClosePipe(&pipe);
  181.     Close((BPTR)output);
  182.     return(NULL);
  183.     }
  184.     return(pipe.p_write);
  185. }
  186.  
  187. struct FileHandle *PipeFrom(char *progname, long flags, struct FileHandle *input)
  188. {
  189.     Pipe pipe;
  190.     long err;
  191.     char *pipefn = NULL;
  192.     char *substname = NULL;
  193.     /* 
  194.     ** runs another program asynchronously, returns a file descriptor
  195.     ** to write to 
  196.     */
  197.     if (input == NULL) {
  198.         input = (struct FileHandle *)Open("CONSOLE:",MODE_OLDFILE);
  199.     if (input == NULL) {
  200. #ifdef TEST_PIPE
  201.         printf("can't open CONSOLE: for input\n");
  202. #endif
  203.         return(NULL);    /* couldn't open console */
  204.     }
  205.     }
  206.     if (OpenPipe(&pipe,NULL,flags & PIPE_SUBS ? &pipefn : NULL, flags)==-1) 
  207.         return(NULL); 
  208.  
  209.     if (flags & PIPE_SUBS) {
  210.     int count = 0;
  211.     char *p;
  212.  
  213.         if (pipefn == NULL) return(NULL);
  214.     p = progname;
  215.     while (*p) if (*p++ == '%') count++;
  216.     if (count != 0) {
  217.         char *out;
  218.         substname = StringNew(strlen(progname)+count*strlen(pipefn));
  219.         if (substname == NULL) {
  220.             StringDelete(pipefn);
  221.         ClosePipe(&pipe);
  222.         return(NULL);
  223.         }
  224.         out = substname;
  225.         p = progname;
  226.         while(*p) {
  227.             if (*p == '%') {
  228.             char *q = pipefn;
  229.             while (*q) *out++ = *q++;    /* copy file name */
  230.             p++;
  231.         } else {
  232.             *out++ = *p++;
  233.         }
  234.         }
  235.         *out = 0;    /* Null terminate substituted command line */
  236.         progname = substname;
  237.         StringDelete(pipefn);
  238.     }
  239.     }
  240.  
  241.     err = SystemTags(progname, SYS_Input, input,
  242.             SYS_Asynch, 1, 
  243.             SYS_Output, pipe.p_write,
  244.             SYS_UserShell, 1,
  245.             TAG_DONE);
  246. #ifdef TEST_PIPE
  247.     printf("calling SystemTags(%s)\n",progname);
  248. #endif
  249.  
  250.     if (substname) StringDelete(substname);
  251.  
  252.     if (err) {
  253. #ifdef TEST_PIPE
  254.         printf("couldn't SystemTags.\n");
  255. #endif
  256.         ClosePipe(&pipe);
  257.     Close((BPTR)input);
  258.     return(NULL);
  259.     }
  260.     return(pipe.p_read);
  261. }
  262.  
  263. #ifdef TEST_PIPE
  264. char buf[1024];
  265.  
  266. main(int argc,char **argv)
  267. {
  268.     struct FileHandle *r, *w;
  269.     char *str;
  270.     int bytes;
  271.  
  272.     /* test pipe functions.. */
  273.  
  274.     /* open a read pipe to 'type' */
  275.     r = PipeFrom("ls -al", PIPE_SUBS, NULL);
  276.  
  277.     /* open a write pipe to 'type' */
  278.     /* we set PIPE_NOREAD because we let more use redirection and
  279.     ** if we open the read side of the pipe, more will not be able to.
  280.      */
  281.     w = PipeTo(argv[1] ? argv[1] : "more <%",PIPE_SUBS|PIPE_NOREAD,(struct FileHandle *)Output());
  282.  
  283.     while ((bytes = Read((BPTR)r,buf,sizeof(buf))) > 0) {
  284.         Write((BPTR)w,buf,bytes);
  285.     }
  286.     str = "That's all folks!\n\n*** END OF FILE***\n";
  287.     Write((BPTR)w,str,strlen(str));
  288.     Close((BPTR)r);
  289.     Close((BPTR)w);
  290.     return(0);
  291. }
  292. #endif
  293.