Import 2.3.12pre9
[davej-history.git] / fs / ioctl.c
blob54e9e94cdc4bb45dc449f7701df4d1ce2717ff30
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:
22 struct buffer_head tmp;
24 if (inode->i_op == NULL)
25 return -EBADF;
26 if (inode->i_op->get_block == NULL)
27 return -EINVAL;
28 if (!capable(CAP_SYS_RAWIO))
29 return -EPERM;
30 if ((error = get_user(block, (int *) arg)) != 0)
31 return error;
33 tmp.b_state = 0;
34 tmp.b_blocknr = 0;
35 inode->i_op->get_block(inode, block, &tmp, 0);
36 return put_user(tmp.b_blocknr, (int *) arg);
38 case FIGETBSZ:
39 if (inode->i_sb == NULL)
40 return -EBADF;
41 return put_user(inode->i_sb->s_blocksize, (int *) arg);
42 case FIONREAD:
43 return put_user(inode->i_size - filp->f_pos, (int *) arg);
45 if (filp->f_op && filp->f_op->ioctl)
46 return filp->f_op->ioctl(inode, filp, cmd, arg);
47 return -ENOTTY;
51 asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
53 struct file * filp;
54 unsigned int flag;
55 int on, error = -EBADF;
57 filp = fget(fd);
58 if (!filp)
59 goto out;
60 error = 0;
61 lock_kernel();
62 switch (cmd) {
63 case FIOCLEX:
64 FD_SET(fd, current->files->close_on_exec);
65 break;
67 case FIONCLEX:
68 FD_CLR(fd, current->files->close_on_exec);
69 break;
71 case FIONBIO:
72 if ((error = get_user(on, (int *)arg)) != 0)
73 break;
74 flag = O_NONBLOCK;
75 #ifdef __sparc__
76 /* SunOS compatibility item. */
77 if(O_NONBLOCK != O_NDELAY)
78 flag |= O_NDELAY;
79 #endif
80 if (on)
81 filp->f_flags |= flag;
82 else
83 filp->f_flags &= ~flag;
84 break;
86 case FIOASYNC:
87 if ((error = get_user(on, (int *)arg)) != 0)
88 break;
89 flag = on ? FASYNC : 0;
91 /* Did FASYNC state change ? */
92 if ((flag ^ filp->f_flags) & FASYNC) {
93 if (filp->f_op && filp->f_op->fasync)
94 filp->f_op->fasync(fd, filp, on);
96 if (on)
97 filp->f_flags |= FASYNC;
98 else
99 filp->f_flags &= ~FASYNC;
100 break;
102 default:
103 error = -ENOTTY;
104 if (!filp->f_dentry || !filp->f_dentry->d_inode)
105 error = -ENOENT;
106 else 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);
111 fput(filp);
112 unlock_kernel();
114 out:
115 return error;