root/fs/fcntl.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dupfd
  2. sys_dup2
  3. sys_dup
  4. sys_fcntl

   1 /*
   2  *  linux/fs/fcntl.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 #include <asm/segment.h>
   8 
   9 #include <linux/sched.h>
  10 #include <linux/kernel.h>
  11 #include <linux/errno.h>
  12 #include <linux/stat.h>
  13 #include <linux/fcntl.h>
  14 #include <linux/string.h>
  15 
  16 extern int sys_close(int fd);
  17 extern int fcntl_getlk(unsigned int, struct flock *);
  18 extern int fcntl_setlk(unsigned int, unsigned int, struct flock *);
  19 
  20 static int dupfd(unsigned int fd, unsigned int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  21 {
  22         if (fd >= NR_OPEN || !current->filp[fd])
  23                 return -EBADF;
  24         if (arg >= NR_OPEN)
  25                 return -EINVAL;
  26         while (arg < NR_OPEN)
  27                 if (current->filp[arg])
  28                         arg++;
  29                 else
  30                         break;
  31         if (arg >= NR_OPEN)
  32                 return -EMFILE;
  33         FD_CLR(arg, &current->close_on_exec);
  34         (current->filp[arg] = current->filp[fd])->f_count++;
  35         return arg;
  36 }
  37 
  38 int sys_dup2(unsigned int oldfd, unsigned int newfd)
     /* [previous][next][first][last][top][bottom][index][help] */
  39 {
  40         if (oldfd >= NR_OPEN || !current->filp[oldfd])
  41                 return -EBADF;
  42         if (newfd == oldfd)
  43                 return newfd;
  44         sys_close(newfd);
  45         return dupfd(oldfd,newfd);
  46 }
  47 
  48 int sys_dup(unsigned int fildes)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50         return dupfd(fildes,0);
  51 }
  52 
  53 int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {       
  55         struct file * filp;
  56         extern int sock_fcntl (struct file *, unsigned int cmd,
  57                                unsigned long arg);
  58         if (fd >= NR_OPEN || !(filp = current->filp[fd]))
  59                 return -EBADF;
  60         switch (cmd) {
  61                 case F_DUPFD:
  62                         return dupfd(fd,arg);
  63                 case F_GETFD:
  64                         return FD_ISSET(fd, &current->close_on_exec);
  65                 case F_SETFD:
  66                         if (arg&1)
  67                                 FD_SET(fd, &current->close_on_exec);
  68                         else
  69                                 FD_CLR(fd, &current->close_on_exec);
  70                         return 0;
  71                 case F_GETFL:
  72                         return filp->f_flags;
  73                 case F_SETFL:
  74                         filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
  75                         filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
  76                         return 0;
  77                 case F_GETLK:
  78                         return fcntl_getlk(fd, (struct flock *) arg);
  79                 case F_SETLK:
  80                         return fcntl_setlk(fd, cmd, (struct flock *) arg);
  81                 case F_SETLKW:
  82                         return fcntl_setlk(fd, cmd, (struct flock *) arg);
  83                 default:
  84                         /* sockets need a few special fcntls. */
  85                         if (S_ISSOCK (filp->f_inode->i_mode))
  86                           {
  87                              return (sock_fcntl (filp, cmd, arg));
  88                           }
  89                         return -EINVAL;
  90         }
  91 }

/* [previous][next][first][last][top][bottom][index][help] */