[comp.sys.amiga.programmer] child process I/O problem

henning@madnix.UUCP (Mark D. Henning) (04/03/91)

Hello.  
   I have a rather complicated programming problem.  I am not sure
where it lies, but it is rather nasty.  

What I am trying to accomplish is to have a syncronous process place
data into a temproary file, eventually receiving its input from a
temporary file created by the parent process.

I had originally tried to do this using the pipe device as the output
stream of the child process, but I ran into a problem of the parent
blocking forever, waiting for an end of file so that it's final read
could be processed.  This made me decide to use temp files.  I use the 
Aztec fexecv function so that the parent waits till' the child is
finished. (I used the AmigaDos Execute when working with the pipe
device, as it would block anyway if its buffer overran, thus allowing
the parent to slurp the output as the child delivered it.)

The redefining of pr_COS worked fine without the redefining of pr_CIS.
Therefore I am not forgetting any BCPL garbage (I think?)  However,
when I debug through the parent program, somewhere during the fexecv
memory location 0000000 is written 0a000000.  Future calls can cause a guru.

The filter works with the equivelent function in a shell:

filter <foo >tmp

Therefore Either I am forgetting to set something in my process
structure to reflect the new CIS, or fexecv does something fishy.

Please help.  This is the final routine to make GNU emacs a full port.
Once this is accomplished, I can start to revamp the interface, making
it more ``intuition'' friendly, and get to fixing the elusive file
completion across devices bug.

Thanks in advance,

				Mark Henning

P.S. C code for examples follows the signature.

--------------------------------------------------------------------------
Providing the Amiga community with GNU Emacs and related materials.

UUCP: {harvard|rutgers|ucbvax}!uwvax!astroact!nicmad!madnix!aemsrc!henning
                                 {decvax|att}!
INTERNET: henning@aemsrc.UUCP

IF ABOVE FAILS: henning@stolaf.edu
--------------------------------------------------------------------------

/************************************************
 * useless filter, but good for testing purposes
 ************************************************/

#include <stdio.h>
main ()
{
 char c;
while ((c = getchar()) != EOF){
 putchar(c);
 putchar(c);
}
exit (0);
}


/***************************************************************************
 * second program, the parent.
 *****************************************************************/



#include <functions.h>
#include <exec/tasks.h>
#include <libraries/dosextens.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
  

int child_setup(new_argv, nametem)
  register char **new_argv;
  char *nametem;
{
  struct FileHandle *sout,*sin;
  struct Process *SyncProc;
  int fd,ok;  
  
  SyncProc = (struct Process *)FindTask (0);
  sout = SyncProc->pr_COS;
  sin = SyncProc->pr_CIS;
  SyncProc->pr_COS = Open (nametem, MODE_NEWFILE);
  SyncProc->pr_CIS = Open ("wrk:syncprocess/foo", MODE_OLDFILE); 
  ok = fexecv (new_argv[0], new_argv);
  Close (SyncProc->pr_COS);
  Close (SyncProc->pr_CIS);
  SyncProc->pr_COS = sout;
  SyncProc->pr_CIS = sin;
  return ok;
}


void main ()
{
  int fd;
  int nread;
  char buf[80];
  char *args[2] =
    {
      "filter",
      (char *) 0
      };
  char *name;  
  
  name = mktemp ("t:emacspipeXXXX");

  if (child_setup(args, name) == -1)
    {
       fprintf(stderr,"error in child process #%d\n",errno);
       exit(-1);
    }
  fd = open (name , O_RDONLY );
  while ((nread = read (fd, buf, sizeof buf)) >0)
    {
      write (fileno(stdout), buf, nread );
    }
  close (fd);
}



-- 
UUCP: {harvard|rutgers|ucbvax}!uwvax!astroatc!nicmad!madnix!henning
                                 {decvax|att}!

jesup@cbmvax.commodore.com (Randell Jesup) (04/05/91)

In article <1792@madnix.UUCP> henning@madnix.UUCP (Mark D. Henning) writes:
>What I am trying to accomplish is to have a syncronous process place
>data into a temproary file, eventually receiving its input from a
>temporary file created by the parent process.
>
>I had originally tried to do this using the pipe device as the output
>stream of the child process, but I ran into a problem of the parent
>blocking forever, waiting for an end of file so that it's final read
>could be processed.



>  This made me decide to use temp files.  I use the 
>Aztec fexecv function so that the parent waits till' the child is
>finished. (I used the AmigaDos Execute when working with the pipe
>device, as it would block anyway if its buffer overran, thus allowing
>the parent to slurp the output as the child delivered it.)

	Huh?  If you Execute("run filter <foo >pipe:tmp",0,nilfh), it should
work fine (you can use 0 instead of a nil: fh, that's just a habit of mine).
This causes the filter and the parent to run at the same time, and when the
filter runs out of input it will close the output stream, sending an EOF to
the parent.  Note that what I suspect you did was Execute("run filter",foofh,
pipefh).  

	Give Execute() a try, or please explain in more detail what the
problem was.

>The redefining of pr_COS worked fine without the redefining of pr_CIS.
>Therefore I am not forgetting any BCPL garbage (I think?)  However,
>when I debug through the parent program, somewhere during the fexecv
>memory location 0000000 is written 0a000000.  Future calls can cause a guru.

	fexecv makes certain (unwarranted) assumptions about it's environement.
For example, it assumes a filehandle has been used for buffered (BCPL) I/O
before it's called (as your normal COS/CIS/etc have been).  It uses the
buffer pointer and stuffs data into it, I believe.  Unfortunately, this doesn't
work well if no buffer has been allocated yet.

	It has to stuff the arguments passed to it (argv[1-n] and a newline)
into the buffer in the input filehandle.  Buffers aren't allocated unless
buffered BCPL-style I/O is done.

>The filter works with the equivelent function in a shell:
>
>filter <foo >tmp
>
>Therefore Either I am forgetting to set something in my process
>structure to reflect the new CIS, or fexecv does something fishy.

	fexecv does several fishy things, though in general it works.  It may
not deal properly with filehandles that don't have attached buffers.  Double-
check your manx docs as well, or call them and see if they can help you.

-- 
Randell Jesup, Keeper of AmigaDos, Commodore Engineering.
{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.commodore.com  BIX: rjesup  
Disclaimer: Nothing I say is anything other than my personal opinion.
Thus spake the Master Ninjei: "To program a million-line operating system
is easy, to change a man's temperament is more difficult."
(From "The Zen of Programming")  ;-)

peter@sugar.hackercorp.com (Peter da Silva) (04/07/91)

Why don't you just use a named message port?
-- 
Peter da Silva.   `-_-'
<peter@sugar.hackercorp.com>.