home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / dev / gcc / ixemulsrc.lha / ixemul / library / kern_descrip.c < prev    next >
C/C++ Source or Header  |  1996-12-26  |  9KB  |  382 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.   /* This was NOFILE, but getdtablesize is also used to determine the number
  79.      number of filehandles select() should test. And if you pass a value
  80.      larger than FD_SETSIZE to select(), you'll get fireworks. And it is very
  81.      hard to discover why your program won't work. I know: I've been through
  82.      this process twice now, so I thought I'd better fix this here by just
  83.      returning FD_SETSIZE. 
  84.      
  85.      I could also change the FD_SETSIZE macro to the value of NOFILE (changing
  86.      256 to 512), but that would be a waste of memory, and besides, in the
  87.      future the number of filehandles might become dynamic, so it wouldn't work
  88.      in any case. */
  89.   return FD_SETSIZE;
  90. }
  91.  
  92. /*
  93.  * Duplicate a file descriptor.
  94.  */
  95. /* ARGSUSED */
  96. int
  97. dup (unsigned i)
  98. {
  99.   struct file *fp;
  100.   int fd, error;
  101.  
  102.   if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
  103.     {
  104.       errno = EBADF;
  105.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  106.       return -1;
  107.     }
  108.  
  109.   if ((error = ufalloc (0, &fd)))
  110.     {
  111.       errno = error;
  112.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  113.       return -1;
  114.     }
  115.  
  116.   u.u_ofile[fd] = fp;
  117.   u.u_pofile[fd] = u.u_pofile[i] &~ UF_EXCLOSE;
  118.   fp->f_count++;
  119.  
  120.   if (fd > u.u_lastfile) u.u_lastfile = fd;
  121.  
  122.   return fd;
  123. }
  124.  
  125. /*
  126.  * Duplicate a file descriptor to a particular value.
  127.  */
  128. /* ARGSUSED */
  129. int
  130. dup2 (unsigned i, unsigned j)
  131. {
  132.   register struct file *fp;
  133.   int old_err;
  134.  
  135.   if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
  136.     {
  137.       errno = EBADF;
  138.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  139.       return -1;
  140.     }
  141.  
  142.   if (j < 0 || j >= NOFILE)
  143.     {
  144.       errno = EBADF;
  145.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  146.       return -1;
  147.     }
  148.  
  149.   if (i == j) return (int)j;
  150.  
  151.   ix_lock_base ();
  152.  
  153.   old_err = errno;
  154.   if (u.u_ofile[j] && u.u_ofile[j]->f_close)
  155.     u.u_ofile[j]->f_close (u.u_ofile[j]);
  156.  
  157.   u.u_ofile[j] = fp;
  158.   u.u_pofile[j] = u.u_pofile[i] &~ UF_EXCLOSE;
  159.   fp->f_count++;
  160.   if (j > u.u_lastfile)
  161.     u.u_lastfile = j;
  162.   
  163.   ix_unlock_base ();
  164.  
  165.   /*
  166.    * dup2() must suceed even though the close had an error.
  167.    */
  168.   errno = old_err;    /* XXX */
  169.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  170.   return (int)j;
  171. }
  172.  
  173. /*
  174.  * The file control system call.
  175.  */
  176. /* ARGSUSED */
  177. int
  178. fcntl(int fdes, int cmd, int arg)
  179. {
  180.   register struct file *fp;
  181.   register char *pop;
  182.   int i, error;
  183.  
  184.   /* F_INTERNALIZE doesn't need a valid descriptor. Check for this first */
  185.   if (cmd == F_INTERNALIZE)
  186.     {
  187.       if ((error = ufalloc (0, &i)))
  188.         {
  189.           errno = error;
  190.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  191.           return -1;
  192.         }
  193.       fp = (struct file *) arg;
  194.       u.u_ofile[i] = fp;
  195.       u.u_pofile[i] = 0;
  196.       fp->f_count++;
  197.       return i;
  198.     }
  199.  
  200.  
  201.   if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
  202.     {
  203.       errno = EBADF;
  204.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  205.       return -1;
  206.     }
  207.  
  208.   pop = &u.u_pofile[fdes];
  209.   switch (cmd) 
  210.     {
  211.       case F_DUPFD:
  212.     if (arg < 0 || arg >= NOFILE)
  213.       {
  214.         errno = EINVAL; 
  215.         KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  216.         return -1;
  217.       }
  218.     if ((error = ufalloc (arg, &i)))
  219.       {
  220.         errno = error;
  221.         KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  222.         return -1;
  223.       }
  224.     ix_lock_base ();
  225.     u.u_ofile[i] = fp;
  226.     u.u_pofile[i] = *pop &~ UF_EXCLOSE;
  227.     fp->f_count++;
  228.     ix_unlock_base ();
  229.     if (i > u.u_lastfile) u.u_lastfile = i;
  230.     return i;
  231.  
  232.       case F_GETFD:
  233.     return *pop & 1;
  234.  
  235.       case F_SETFD:
  236.     *pop = (*pop &~ 1) | (arg & 1);
  237.     return 0;
  238.  
  239.       case F_GETFL:
  240.     return OFLAGS(fp->f_flags);
  241.  
  242.       case F_SETFL:
  243.     fp->f_flags &= ~FCNTLFLAGS;
  244.     fp->f_flags |= FFLAGS(arg) & FCNTLFLAGS;
  245.     if (fp->f_type == DTYPE_SOCKET)
  246.     {
  247.       arg = (fp->f_flags & FASYNC) ? 1 : 0;
  248.       ioctl(fdes, FIOASYNC, &arg);
  249.       arg = (fp->f_flags & FNONBLOCK) ? 1 : 0;
  250.       ioctl(fdes, FIONBIO, &arg);
  251.     }
  252.     return 0;
  253.  
  254.       case F_EXTERNALIZE:
  255.         return (int)fp;
  256.  
  257.       default:
  258.         errno = EINVAL;
  259.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  260.     return -1;
  261.     }
  262.     /* NOTREACHED */
  263. }
  264.  
  265. /*
  266.  * Return status information about a file descriptor.
  267.  */
  268. /* ARGSUSED */
  269. int
  270. fstat (int fdes, struct stat *sb)
  271. {
  272.   struct file *fp;
  273.  
  274.   if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
  275.     {
  276.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  277.       errno = EBADF;
  278.       return -1;
  279.     }
  280.  
  281.   /* I found this code from the AmiTCP sdk. It *should* work with AS225 */
  282.   if (fp->f_type == DTYPE_SOCKET && u.u_ixnetbase)
  283.     return netcall(NET__fstat, fp, sb);
  284.  
  285.   /* if this file is writable, then it's quite probably that the stat buffer
  286.      information stored at open time is no longer valid. So if the file really
  287.      is a file, update that information */
  288.   if ((fp->f_flags & FWRITE) && fp->f_type == DTYPE_FILE)
  289.     __fstat (fp);
  290.  
  291.   *sb = fp->f_stb;
  292.   return 0;
  293. }
  294.  
  295. /*
  296.  * Allocate a user file descriptor.
  297.  */
  298. int
  299. ufalloc(int want, int *result)
  300. {
  301.   for (; want < NOFILE; want++) 
  302.     {
  303.       if (u.u_ofile[want] == NULL) 
  304.         {
  305.       u.u_pofile[want] = 0;
  306.       if (want > u.u_lastfile) u.u_lastfile = want;
  307.             
  308.       *result = want;
  309.       return 0;
  310.     }
  311.     }
  312.   return EMFILE;
  313. }
  314.  
  315. /*
  316.  * Allocate a user file descriptor
  317.  * and a file structure.
  318.  * Initialize the descriptor
  319.  * to point at the file structure.
  320.  */
  321. int
  322. falloc(struct file **resultfp, int *resultfd)
  323. {
  324.   register struct file *fp;
  325.   int error, i;
  326.  
  327.   if ((error = ufalloc(0, &i)))
  328.     return (error);
  329.  
  330.   ix_lock_base ();
  331.  
  332.   if (ix.ix_lastf == 0)
  333.     ix.ix_lastf = ix.ix_file_tab;
  334.  
  335.   for (fp = ix.ix_lastf; fp < ix.ix_fileNFILE; fp++)
  336.     if (fp->f_count == 0)
  337.       goto slot;
  338.  
  339.   for (fp = ix.ix_file_tab; fp < ix.ix_lastf; fp++)
  340.     if (fp->f_count == 0)
  341.       goto slot;
  342.  
  343.   /* YES I know.. it's not optimal, we should resize the table...
  344.    * unfortunately all code accessing file structures will then have
  345.    * to be changed as well, and this is a job for later improvement,
  346.    * first goal is to get this baby working... */
  347.   ix_warning("ixemul.library file table full!");
  348.   error = ENFILE;
  349.   goto do_ret;
  350.  
  351. slot:
  352.   u.u_ofile[i] = fp;
  353.   fp->f_name = 0;
  354.   fp->f_count = 1;
  355.   fp->f_type = 0;        /* inexistant type ;-) */
  356.   memset(&fp->f__fh, 0, sizeof(fp->f__fh));
  357.   ix.ix_lastf = fp + 1;
  358.   if (resultfp)
  359.     *resultfp = fp;
  360.   if (resultfd)
  361.     *resultfd = i;
  362.  
  363.   error = 0;
  364.  
  365. do_ret:
  366.   ix_unlock_base();
  367.  
  368.   return error;
  369. }
  370.  
  371.  
  372. /*
  373.  * Apply an advisory lock on a file descriptor.
  374.  */
  375. /* ARGSUSED */
  376. int
  377. flock (int fdes, int how)
  378. {
  379.   return 0;    /* always succeed */
  380. }
  381.  
  382.