home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / library / rcs / kern_descrip.c,v < prev    next >
Encoding:
Text File  |  1992-07-04  |  7.9 KB  |  400 lines

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