summaryrefslogtreecommitdiffstats
path: root/fs/ioctl.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1994-11-28 11:59:19 +0000
committer <ralf@linux-mips.org>1994-11-28 11:59:19 +0000
commit1513ff9b7899ab588401c89db0e99903dbf5f886 (patch)
treef69cc81a940a502ea23d664c3ffb2d215a479667 /fs/ioctl.c
Import of Linus's Linux 1.1.68
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r--fs/ioctl.c99
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, &current->files->close_on_exec);
+ return 0;
+
+ case FIONCLEX:
+ FD_CLR(fd, &current->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;
+ }
+}