/*
 *  Open a FileHandle to a process.
 *
 */

#include <stdio.h>
#include <fcntl.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include "roguestar.h"
#include "bcpl.h"

extern void *AllocMem();
extern struct FileHandle *Open();
extern FILE *fdopen();
extern void *CreatePort();
extern void *GetMsg();
extern char *getenv();

FILE * popenv(av,ac,mode,pp)
char *av[];
int ac;
char *mode;
struct MsgPort **pp;
{
  char *PipeDevice;
  long ProcessId;
  static long Sequence=0;
  struct FileHandle *in,*out,*err;
  struct FileHandle *pin,*pout,*ret,*temp;
  struct MsgPort *p;
  struct RogueStartup *r;
  char PipeName[40];
  FILE   *rf;
  int code;
  long mask;
  int i;

  in=RogueInput();
  out=RogueOutput();
  err=RogueError();

/*  if((PipeDevice=getenv("PIPEDEV"))==NULL) {*/
    PipeDevice="PIPE:";
/*  }*/
  ProcessId=FindTask(NULL);

  if(mode[0]!='r' && mode[0]!='w') return(NULL);

  sprintf(PipeName, "%srogue%dpipe%d", PipeDevice, ProcessId, Sequence++);
  if((pin = Open(PipeName, MODE_NEWFILE))==NULL) {
    return(NULL);
  }
  if((pout = Open(PipeName, MODE_OLDFILE))==NULL) {
    Close(pin);
    return(NULL);
  }

  if(mode[0]=='r') {
    out=pin;
    ret=pout;
    mask=(1L << 1);
  }
  else {
    in=pout;
    ret=pin;
    mask=(1L << 0);
  }

  /* Now set up the _devtab structure. */
  for(i=0; i<_numdev; i++) {
    if(_devtab[i].fd==NULL) {
      break;
    }
  }

  if(i==_numdev) {
    Close(pin);
    Close(pout);
    return(NULL);
  }
  _devtab[i].fd=(long)ret;
  _devtab[i].mode=(mode[0]=='r' ? O_RDONLY : O_WRONLY);

  if((rf=(FILE *)fdopen(i,mode))==NULL) {
    _devtab[i].fd=NULL;
    Close(pin);
    Close(pout);
    return(NULL);
  }

  if((p=(struct MsgPort *)CreatePort(NULL,NULL))==NULL) {
    if(ret==pin) Close(pout);
    else Close(pin);
    fclose(rf);
    return(NULL);
  }
  if((r=RogueLaunch(p,av[0],av,ac,NULL,0,NULL,10000,in,out,err,mask))==NULL) {
    if(ret==pin) Close(pout);
    else Close(pin);
    fclose(rf);
    DeletePort(p);
    return(NULL);
  }
  *pp=p;

  return(rf);

}

int pclose(f,pp)
FILE *f;
struct MsgPort **pp;
{
  struct MsgPort *p;
  struct RogueStart *rs;
  int code;

  if(f==NULL||pp==NULL) return(-1);

  p=*pp;

  if(p==NULL) return(-2);

  fclose(f);     /* Close our end of the pipe */

  WaitPort(p);
  rs=GetMsg(p);
  if(rs) {
    code=RogueFreeStartup(rs);
  }

  return(code);
}






