4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/syscalls.h>
9 #include <linux/smp_lock.h>
10 #include <linux/capability.h>
11 #include <linux/file.h>
13 #include <linux/security.h>
14 #include <linux/module.h>
15 #include <linux/kallsyms.h>
17 #include <asm/uaccess.h>
18 #include <asm/ioctls.h>
20 static long do_ioctl(struct file
*filp
, unsigned int cmd
,
29 if (filp
->f_op
->unlocked_ioctl
) {
30 error
= filp
->f_op
->unlocked_ioctl(filp
, cmd
, arg
);
31 if (error
== -ENOIOCTLCMD
)
34 } else if ((f
= filp
->f_op
->ioctl
)) {
36 if (!filp
->f_op
->ioctl
) {
37 printk("%s: ioctl %p disappeared\n", __FUNCTION__
, f
);
38 print_symbol("symbol: %s\n", (unsigned long)f
);
41 error
= filp
->f_op
->ioctl(filp
->f_path
.dentry
->d_inode
,
51 static int file_ioctl(struct file
*filp
, unsigned int cmd
,
56 struct inode
* inode
= filp
->f_path
.dentry
->d_inode
;
57 int __user
*p
= (int __user
*)arg
;
62 struct address_space
*mapping
= filp
->f_mapping
;
64 /* do we support this mess? */
65 if (!mapping
->a_ops
->bmap
)
67 if (!capable(CAP_SYS_RAWIO
))
69 if ((error
= get_user(block
, p
)) != 0)
73 res
= mapping
->a_ops
->bmap(mapping
, block
);
75 return put_user(res
, p
);
78 return put_user(inode
->i_sb
->s_blocksize
, p
);
80 return put_user(i_size_read(inode
) - filp
->f_pos
, p
);
83 return do_ioctl(filp
, cmd
, arg
);
87 * When you add any new common ioctls to the switches above and below
88 * please update compat_sys_ioctl() too.
90 * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
91 * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
93 int vfs_ioctl(struct file
*filp
, unsigned int fd
, unsigned int cmd
, unsigned long arg
)
100 set_close_on_exec(fd
, 1);
104 set_close_on_exec(fd
, 0);
108 if ((error
= get_user(on
, (int __user
*)arg
)) != 0)
112 /* SunOS compatibility item. */
113 if(O_NONBLOCK
!= O_NDELAY
)
117 filp
->f_flags
|= flag
;
119 filp
->f_flags
&= ~flag
;
123 if ((error
= get_user(on
, (int __user
*)arg
)) != 0)
125 flag
= on
? FASYNC
: 0;
127 /* Did FASYNC state change ? */
128 if ((flag
^ filp
->f_flags
) & FASYNC
) {
129 if (filp
->f_op
&& filp
->f_op
->fasync
) {
131 error
= filp
->f_op
->fasync(fd
, filp
, on
);
134 else error
= -ENOTTY
;
140 filp
->f_flags
|= FASYNC
;
142 filp
->f_flags
&= ~FASYNC
;
146 if (S_ISDIR(filp
->f_path
.dentry
->d_inode
->i_mode
) ||
147 S_ISREG(filp
->f_path
.dentry
->d_inode
->i_mode
) ||
148 S_ISLNK(filp
->f_path
.dentry
->d_inode
->i_mode
)) {
149 loff_t res
= inode_get_bytes(filp
->f_path
.dentry
->d_inode
);
150 error
= copy_to_user((loff_t __user
*)arg
, &res
, sizeof(res
)) ? -EFAULT
: 0;
156 if (S_ISREG(filp
->f_path
.dentry
->d_inode
->i_mode
))
157 error
= file_ioctl(filp
, cmd
, arg
);
159 error
= do_ioctl(filp
, cmd
, arg
);
165 asmlinkage
long sys_ioctl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
171 filp
= fget_light(fd
, &fput_needed
);
175 error
= security_file_ioctl(filp
, cmd
, arg
);
179 error
= vfs_ioctl(filp
, fd
, cmd
, arg
);
181 fput_light(filp
, fput_needed
);
187 * Platforms implementing 32 bit compatibility ioctl handlers in
188 * modules need this exported
191 EXPORT_SYMBOL(sys_ioctl
);