/*
 *  This file is part of ixemul.library for the Amiga.
 *  Copyright (C) 1991, 1992  Markus M. Wild
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#define KERNEL
#include "ixemul.h"

#if __GNUC__ != 2
#define alloca __builtin_alloca
#endif

struct pipe_vec {
  struct FileHandle *fh1, *fh2;
};

static int
__pipe_func (struct StandardPacket *sp, struct MsgPort *handler,
             BPTR parent_lock,
	     BSTR name,
	     struct pipe_vec *pv, int *no_error)
{
  bzero (pv->fh1, sizeof (struct FileHandle));
  pv->fh1->fh_Pos = pv->fh1->fh_End = -1;

  sp->sp_Pkt.dp_Type = 2000;	/* conman-packet */
  sp->sp_Pkt.dp_Arg1 = CTOBPTR (pv->fh1);
  sp->sp_Pkt.dp_Arg2 = parent_lock;
  sp->sp_Pkt.dp_Arg3 = name;

  PutPacket (handler, sp);
  __wait_packet (sp);

  *no_error = sp->sp_Pkt.dp_Res1 == -1;
 
  /* handler is supposed to supply this, but if it didn't... */
  if (*no_error && !pv->fh1->fh_Type) pv->fh1->fh_Type = handler;

  if (*no_error) bcopy (pv->fh1, pv->fh2, sizeof (struct FileHandle));

  /* don't continue if we failed because of symlink - reference */
  return 0;
}

int
__pipe (BPTR vecs[2])
{
  unsigned long *fh1, *fh2;
  struct pipe_vec pv;
  BPTR res;

  /* provide new filehandles, allocated as DOS-like as possible
   * (don't know if that's needed) */
  fh1 = (unsigned long *) kmalloc (sizeof (struct FileHandle) + 4);
  *fh1 = sizeof (struct FileHandle);
  pv.fh1 = (struct FileHandle *)(fh1 + 1);
  fh2 = (unsigned long *) kmalloc (sizeof (struct FileHandle) + 4);
  *fh2 = sizeof (struct FileHandle);
  pv.fh2 = (struct FileHandle *)(fh2 + 1);
  
  res = __plock ("PIP:5120", __pipe_func, &pv);
  
  if (! res)
    {
      kfree (fh1);
      kfree (fh2);
    }
  else
    {
      vecs[0] = CTOBPTR (pv.fh1);
      vecs[1] = CTOBPTR (pv.fh2);
    }

  return res;
}
