/*
 *  This file is part of ixemul.library for the Amiga.
 *  Copyright (C) 1991, 1992  Markus M. Wild
 *  Portions Copyright (C) 1994 Rafael W. Luebbert
 *  Portions Copyright (C) 1995 Jeff Shepherd
 *
 *  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.
 *  $Id$
 *
 *  $Log$
 */
#define KERNEL
#include <library/ixemul.h>

/*
 * Allocate a user file descriptor.
 */
int
ufalloc(int want, int *result)
{
  for (; want < NOFILE; want++)
    {
      if (u.u_ofile[want] == NULL)
	{
	  u.u_pofile[want] = 0;
	  if (want > u.u_lastfile) u.u_lastfile = want;

	  *result = want;
	  return 0;
	}
    }
  return EMFILE;
}



/*
 * Allocate a user file descriptor
 * and a file structure.
 * Initialize the descriptor
 * to point at the file structure.
 */
int
falloc(struct file **resultfp, int *resultfd)
{
  register struct file *fp;
  int error, i;

  if (error = ufalloc(*resultfd, &i))  /* Change *resultfd used to be 0 */
    return (error);

  ix_lock_base ();

  if (ix.ix_lastf == 0)
    ix.ix_lastf = ix.ix_file_tab;

  for (fp = ix.ix_lastf; fp < ix.ix_fileNFILE; fp++)
    if (fp->f_count == 0)
      goto slot;

  for (fp = ix.ix_file_tab; fp < ix.ix_lastf; fp++)
    if (fp->f_count == 0)
      goto slot;

  /* YES I know.. it's not optimal, we should resize the table...
   * unfortunately all code accessing file structures will then have
   * to be changed as well, and this is a job for later improvement,
   * first goal is to get this baby working... */
  ix_panic ("ixemul.library file table full!");
  error = ENFILE;
  goto do_ret;

slot:
  u.u_ofile[i] = fp;
  fp->f_name = 0;
  fp->f_count = 1;
  fp->f_type = 0;		/* inexistant type ;-) */
  fp->f_async_buf = 0;
  fp->f_async_len = 0;
  ix.ix_lastf = fp + 1;
  if (resultfp)
    *resultfp = fp;
  if (resultfd)
    *resultfd = i;

  error = 0;

do_ret:
  ix_unlock_base();

  return error;
}

