linux-old/fs/ioctl.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/ioctl.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 */
   6
   7#include <linux/mm.h>
   8#include <linux/smp_lock.h>
   9#include <linux/file.h>
  10
  11#include <asm/uaccess.h>
  12
  13static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
  14{
  15        int error;
  16        int block;
  17        struct inode * inode = filp->f_dentry->d_inode;
  18
  19        switch (cmd) {
  20                case FIBMAP:
  21                        if (!capable(CAP_SYS_RAWIO))
  22                                return -EPERM;
  23                        if (inode->i_op == NULL)
  24                                return -EBADF;
  25                        if (inode->i_op->bmap == NULL)
  26                                return -EINVAL;
  27                        if ((error = get_user(block, (int *) arg)) != 0)
  28                                return error;
  29                        block = inode->i_op->bmap(inode,block);
  30                        return put_user(block, (int *) arg);
  31                case FIGETBSZ:
  32                        if (inode->i_sb == NULL)
  33                                return -EBADF;
  34                        return put_user(inode->i_sb->s_blocksize, (int *) arg);
  35                case FIONREAD:
  36                        return put_user(inode->i_size - filp->f_pos, (int *) arg);
  37        }
  38        if (filp->f_op && filp->f_op->ioctl)
  39                return filp->f_op->ioctl(inode, filp, cmd, arg);
  40        return -ENOTTY;
  41}
  42
  43
  44asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
  45{       
  46        struct file * filp;
  47        unsigned int flag;
  48        int on, error = -EBADF;
  49
  50        lock_kernel();
  51        filp = fget(fd);
  52        if (!filp)
  53                goto out;
  54        error = 0;
  55        switch (cmd) {
  56                case FIOCLEX:
  57                        FD_SET(fd, current->files->close_on_exec);
  58                        break;
  59
  60                case FIONCLEX:
  61                        FD_CLR(fd, current->files->close_on_exec);
  62                        break;
  63
  64                case FIONBIO:
  65                        if ((error = get_user(on, (int *)arg)) != 0)
  66                                break;
  67                        flag = O_NONBLOCK;
  68#ifdef __sparc__
  69                        /* SunOS compatibility item. */
  70                        if(O_NONBLOCK != O_NDELAY)
  71                                flag |= O_NDELAY;
  72#endif
  73                        if (on)
  74                                filp->f_flags |= flag;
  75                        else
  76                                filp->f_flags &= ~flag;
  77                        break;
  78
  79                case FIOASYNC:
  80                        if ((error = get_user(on, (int *)arg)) != 0)
  81                                break;
  82                        flag = on ? FASYNC : 0;
  83
  84                        /* Did FASYNC state change ? */
  85                        if ((flag ^ filp->f_flags) & FASYNC) {
  86                                if (filp->f_op && filp->f_op->fasync)
  87                                        error = filp->f_op->fasync(fd, filp, on);
  88                                else error = -ENOTTY;
  89                        }
  90                        if (error != 0)
  91                                break;
  92
  93                        if (on)
  94                                filp->f_flags |= FASYNC;
  95                        else
  96                                filp->f_flags &= ~FASYNC;
  97                        break;
  98
  99                default:
 100                        error = -ENOTTY;
 101                        if (!filp->f_dentry || !filp->f_dentry->d_inode)
 102                                error = -ENOENT;
 103                        else if (S_ISREG(filp->f_dentry->d_inode->i_mode))
 104                                error = file_ioctl(filp, cmd, arg);
 105                        else if (filp->f_op && filp->f_op->ioctl)
 106                                error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
 107        }
 108        fput(filp);
 109
 110out:
 111        unlock_kernel();
 112        return error;
 113}
 114
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.