/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { int error = 0; int __user *argp = (int __user *)arg; switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: /* BKL needed to avoid races tweaking f_flags */ lock_kernel(); error = ioctl_fionbio(filp, argp); unlock_kernel(); break; case FIOASYNC: /* BKL needed to avoid races tweaking f_flags */ lock_kernel(); error = ioctl_fioasync(fd, filp, argp); unlock_kernel(); break; case FIOQSIZE: if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) || S_ISREG(filp->f_path.dentry->d_inode->i_mode) || S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) { loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode); error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; case FIFREEZE: error = ioctl_fsfreeze(filp); break; case FITHAW: error = ioctl_fsthaw(filp); break; default: if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg); else error = vfs_ioctl(filp, cmd, arg); break; } return error; }
/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { int error = 0; int __user *argp = (int __user *)arg; struct inode *inode = file_inode(filp); switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: error = ioctl_fionbio(filp, argp); break; case FIOASYNC: error = ioctl_fioasync(fd, filp, argp); break; case FIOQSIZE: if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) { loff_t res = inode_get_bytes(inode); error = copy_to_user(argp, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; case FIFREEZE: error = ioctl_fsfreeze(filp); break; case FITHAW: error = ioctl_fsthaw(filp); break; case FS_IOC_FIEMAP: return ioctl_fiemap(filp, arg); case FIGETBSZ: return put_user(inode->i_sb->s_blocksize, argp); default: if (S_ISREG(inode->i_mode)) error = file_ioctl(filp, cmd, arg); else error = vfs_ioctl(filp, cmd, arg); break; } return error; }
int sys_ioctl(int fd, int request, void *arg) { struct process *proc; proc = process_get_current(); if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) { return vfs_ioctl(proc->files[fd], request, arg); } else { printk(LOG_DEBUG, "sys_ioctl: invalid fd (%d)\n", fd); } return -1; }
static int file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); int __user *p = (int __user *)arg; switch (cmd) { case FIBMAP: return ioctl_fibmap(filp, p); case FIONREAD: return put_user(i_size_read(inode) - filp->f_pos, p); case FS_IOC_RESVSP: case FS_IOC_RESVSP64: return ioctl_preallocate(filp, p); } return vfs_ioctl(filp, cmd, arg); }
static long ovl_real_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct fd real; const struct cred *old_cred; long ret; ret = ovl_real_fdget(file, &real); if (ret) return ret; old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_ioctl(real.file, cmd, arg); revert_creds(old_cred); fdput(real); return ret; }
static int file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = filp->f_path.dentry->d_inode; int __user *p = (int __user *)arg; switch (cmd) { case FIBMAP: return ioctl_fibmap(filp, p); case FS_IOC_FIEMAP: return ioctl_fiemap(filp, arg); case FIGETBSZ: return put_user(inode->i_sb->s_blocksize, p); case FIONREAD: return put_user(i_size_read(inode) - filp->f_pos, p); } return vfs_ioctl(filp, cmd, arg); }
asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct file * filp; int error = -EBADF; int fput_needed; filp = fget_light(fd, &fput_needed); if (!filp) goto out; error = security_file_ioctl(filp, cmd, arg); if (error) goto out_fput; error = vfs_ioctl(filp, fd, cmd, arg); out_fput: fput_light(filp, fput_needed); out: return error; }
static int socket_dev_ioctl(dev_cookie cookie, int op, void *buf, size_t len) { socket_dev *s = (socket_dev *)cookie; _socket_api_args_t args; int err; // copy the args over from user space err = user_memcpy(&args, buf, min(sizeof(args), len)); if(err < 0) return err; if(s->id < 0) { switch(op) { case _SOCKET_API_CREATE: err = s->id = socket_create(args.u.create.type, args.u.create.flags); break; case _SOCKET_API_ASSOCIATE_SOCKET: s->id = args.u.associate.id; err = NO_ERROR; break; default: err = ERR_INVALID_ARGS; } } else { switch(op) { case _SOCKET_API_BIND: err = socket_bind(s->id, args.u.bind.saddr); break; case _SOCKET_API_CONNECT: err = socket_connect(s->id, args.u.connect.saddr); break; case _SOCKET_API_LISTEN: err = socket_listen(s->id); break; case _SOCKET_API_ACCEPT: { // this one is a little tricky, we have a new socket we need to associate with a file descriptor sock_id id; int fd; _socket_api_args_t new_args; char socket_dev_path[SYS_MAX_PATH_LEN]; id = socket_accept(s->id, args.u.accept.saddr); if(id < 0) { err = id; break; } // we have the new id, open a new file descriptor in user space strcpy(socket_dev_path, "/dev/net/socket"); fd = vfs_open(socket_dev_path, 0, false); if(fd < 0) { socket_close(id); err = fd; break; } // now do a special call on this file descriptor that associates it with this socket new_args.u.associate.id = id; err = vfs_ioctl(fd, _SOCKET_API_ASSOCIATE_SOCKET, &new_args, sizeof(new_args), false); if(err < 0) { socket_close(id); break; } err = fd; break; } case _SOCKET_API_RECVFROM: err = socket_recvfrom(s->id, args.u.transfer.buf, args.u.transfer.len, args.u.transfer.saddr); break; case _SOCKET_API_RECVFROM_ETC: err = socket_recvfrom_etc(s->id, args.u.transfer.buf, args.u.transfer.len, args.u.transfer.saddr, args.u.transfer.flags, args.u.transfer.timeout); break; case _SOCKET_API_SENDTO: err = socket_sendto(s->id, args.u.transfer.buf, args.u.transfer.len, args.u.transfer.saddr); break; default: err = ERR_INVALID_ARGS; } } return err; }
/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { int error = 0; int __user *argp = (int __user *)arg; switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: error = ioctl_fionbio(filp, argp); break; case FIOASYNC: error = ioctl_fioasync(fd, filp, argp); break; case FIOQSIZE: if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) || S_ISREG(filp->f_path.dentry->d_inode->i_mode) || S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) { loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode); error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; case FIFREEZE: error = ioctl_fsfreeze(filp); break; case FITHAW: error = ioctl_fsthaw(filp); break; case FS_IOC_FIEMAP: return ioctl_fiemap(filp, arg); case FIGETBSZ: { struct super_block *sb = filp->f_path.dentry->d_inode->i_sb; int __user *p = (int __user *)arg; if (sb->s_blocksize == 1ul << sb->s_blocksize_bits) return put_user(sb->s_blocksize, p); /* fail through */ } default: if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg); else error = vfs_ioctl(filp, cmd, arg); break; } return error; }
/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { int error = 0; int __user *argp = (int __user *)arg; #ifdef CONFIG_LTT_LITE char ltt_string[LTT_LITE_MAX_LOG_STRING_SIZE]; sprintf(ltt_string, "fd=%X/cmd=%X/arg=%X/pid=%d\n", fd, cmd, (int)arg, current->pid); ltt_lite_syscall_param(LTT_EV_FILE_SYSTEM_IOCTL, ltt_string, strlen(ltt_string)); sprintf(ltt_string, "f_op=%X/pid=%d\n", (int)filp->f_op, current->pid); ltt_lite_syscall_param(LTT_EV_FILE_SYSTEM_IOCTL, ltt_string, strlen(ltt_string)); #endif switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: /* BKL needed to avoid races tweaking f_flags */ lock_kernel(); error = ioctl_fionbio(filp, argp); unlock_kernel(); break; case FIOASYNC: /* BKL needed to avoid races tweaking f_flags */ lock_kernel(); error = ioctl_fioasync(fd, filp, argp); unlock_kernel(); break; case FIOQSIZE: if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) || S_ISREG(filp->f_path.dentry->d_inode->i_mode) || S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) { loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode); error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; case FIFREEZE: error = ioctl_fsfreeze(filp); break; case FITHAW: error = ioctl_fsthaw(filp); break; default: if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg); else error = vfs_ioctl(filp, cmd, arg); break; } return error; }