ioctl.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:2k
- /*
- * linux/fs/ioctl.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
- #include <linux/mm.h>
- #include <linux/smp_lock.h>
- #include <linux/file.h>
- #include <asm/uaccess.h>
- #include <asm/ioctls.h>
- static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
- {
- int error;
- int block;
- struct inode * inode = filp->f_dentry->d_inode;
- switch (cmd) {
- case FIBMAP:
- {
- struct address_space *mapping = inode->i_mapping;
- int res;
- /* do we support this mess? */
- if (!mapping->a_ops->bmap)
- return -EINVAL;
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
- if ((error = get_user(block, (int *) arg)) != 0)
- return error;
- res = mapping->a_ops->bmap(mapping, block);
- return put_user(res, (int *) arg);
- }
- case FIGETBSZ:
- if (inode->i_sb == NULL)
- return -EBADF;
- return put_user(inode->i_sb->s_blocksize, (int *) arg);
- case FIONREAD:
- return put_user(inode->i_size - filp->f_pos, (int *) arg);
- }
- if (filp->f_op && filp->f_op->ioctl)
- return filp->f_op->ioctl(inode, filp, cmd, arg);
- return -ENOTTY;
- }
- asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
- {
- struct file * filp;
- unsigned int flag;
- int on, error = -EBADF;
- filp = fget(fd);
- if (!filp)
- goto out;
- error = 0;
- lock_kernel();
- switch (cmd) {
- case FIOCLEX:
- set_close_on_exec(fd, 1);
- break;
- case FIONCLEX:
- set_close_on_exec(fd, 0);
- break;
- case FIONBIO:
- if ((error = get_user(on, (int *)arg)) != 0)
- break;
- flag = O_NONBLOCK;
- #ifdef __sparc__
- /* SunOS compatibility item. */
- if(O_NONBLOCK != O_NDELAY)
- flag |= O_NDELAY;
- #endif
- if (on)
- filp->f_flags |= flag;
- else
- filp->f_flags &= ~flag;
- break;
- case FIOASYNC:
- if ((error = get_user(on, (int *)arg)) != 0)
- break;
- flag = on ? FASYNC : 0;
- /* Did FASYNC state change ? */
- if ((flag ^ filp->f_flags) & FASYNC) {
- if (filp->f_op && filp->f_op->fasync)
- error = filp->f_op->fasync(fd, filp, on);
- else error = -ENOTTY;
- }
- if (error != 0)
- break;
- if (on)
- filp->f_flags |= FASYNC;
- else
- filp->f_flags &= ~FASYNC;
- break;
- default:
- error = -ENOTTY;
- if (S_ISREG(filp->f_dentry->d_inode->i_mode))
- error = file_ioctl(filp, cmd, arg);
- else if (filp->f_op && filp->f_op->ioctl)
- error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
- }
- unlock_kernel();
- fput(filp);
- out:
- return error;
- }