home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / library / kern_descrip.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  9KB  |  371 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  kern_descrip.c,v 1.1.1.1 1994/04/04 04:30:42 amiga Exp
  20.  *
  21.  *  kern_descrip.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:42  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.2  1992/07/04  19:19:04  mwild
  26.  *  add support for F_INTERNALIZE/F_EXTERNALIZE, which are used by IXPIPE
  27.  *  and execve().
  28.  *
  29.  * Revision 1.1  1992/05/14  19:55:40  mwild
  30.  * Initial revision
  31.  *
  32.  *
  33.  *  Since the code originated from Berkeley, the following copyright
  34.  *  header applies as well. The code has been changed, it's not the
  35.  *  original Berkeley code!
  36.  */
  37.  
  38. /*
  39.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  40.  * All rights reserved.
  41.  *
  42.  * Redistribution is only permitted until one year after the first shipment
  43.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  44.  * binary forms are permitted provided that: (1) source distributions retain
  45.  * this entire copyright notice and comment, and (2) distributions including
  46.  * binaries display the following acknowledgement:  This product includes
  47.  * software developed by the University of California, Berkeley and its
  48.  * contributors'' in the documentation or other materials provided with the
  49.  * distribution and in all advertising materials mentioning features or use
  50.  * of this software.  Neither the name of the University nor the names of
  51.  * its contributors may be used to endorse or promote products derived from
  52.  * this software without specific prior written permission.
  53.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  54.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  55.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  56.  *
  57.  *    @(#)kern_descrip.c    7.16 (Berkeley) 6/28/90
  58.  */
  59.  
  60. #define _KERNEL
  61. #include "ixemul.h"
  62. #include "kprintf.h"
  63. #include <sys/socket.h>
  64. #include <sys/ioctl.h>
  65. #include <string.h>
  66.  
  67. /*
  68.  * Descriptor management.
  69.  */
  70.  
  71. /*
  72.  * System calls on descriptors.
  73.  */
  74. /* ARGSUSED */
  75. int
  76. getdtablesize (void)
  77. {
  78.   return NOFILE;
  79. }
  80.  
  81. /*
  82.  * Duplicate a file descriptor.
  83.  */
  84. /* ARGSUSED */
  85. int
  86. dup (unsigned i)
  87. {
  88.   struct file *fp;
  89.   int fd, error;
  90.  
  91.   if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
  92.     {
  93.       errno = EBADF;
  94.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  95.       return -1;
  96.     }
  97.  
  98.   if ((error = ufalloc (0, &fd)))
  99.     {
  100.       errno = error;
  101.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  102.       return -1;
  103.     }
  104.  
  105.   u.u_ofile[fd] = fp;
  106.   u.u_pofile[fd] = u.u_pofile[i] &~ UF_EXCLOSE;
  107.   fp->f_count++;
  108.  
  109.   if (fd > u.u_lastfile) u.u_lastfile = fd;
  110.  
  111.   return fd;
  112. }
  113.  
  114. /*
  115.  * Duplicate a file descriptor to a particular value.
  116.  */
  117. /* ARGSUSED */
  118. int
  119. dup2 (unsigned i, unsigned j)
  120. {
  121.   register struct file *fp;
  122.   int old_err;
  123.  
  124.   if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
  125.     {
  126.       errno = EBADF;
  127.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  128.       return -1;
  129.     }
  130.  
  131.   if (j < 0 || j >= NOFILE)
  132.     {
  133.       errno = EBADF;
  134.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  135.       return -1;
  136.     }
  137.  
  138.   if (i == j) return (int)j;
  139.  
  140.   ix_lock_base ();
  141.  
  142.   old_err = errno;
  143.   if (u.u_ofile[j] && u.u_ofile[j]->f_close)
  144.     u.u_ofile[j]->f_close (u.u_ofile[j]);
  145.  
  146.   u.u_ofile[j] = fp;
  147.   u.u_pofile[j] = u.u_pofile[i] &~ UF_EXCLOSE;
  148.   fp->f_count++;
  149.   if (j > u.u_lastfile)
  150.     u.u_lastfile = j;
  151.   
  152.   ix_unlock_base ();
  153.  
  154.   /*
  155.    * dup2() must suceed even though the close had an error.
  156.    */
  157.   errno = old_err;    /* XXX */
  158.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  159.   return (int)j;
  160. }
  161.  
  162. /*
  163.  * The file control system call.
  164.  */
  165. /* ARGSUSED */
  166. int
  167. fcntl(int fdes, int cmd, int arg)
  168. {
  169.   register struct file *fp;
  170.   register char *pop;
  171.   int i, error;
  172.  
  173.   /* F_INTERNALIZE doesn't need a valid descriptor. Check for this first */
  174.   if (cmd == F_INTERNALIZE)
  175.     {
  176.       if ((error = ufalloc (0, &i)))
  177.         {
  178.           errno = error;
  179.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  180.           return -1;
  181.         }
  182.       fp = (struct file *) arg;
  183.       u.u_ofile[i] = fp;
  184.       u.u_pofile[i] = 0;
  185.       fp->f_count++;
  186.       return i;
  187.     }
  188.  
  189.  
  190.   if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
  191.     {
  192.       errno = EBADF;
  193.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  194.       return -1;
  195.     }
  196.  
  197.   pop = &u.u_pofile[fdes];
  198.   switch (cmd) 
  199.     {
  200.       case F_DUPFD:
  201.     if (arg < 0 || arg >= NOFILE)
  202.       {
  203.         errno = EINVAL; 
  204.         KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  205.         return -1;
  206.       }
  207.     if ((error = ufalloc (arg, &i)))
  208.       {
  209.         errno = error;
  210.         KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  211.         return -1;
  212.       }
  213.     ix_lock_base ();
  214.     u.u_ofile[i] = fp;
  215.     u.u_pofile[i] = *pop &~ UF_EXCLOSE;
  216.     fp->f_count++;
  217.     ix_unlock_base ();
  218.     if (i > u.u_lastfile) u.u_lastfile = i;
  219.     return i;
  220.  
  221.       case F_GETFD:
  222.     return *pop & 1;
  223.  
  224.       case F_SETFD:
  225.     *pop = (*pop &~ 1) | (arg & 1);
  226.     return 0;
  227.  
  228.       case F_GETFL:
  229.     return OFLAGS(fp->f_flags);
  230.  
  231.       case F_SETFL:
  232.     fp->f_flags &= ~FCNTLFLAGS;
  233.     fp->f_flags |= FFLAGS(arg) & FCNTLFLAGS;
  234.     if (fp->f_type == DTYPE_SOCKET)
  235.     {
  236.       arg = (fp->f_flags & FASYNC) ? 1 : 0;
  237.       ioctl(fdes, FIOASYNC, &arg);
  238.       arg = (fp->f_flags & FNONBLOCK) ? 1 : 0;
  239.       ioctl(fdes, FIONBIO, &arg);
  240.     }
  241.     return 0;
  242.  
  243.       case F_EXTERNALIZE:
  244.         return (int)fp;
  245.  
  246.       default:
  247.         errno = EINVAL;
  248.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  249.     return -1;
  250.     }
  251.     /* NOTREACHED */
  252. }
  253.  
  254. /*
  255.  * Return status information about a file descriptor.
  256.  */
  257. /* ARGSUSED */
  258. int
  259. fstat (int fdes, struct stat *sb)
  260. {
  261.   struct file *fp;
  262.  
  263.   if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
  264.     {
  265.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  266.       errno = EBADF;
  267.       return -1;
  268.     }
  269.  
  270.   /* I found this code from the AmiTCP sdk. It *should* work with AS225 */
  271.   if (fp->f_type == DTYPE_SOCKET && u.u_ixnetbase)
  272.     return netcall(NET__fstat, fp, sb);
  273.  
  274.   /* if this file is writable, then it's quite probably that the stat buffer
  275.      information stored at open time is no longer valid. So if the file really
  276.      is a file, update that information */
  277.   if ((fp->f_flags & FWRITE) && fp->f_type == DTYPE_FILE)
  278.     __fstat (fp);
  279.  
  280.   *sb = fp->f_stb;
  281.   return 0;
  282. }
  283.  
  284. /*
  285.  * Allocate a user file descriptor.
  286.  */
  287. int
  288. ufalloc(int want, int *result)
  289. {
  290.   for (; want < NOFILE; want++) 
  291.     {
  292.       if (u.u_ofile[want] == NULL) 
  293.         {
  294.       u.u_pofile[want] = 0;
  295.       if (want > u.u_lastfile) u.u_lastfile = want;
  296.             
  297.       *result = want;
  298.       return 0;
  299.     }
  300.     }
  301.   return EMFILE;
  302. }
  303.  
  304. /*
  305.  * Allocate a user file descriptor
  306.  * and a file structure.
  307.  * Initialize the descriptor
  308.  * to point at the file structure.
  309.  */
  310. int
  311. falloc(struct file **resultfp, int *resultfd)
  312. {
  313.   register struct file *fp;
  314.   int error, i;
  315.  
  316.   if ((error = ufalloc(0, &i)))
  317.     return (error);
  318.  
  319.   ix_lock_base ();
  320.  
  321.   if (ix.ix_lastf == 0)
  322.     ix.ix_lastf = ix.ix_file_tab;
  323.  
  324.   for (fp = ix.ix_lastf; fp < ix.ix_fileNFILE; fp++)
  325.     if (fp->f_count == 0)
  326.       goto slot;
  327.  
  328.   for (fp = ix.ix_file_tab; fp < ix.ix_lastf; fp++)
  329.     if (fp->f_count == 0)
  330.       goto slot;
  331.  
  332.   /* YES I know.. it's not optimal, we should resize the table...
  333.    * unfortunately all code accessing file structures will then have
  334.    * to be changed as well, and this is a job for later improvement,
  335.    * first goal is to get this baby working... */
  336.   ix_warning("ixemul.library file table full!");
  337.   error = ENFILE;
  338.   goto do_ret;
  339.  
  340. slot:
  341.   u.u_ofile[i] = fp;
  342.   fp->f_name = 0;
  343.   fp->f_count = 1;
  344.   fp->f_type = 0;        /* inexistant type ;-) */
  345.   memset(&fp->f__fh, 0, sizeof(fp->f__fh));
  346.   ix.ix_lastf = fp + 1;
  347.   if (resultfp)
  348.     *resultfp = fp;
  349.   if (resultfd)
  350.     *resultfd = i;
  351.  
  352.   error = 0;
  353.  
  354. do_ret:
  355.   ix_unlock_base();
  356.  
  357.   return error;
  358. }
  359.  
  360.  
  361. /*
  362.  * Apply an advisory lock on a file descriptor.
  363.  */
  364. /* ARGSUSED */
  365. int
  366. flock (int fdes, int how)
  367. {
  368.   return 0;    /* always succeed */
  369. }
  370.  
  371.