home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / fcntl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  2.6 KB  |  110 lines

  1. /*
  2.  *  linux/fs/fcntl.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. #include <asm/segment.h>
  12.  
  13. #include <linux/sched.h>
  14. #include <linux/kernel.h>
  15. #include <linux/errno.h>
  16. #include <linux/stat.h>
  17. #include <linux/fcntl.h>
  18. #include <linux/string.h>
  19.  
  20. extern int fcntl_getlk(unsigned int, struct flock *);
  21. extern int fcntl_setlk(unsigned int, unsigned int, struct flock *);
  22. extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg);
  23.  
  24. static int dupfd(unsigned int fd, unsigned int arg)
  25. {
  26.     if (fd >= NR_OPEN || !current->filp[fd])
  27.         return -EBADF;
  28.     if (arg >= NR_OPEN)
  29.         return -EINVAL;
  30.     while (arg < NR_OPEN)
  31.         if (current->filp[arg])
  32.             arg++;
  33.         else
  34.             break;
  35.     if (arg >= NR_OPEN)
  36.         return -EMFILE;
  37.     FD_CLR(arg, ¤t->close_on_exec);
  38.     (current->filp[arg] = current->filp[fd])->f_count++;
  39.     return arg;
  40. }
  41.  
  42. asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
  43. {
  44.     if (oldfd >= NR_OPEN || !current->filp[oldfd])
  45.         return -EBADF;
  46.     if (newfd == oldfd)
  47.         return newfd;
  48.     /*
  49.      * errno's for dup2() are slightly different than for fcntl(F_DUPFD)
  50.      * for historical reasons.
  51.      */
  52.     if (newfd > NR_OPEN)    /* historical botch - should have been >= */
  53.         return -EBADF;    /* dupfd() would return -EINVAL */
  54. #if 1
  55.     if (newfd == NR_OPEN)
  56.         return -EBADF;    /* dupfd() does return -EINVAL and that may
  57.                  * even be the standard!  But that is too
  58.                  * weird for now.
  59.                  */
  60. #endif
  61.     sys_close(newfd);
  62.     return dupfd(oldfd,newfd);
  63. }
  64.  
  65. asmlinkage int sys_dup(unsigned int fildes)
  66. {
  67.     return dupfd(fildes,0);
  68. }
  69.  
  70. asmlinkage int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
  71. {    
  72.     struct file * filp;
  73.  
  74.     if (fd >= NR_OPEN || !(filp = current->filp[fd]))
  75.         return -EBADF;
  76.     switch (cmd) {
  77.         case F_DUPFD:
  78.             return dupfd(fd,arg);
  79.         case F_GETFD:
  80.             return FD_ISSET(fd, ¤t->close_on_exec);
  81.         case F_SETFD:
  82.             if (arg&1)
  83.                 FD_SET(fd, ¤t->close_on_exec);
  84.             else
  85.                 FD_CLR(fd, ¤t->close_on_exec);
  86.             return 0;
  87.         case F_GETFL:
  88.             return filp->f_flags;
  89.         case F_SETFL:
  90.             filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
  91.             filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
  92.             return 0;
  93.         case F_GETLK:
  94.             return fcntl_getlk(fd, (struct flock *) arg);
  95.         case F_SETLK:
  96.             return fcntl_setlk(fd, cmd, (struct flock *) arg);
  97.         case F_SETLKW:
  98.             return fcntl_setlk(fd, cmd, (struct flock *) arg);
  99.         default:
  100.             /* sockets need a few special fcntls. */
  101.             if (S_ISSOCK (filp->f_inode->i_mode))
  102.               {
  103. #if 0                  
  104.                  return (sock_fcntl (filp, cmd, arg));
  105. #endif
  106.               }
  107.             return -EINVAL;
  108.     }
  109. }
  110.