Import 2.3.7pre9
[davej-history.git] / fs / ioctl.c
blob8d18e453af31196c9fa1008bcc568d42991259d6
1 /*
2 * linux/fs/ioctl.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 #include <linux/mm.h>
8 #include <linux/smp_lock.h>
9 #include <linux/file.h>
11 #include <asm/uaccess.h>
13 static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
15 int error;
16 int block;
17 struct inode * inode = filp->f_dentry->d_inode;
19 switch (cmd) {
20 case FIBMAP:
21 if (inode->i_op == NULL)
22 return -EBADF;
23 if (inode->i_op->bmap == NULL)
24 return -EINVAL;
25 if ((error = get_user(block, (int *) arg)) != 0)
26 return error;
27 block = inode->i_op->bmap(inode,block);
28 return put_user(block, (int *) arg);
29 case FIGETBSZ:
30 if (inode->i_sb == NULL)
31 return -EBADF;
32 return put_user(inode->i_sb->s_blocksize, (int *) arg);
33 case FIONREAD:
34 return put_user(inode->i_size - filp->f_pos, (int *) arg);
36 if (filp->f_op && filp->f_op->ioctl)
37 return filp->f_op->ioctl(inode, filp, cmd, arg);
38 return -ENOTTY;
42 asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
44 struct file * filp;
45 unsigned int flag;
46 int on, error = -EBADF;
48 lock_kernel();
49 filp = fget(fd);
50 if (!filp)
51 goto out;
52 error = 0;
53 switch (cmd) {
54 case FIOCLEX:
55 FD_SET(fd, &current->files->close_on_exec);
56 break;
58 case FIONCLEX:
59 FD_CLR(fd, &current->files->close_on_exec);
60 break;
62 case FIONBIO:
63 if ((error = get_user(on, (int *)arg)) != 0)
64 break;
65 flag = O_NONBLOCK;
66 #ifdef __sparc__
67 /* SunOS compatibility item. */
68 if(O_NONBLOCK != O_NDELAY)
69 flag |= O_NDELAY;
70 #endif
71 if (on)
72 filp->f_flags |= flag;
73 else
74 filp->f_flags &= ~flag;
75 break;
77 case FIOASYNC:
78 if ((error = get_user(on, (int *)arg)) != 0)
79 break;
80 flag = on ? FASYNC : 0;
82 /* Did FASYNC state change ? */
83 if ((flag ^ filp->f_flags) & FASYNC) {
84 if (filp->f_op && filp->f_op->fasync)
85 filp->f_op->fasync(fd, filp, on);
87 if (on)
88 filp->f_flags |= FASYNC;
89 else
90 filp->f_flags &= ~FASYNC;
91 break;
93 default:
94 error = -ENOTTY;
95 if (!filp->f_dentry || !filp->f_dentry->d_inode)
96 error = -ENOENT;
97 else if (S_ISREG(filp->f_dentry->d_inode->i_mode))
98 error = file_ioctl(filp, cmd, arg);
99 else if (filp->f_op && filp->f_op->ioctl)
100 error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
102 fput(filp);
104 out:
105 unlock_kernel();
106 return error;