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 + -
显示快捷键?