diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1994-11-28 11:59:19 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1994-11-28 11:59:19 +0000 |
commit | 1513ff9b7899ab588401c89db0e99903dbf5f886 (patch) | |
tree | f69cc81a940a502ea23d664c3ffb2d215a479667 /fs/ioctl.c |
Import of Linus's Linux 1.1.68
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r-- | fs/ioctl.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c new file mode 100644 index 000000000..22d0f4d10 --- /dev/null +++ b/fs/ioctl.c @@ -0,0 +1,99 @@ +/* + * linux/fs/ioctl.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include <asm/segment.h> + +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/stat.h> +#include <linux/termios.h> +#include <linux/fcntl.h> /* for f_flags values */ + +static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) +{ + int error; + int block; + + switch (cmd) { + case FIBMAP: + if (filp->f_inode->i_op == NULL) + return -EBADF; + if (filp->f_inode->i_op->bmap == NULL) + return -EINVAL; + error = verify_area(VERIFY_WRITE,(void *) arg,4); + if (error) + return error; + block = get_fs_long((long *) arg); + block = filp->f_inode->i_op->bmap(filp->f_inode,block); + put_fs_long(block,(long *) arg); + return 0; + case FIGETBSZ: + if (filp->f_inode->i_sb == NULL) + return -EBADF; + error = verify_area(VERIFY_WRITE,(void *) arg,4); + if (error) + return error; + put_fs_long(filp->f_inode->i_sb->s_blocksize, + (long *) arg); + return 0; + case FIONREAD: + error = verify_area(VERIFY_WRITE,(void *) arg,4); + if (error) + return error; + put_fs_long(filp->f_inode->i_size - filp->f_pos, + (long *) arg); + return 0; + } + if (filp->f_op && filp->f_op->ioctl) + return filp->f_op->ioctl(filp->f_inode, filp, cmd,arg); + return -EINVAL; +} + + +asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct file * filp; + int on; + + if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) + return -EBADF; + switch (cmd) { + case FIOCLEX: + FD_SET(fd, ¤t->files->close_on_exec); + return 0; + + case FIONCLEX: + FD_CLR(fd, ¤t->files->close_on_exec); + return 0; + + case FIONBIO: + on = get_fs_long((unsigned long *) arg); + if (on) + filp->f_flags |= O_NONBLOCK; + else + filp->f_flags &= ~O_NONBLOCK; + return 0; + + case FIOASYNC: /* O_SYNC is not yet implemented, + but it's here for completeness. */ + on = get_fs_long ((unsigned long *) arg); + if (on) + filp->f_flags |= O_SYNC; + else + filp->f_flags &= ~O_SYNC; + return 0; + + default: + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode)) + return file_ioctl(filp,cmd,arg); + + if (filp->f_op && filp->f_op->ioctl) + return filp->f_op->ioctl(filp->f_inode, filp, cmd,arg); + + return -EINVAL; + } +} |