home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / posix / fcntl / fcntl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-19  |  1.2 KB  |  73 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <libc/stubs.h>
  4. #include <dpmi.h>
  5. #include <errno.h>
  6. #include <stdarg.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <sys/fsext.h>
  10.  
  11. static int
  12. is_used_fd(int fd)
  13. {
  14.   __dpmi_regs regs;
  15.  
  16.   regs.x.ax = 0x4400;
  17.   regs.x.bx = fd;
  18.   __dpmi_int(0x21, ®s);
  19.   if (regs.x.flags & 1)
  20.     return 0;
  21.  
  22.   return 1;
  23. }
  24.  
  25. int
  26. fcntl(int fd, int cmd, ...)
  27. {
  28.   int tofd, open_max;
  29.   va_list ap;
  30.   __FSEXT_Function *func = __FSEXT_get_function(fd);
  31.   if (func)
  32.   {
  33.     int rv;
  34.     if (func(__FSEXT_fcntl, &rv, &fd))
  35.       return rv;
  36.   }
  37.  
  38.   switch (cmd)
  39.   {
  40.   case F_DUPFD:
  41.     va_start(ap, cmd);
  42.     tofd = va_arg(ap, int);
  43.     va_end(ap);
  44.  
  45.     open_max = getdtablesize();
  46.     while (tofd < open_max)
  47.     {
  48.       if (! is_used_fd(tofd))
  49.     break;
  50.       tofd++;
  51.     }
  52.  
  53.     if (tofd >= open_max)
  54.     {
  55.       errno = EMFILE;
  56.       return -1;
  57.     }
  58.  
  59.     return dup2(fd, tofd);
  60.     
  61.   case F_GETFD:
  62.   case F_SETFD:
  63.   case F_GETFL:
  64.   case F_SETFL:
  65.     return 0;
  66.   case F_GETLK:
  67.   case F_SETLK:
  68.   case F_SETLKW:
  69.     return -1;
  70.   }
  71.   return -1;
  72. }
  73.