ioctl32.c
来自「linux-2.4.29操作系统的源码」· C语言 代码 · 共 812 行 · 第 1/2 页
C
812 行
err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) { err = -EFAULT; } else { set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&l); set_fs (old_fs); } break; case LOOP_GET_STATUS: set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&l); set_fs (old_fs); if (!err) { err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) err = -EFAULT; } break; default: { static int count = 0; if (++count <= 20) printk("%s: Unknown loop ioctl cmd, fd(%d) " "cmd(%08x) arg(%08lx)\n", __FUNCTION__, fd, cmd, arg); } } return err;}struct blkpg_ioctl_arg32 { int op; int flags; int datalen; u32 data;}; static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg){ struct blkpg_ioctl_arg a; struct blkpg_partition p; int err; mm_segment_t old_fs = get_fs(); err = get_user(a.op, &arg->op); err |= __get_user(a.flags, &arg->flags); err |= __get_user(a.datalen, &arg->datalen); err |= __get_user((long)a.data, &arg->data); if (err) return err; switch (a.op) { case BLKPG_ADD_PARTITION: case BLKPG_DEL_PARTITION: if (a.datalen < sizeof(struct blkpg_partition)) return -EINVAL; if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) return -EFAULT; a.data = &p; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&a); set_fs (old_fs); default: return -EINVAL; } return err;}static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); int err; unsigned long val; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); if (!err && put_user((unsigned int) val, (u32 *)arg)) return -EFAULT; return err;}struct ioctl32_handler { unsigned int cmd; int (*function)(unsigned int, unsigned int, unsigned long);};struct ioctl32_list { struct ioctl32_handler handler; struct ioctl32_list *next;};#define IOCTL32_DEFAULT(cmd) { { cmd, (void *) sys_ioctl }, 0 }#define IOCTL32_HANDLER(cmd, handler) { { cmd, (void *) handler }, 0 }static struct ioctl32_list ioctl32_handler_table[] = { IOCTL32_DEFAULT(FIBMAP), IOCTL32_DEFAULT(FIGETBSZ), IOCTL32_DEFAULT(DASDAPIVER), IOCTL32_DEFAULT(BIODASDDISABLE), IOCTL32_DEFAULT(BIODASDENABLE), IOCTL32_DEFAULT(BIODASDRSRV), IOCTL32_DEFAULT(BIODASDRLSE), IOCTL32_DEFAULT(BIODASDSLCK), IOCTL32_DEFAULT(BIODASDINFO), IOCTL32_DEFAULT(BIODASDFMT), IOCTL32_DEFAULT(BLKROSET), IOCTL32_DEFAULT(BLKROGET), IOCTL32_DEFAULT(BLKRRPART), IOCTL32_DEFAULT(BLKFLSBUF), IOCTL32_DEFAULT(BLKRASET), IOCTL32_DEFAULT(BLKFRASET), IOCTL32_DEFAULT(BLKSECTSET), IOCTL32_DEFAULT(BLKSSZGET), IOCTL32_DEFAULT(BLKBSZGET), IOCTL32_DEFAULT(BLKGETSIZE64), IOCTL32_DEFAULT(BLKELVGET), IOCTL32_DEFAULT(BLKELVSET), IOCTL32_HANDLER(HDIO_GETGEO, hd_geometry_ioctl), IOCTL32_DEFAULT(TUBICMD), IOCTL32_DEFAULT(TUBOCMD), IOCTL32_DEFAULT(TUBGETI), IOCTL32_DEFAULT(TUBGETO), IOCTL32_DEFAULT(TUBSETMOD), IOCTL32_DEFAULT(TUBGETMOD), IOCTL32_DEFAULT(TCGETA), IOCTL32_DEFAULT(TCSETA), IOCTL32_DEFAULT(TCSETAW), IOCTL32_DEFAULT(TCSETAF), IOCTL32_DEFAULT(TCSBRK), IOCTL32_DEFAULT(TCSBRKP), IOCTL32_DEFAULT(TCXONC), IOCTL32_DEFAULT(TCFLSH), IOCTL32_DEFAULT(TCGETS), IOCTL32_DEFAULT(TCSETS), IOCTL32_DEFAULT(TCSETSW), IOCTL32_DEFAULT(TCSETSF), IOCTL32_DEFAULT(TIOCLINUX), IOCTL32_DEFAULT(TIOCGETD), IOCTL32_DEFAULT(TIOCSETD), IOCTL32_DEFAULT(TIOCEXCL), IOCTL32_DEFAULT(TIOCNXCL), IOCTL32_DEFAULT(TIOCCONS), IOCTL32_DEFAULT(TIOCGSOFTCAR), IOCTL32_DEFAULT(TIOCSSOFTCAR), IOCTL32_DEFAULT(TIOCSWINSZ), IOCTL32_DEFAULT(TIOCGWINSZ), IOCTL32_DEFAULT(TIOCMGET), IOCTL32_DEFAULT(TIOCMBIC), IOCTL32_DEFAULT(TIOCMBIS), IOCTL32_DEFAULT(TIOCMSET), IOCTL32_DEFAULT(TIOCPKT), IOCTL32_DEFAULT(TIOCNOTTY), IOCTL32_DEFAULT(TIOCSTI), IOCTL32_DEFAULT(TIOCOUTQ), IOCTL32_DEFAULT(TIOCSPGRP), IOCTL32_DEFAULT(TIOCGPGRP), IOCTL32_DEFAULT(TIOCSCTTY), IOCTL32_DEFAULT(TIOCGPTN), IOCTL32_DEFAULT(TIOCSPTLCK), IOCTL32_DEFAULT(TIOCGSERIAL), IOCTL32_DEFAULT(TIOCSSERIAL), IOCTL32_DEFAULT(TIOCSERGETLSR), IOCTL32_DEFAULT(FIOCLEX), IOCTL32_DEFAULT(FIONCLEX), IOCTL32_DEFAULT(FIOASYNC), IOCTL32_DEFAULT(FIONBIO), IOCTL32_DEFAULT(FIONREAD), IOCTL32_DEFAULT(PIO_FONT), IOCTL32_DEFAULT(GIO_FONT), IOCTL32_DEFAULT(KDSIGACCEPT), IOCTL32_DEFAULT(KDGETKEYCODE), IOCTL32_DEFAULT(KDSETKEYCODE), IOCTL32_DEFAULT(KIOCSOUND), IOCTL32_DEFAULT(KDMKTONE), IOCTL32_DEFAULT(KDGKBTYPE), IOCTL32_DEFAULT(KDSETMODE), IOCTL32_DEFAULT(KDGETMODE), IOCTL32_DEFAULT(KDSKBMODE), IOCTL32_DEFAULT(KDGKBMODE), IOCTL32_DEFAULT(KDSKBMETA), IOCTL32_DEFAULT(KDGKBMETA), IOCTL32_DEFAULT(KDGKBENT), IOCTL32_DEFAULT(KDSKBENT), IOCTL32_DEFAULT(KDGKBSENT), IOCTL32_DEFAULT(KDSKBSENT), IOCTL32_DEFAULT(KDGKBDIACR), IOCTL32_DEFAULT(KDSKBDIACR), IOCTL32_DEFAULT(KDGKBLED), IOCTL32_DEFAULT(KDSKBLED), IOCTL32_DEFAULT(KDGETLED), IOCTL32_DEFAULT(KDSETLED), IOCTL32_DEFAULT(GIO_SCRNMAP), IOCTL32_DEFAULT(PIO_SCRNMAP), IOCTL32_DEFAULT(GIO_UNISCRNMAP), IOCTL32_DEFAULT(PIO_UNISCRNMAP), IOCTL32_DEFAULT(PIO_FONTRESET), IOCTL32_DEFAULT(PIO_UNIMAPCLR), IOCTL32_DEFAULT(VT_SETMODE), IOCTL32_DEFAULT(VT_GETMODE), IOCTL32_DEFAULT(VT_GETSTATE), IOCTL32_DEFAULT(VT_OPENQRY), IOCTL32_DEFAULT(VT_ACTIVATE), IOCTL32_DEFAULT(VT_WAITACTIVE), IOCTL32_DEFAULT(VT_RELDISP), IOCTL32_DEFAULT(VT_DISALLOCATE), IOCTL32_DEFAULT(VT_RESIZE), IOCTL32_DEFAULT(VT_RESIZEX), IOCTL32_DEFAULT(VT_LOCKSWITCH), IOCTL32_DEFAULT(VT_UNLOCKSWITCH), IOCTL32_DEFAULT(SIOCGSTAMP), IOCTL32_DEFAULT(LOOP_SET_FD), IOCTL32_DEFAULT(LOOP_CLR_FD), IOCTL32_DEFAULT(SIOCATMARK), IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf), IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMETRIC, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMETRIC, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMTU, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMTU, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMEM, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMEM, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFHWADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFHWADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCADDMULTI, dev_ifsioc), IOCTL32_HANDLER(SIOCDELMULTI, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFINDEX, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMAP, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMAP, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFBRDADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFBRDADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFDSTADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFDSTADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFNETMASK, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc), IOCTL32_HANDLER(SIOCADDRT, routing_ioctl), IOCTL32_HANDLER(SIOCDELRT, routing_ioctl), IOCTL32_HANDLER(SIOCBONDENSLAVE, bond_ioctl), IOCTL32_HANDLER(SIOCBONDRELEASE, bond_ioctl), IOCTL32_HANDLER(SIOCBONDSETHWADDR, bond_ioctl), IOCTL32_HANDLER(SIOCBONDSLAVEINFOQUERY, bond_ioctl), IOCTL32_HANDLER(SIOCBONDINFOQUERY, bond_ioctl), IOCTL32_HANDLER(SIOCBONDCHANGEACTIVE, bond_ioctl), IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl), IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status), IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status),/* Raw devices */ IOCTL32_DEFAULT(RAW_SETBIND), IOCTL32_DEFAULT(RAW_GETBIND), IOCTL32_HANDLER(BLKRAGET, w_long), IOCTL32_HANDLER(BLKGETSIZE, w_long), IOCTL32_HANDLER(BLKFRAGET, w_long), IOCTL32_HANDLER(BLKSECTGET, w_long), IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans)};#define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \ sizeof(ioctl32_handler_table[0]))static struct ioctl32_list *ioctl32_hash_table[1024];static inline int ioctl32_hash(unsigned int cmd){ return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;}int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); struct file *filp; struct ioctl32_list *l; int error; l = ioctl32_hash_table[ioctl32_hash(cmd)]; error = -EBADF; filp = fget(fd); if (!filp) return error; if (!filp->f_op || !filp->f_op->ioctl) { error = sys_ioctl (fd, cmd, arg); goto out; } while (l && l->handler.cmd != cmd) l = l->next; if (l) { handler = (void *)l->handler.function; error = handler(fd, cmd, arg, filp); } else { error = -EINVAL; printk("unknown ioctl: %08x\n", cmd); }out: fput(filp); return error;}static void ioctl32_insert(struct ioctl32_list *entry){ int hash = ioctl32_hash(entry->handler.cmd); entry->next = 0; if (!ioctl32_hash_table[hash]) ioctl32_hash_table[hash] = entry; else { struct ioctl32_list *l; l = ioctl32_hash_table[hash]; while (l->next) l = l->next; l->next = entry; }}int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *)){ struct ioctl32_list *l, *new; int hash; hash = ioctl32_hash(cmd); for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) if (l->handler.cmd == cmd) return -EBUSY; new = kmalloc(sizeof(struct ioctl32_list), GFP_KERNEL); if (new == NULL) return -ENOMEM; new->handler.cmd = cmd; new->handler.function = (void *) handler; ioctl32_insert(new); return 0;}int unregister_ioctl32_conversion(unsigned int cmd){ struct ioctl32_list *p, *l; int hash; hash = ioctl32_hash(cmd); p = NULL; for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) { if (l->handler.cmd == cmd) break; p = l; } if (l == NULL) return -ENOENT; if (p == NULL) ioctl32_hash_table[hash] = l->next; else p->next = l->next; kfree(l); return 0;}static int __init init_ioctl32(void){ int i; for (i = 0; i < NR_IOCTL32_HANDLERS; i++) ioctl32_insert(&ioctl32_handler_table[i]); return 0;}__initcall(init_ioctl32);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?