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