⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	case 142: /* TI_BIND */	{		int i;		u32 prim;		SOLD("TI_BIND entry");		ret = timod_putmsg(fd, (char *)A(arg), len, NULL, -1, 0);		SOLD("timod_putmsg() returned");		if (ret)			return (-ret << 8) | TSYSERR;		len = 1024; /* Solaris allows arbitrary return size */		i = MSG_HIPRI;		SOLD("calling timod_getmsg()");		ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i);		SOLD("timod_getmsg() returned");		if (ret)			return (-ret << 8) | TSYSERR;		SOLD("ret ok");		if (get_user(prim, (u32 *)A(arg)))			return (EFAULT << 8) | TSYSERR;		SOLD("got prim");		if (prim == T_ERROR_ACK) {			u32 tmp, tmp2;			SOLD("prim is T_ERROR_ACK");			if (get_user(tmp, (u32 *)A(arg)+3) ||			    get_user(tmp2, (u32 *)A(arg)+2))				return (EFAULT << 8) | TSYSERR;			return (tmp2 << 8) | tmp;		}		SOLD("no ERROR_ACK requested");		if (prim != T_OK_ACK)			return TBADSEQ;		SOLD("OK_ACK requested");		i = MSG_HIPRI;		SOLD("calling timod_getmsg()");		ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i);		SOLD("timod_getmsg() returned");		if (ret)			return (-ret << 8) | TSYSERR;		SOLD("TI_BIND return ok");		return 0;	}	case 140: /* TI_GETINFO */	case 143: /* TI_UNBIND */	case 144: /* TI_GETMYNAME */	case 145: /* TI_GETPEERNAME */	case 146: /* TI_SETMYNAME */	case 147: /* TI_SETPEERNAME */	}	return TNOTSUPPORT;}static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg){	char *p;	int ret;	mm_segment_t old_fs;	struct strioctl si;	struct inode *ino;        struct sol_socket_struct *sock;        struct module_info *mi;        ino = filp->f_dentry->d_inode;        if (! ino->i_sock)		return -EBADF;        sock = filp->private_data;        if (! sock) {                printk("solaris_S: NULL private_data\n");                return -EBADF;        }        if (sock->magic != SOLARIS_SOCKET_MAGIC) {                printk("solaris_S: invalid magic\n");                return -EBADF;        }        	switch (cmd & 0xff) {	case 1: /* I_NREAD */		return -ENOSYS;	case 2: /* I_PUSH */        {		p = getname ((char *)A(arg));		if (IS_ERR (p))			return PTR_ERR(p);                ret = -EINVAL;                for (mi = module_table; mi->name; mi++) {                        if (strcmp(mi->name, p) == 0) {                                sol_module m;                                if (sock->modcount >= MAX_NR_STREAM_MODULES) {                                        ret = -ENXIO;                                        break;                                }                                m = (sol_module) (mi - module_table);                                sock->module[sock->modcount++] = m;                                ret = 0;                                break;                        }                }		putname (p);		return ret;        }	case 3: /* I_POP */                if (sock->modcount <= 0) return -EINVAL;                sock->modcount--;		return 0;        case 4: /* I_LOOK */        {        	const char *p;                if (sock->modcount <= 0) return -EINVAL;                p = module_table[(unsigned)sock->module[sock->modcount]].name;                if (copy_to_user ((char *)A(arg), p, strlen(p)))                	return -EFAULT;                return 0;        }	case 5: /* I_FLUSH */		return 0;	case 8: /* I_STR */		if (copy_from_user(&si, (struct strioctl *)A(arg), sizeof(struct strioctl)))			return -EFAULT;                /* We ignore what module is actually at the top of stack. */		switch ((si.cmd >> 8) & 0xff) {		case 'I':                        return solaris_sockmod(fd, si.cmd, si.data);		case 'T':                        return solaris_timod(fd, si.cmd, si.data, si.len,                                                &((struct strioctl*)A(arg))->len);		default:			return solaris_ioctl(fd, si.cmd, si.data);		}	case 9: /* I_SETSIG */		return sys_ioctl(fd, FIOSETOWN, current->pid);	case 10: /* I_GETSIG */		old_fs = get_fs();		set_fs(KERNEL_DS);		sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret);		set_fs(old_fs);		if (ret == current->pid) return 0x3ff;		else return -EINVAL;	case 11: /* I_FIND */        {                int i;		p = getname ((char *)A(arg));		if (IS_ERR (p))			return PTR_ERR(p);                ret = 0;                for (i = 0; i < sock->modcount; i++) {                        unsigned m = sock->module[i];                        if (strcmp(module_table[m].name, p) == 0) {                                ret = 1;                                break;                        }                 }		putname (p);		return ret;        }	case 19: /* I_SWROPT */	case 32: /* I_SETCLTIME */		return 0;	/* Lie */	}	return -ENOSYS;}static inline int solaris_s(unsigned int fd, unsigned int cmd, u32 arg){	switch (cmd & 0xff) {	case 0: /* SIOCSHIWAT */	case 2: /* SIOCSLOWAT */		return 0; /* We don't support them */	case 1: /* SIOCGHIWAT */	case 3: /* SIOCGLOWAT */		if (put_user (0, (u32 *)A(arg)))			return -EFAULT;		return 0; /* Lie */	case 7: /* SIOCATMARK */		return sys_ioctl(fd, SIOCATMARK, arg);	case 8: /* SIOCSPGRP */		return sys_ioctl(fd, SIOCSPGRP, arg);	case 9: /* SIOCGPGRP */		return sys_ioctl(fd, SIOCGPGRP, arg);	}	return -ENOSYS;}static inline int solaris_r(unsigned int fd, unsigned int cmd, u32 arg){	switch (cmd & 0xff) {	case 10: /* SIOCADDRT */		return sys32_ioctl(fd, SIOCADDRT, arg);	case 11: /* SIOCDELRT */		return sys32_ioctl(fd, SIOCDELRT, arg);	}	return -ENOSYS;}static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg){	switch (cmd & 0xff) {	case 12: /* SIOCSIFADDR */		return sys32_ioctl(fd, SIOCSIFADDR, arg);	case 13: /* SIOCGIFADDR */		return sys32_ioctl(fd, SIOCGIFADDR, arg);	case 14: /* SIOCSIFDSTADDR */		return sys32_ioctl(fd, SIOCSIFDSTADDR, arg);	case 15: /* SIOCGIFDSTADDR */		return sys32_ioctl(fd, SIOCGIFDSTADDR, arg);	case 16: /* SIOCSIFFLAGS */		return sys32_ioctl(fd, SIOCSIFFLAGS, arg);	case 17: /* SIOCGIFFLAGS */		return sys32_ioctl(fd, SIOCGIFFLAGS, arg);	case 18: /* SIOCSIFMEM */		return sys32_ioctl(fd, SIOCSIFMEM, arg);	case 19: /* SIOCGIFMEM */		return sys32_ioctl(fd, SIOCGIFMEM, arg);	case 20: /* SIOCGIFCONF */		return sys32_ioctl(fd, SIOCGIFCONF, arg);	case 21: /* SIOCSIFMTU */		return sys32_ioctl(fd, SIOCSIFMTU, arg);	case 22: /* SIOCGIFMTU */		return sys32_ioctl(fd, SIOCGIFMTU, arg);	case 23: /* SIOCGIFBRDADDR */		return sys32_ioctl(fd, SIOCGIFBRDADDR, arg);	case 24: /* SIOCSIFBRDADDR */		return sys32_ioctl(fd, SIOCSIFBRDADDR, arg);	case 25: /* SIOCGIFNETMASK */		return sys32_ioctl(fd, SIOCGIFNETMASK, arg);	case 26: /* SIOCSIFNETMASK */		return sys32_ioctl(fd, SIOCSIFNETMASK, arg);	case 27: /* SIOCGIFMETRIC */		return sys32_ioctl(fd, SIOCGIFMETRIC, arg);	case 28: /* SIOCSIFMETRIC */		return sys32_ioctl(fd, SIOCSIFMETRIC, arg);	case 30: /* SIOCSARP */		return sys32_ioctl(fd, SIOCSARP, arg);	case 31: /* SIOCGARP */		return sys32_ioctl(fd, SIOCGARP, arg);	case 32: /* SIOCDARP */		return sys32_ioctl(fd, SIOCDARP, arg);	case 52: /* SIOCGETNAME */	case 53: /* SIOCGETPEER */		{			struct sockaddr uaddr;			int uaddr_len = sizeof(struct sockaddr), ret;			long args[3];			mm_segment_t old_fs = get_fs();			int (*sys_socketcall)(int, unsigned long *) =				(int (*)(int, unsigned long *))SYS(socketcall);						args[0] = fd; args[1] = (long)&uaddr; args[2] = (long)&uaddr_len;			set_fs(KERNEL_DS);			ret = sys_socketcall(((cmd & 0xff) == 52) ? SYS_GETSOCKNAME : SYS_GETPEERNAME,					args);			set_fs(old_fs);			if (ret >= 0) {				if (copy_to_user((char *)A(arg), &uaddr, uaddr_len))					return -EFAULT;			}			return ret;		}#if 0			case 86: /* SIOCSOCKSYS */		return socksys_syscall(fd, arg);#endif			case 87: /* SIOCGIFNUM */		{			struct net_device *d;			int i = 0;						read_lock_bh(&dev_base_lock);			for (d = dev_base; d; d = d->next) i++;			read_unlock_bh(&dev_base_lock);			if (put_user (i, (int *)A(arg)))				return -EFAULT;			return 0;		}	}	return -ENOSYS;}static int solaris_m(unsigned int fd, unsigned int cmd, u32 arg){	int ret;	switch (cmd & 0xff) {	case 1: /* MTIOCTOP */		ret = sys_ioctl(fd, MTIOCTOP, (unsigned long)&arg);		break;	case 2: /* MTIOCGET */		ret = sys_ioctl(fd, MTIOCGET, (unsigned long)&arg);		break;	case 3: /* MTIOCGETDRIVETYPE */	case 4: /* MTIOCPERSISTENT */	case 5: /* MTIOCPERSISTENTSTATUS */	case 6: /* MTIOCLRERR */	case 7: /* MTIOCGUARANTEEDORDER */	case 8: /* MTIOCRESERVE */	case 9: /* MTIOCRELEASE */	case 10: /* MTIOCFORCERESERVE */	case 13: /* MTIOCSTATE */	case 14: /* MTIOCREADIGNOREILI */	case 15: /* MTIOCREADIGNOREEOFS */	case 16: /* MTIOCSHORTFMK */	default:		ret = -ENOSYS; /* linux doesn't support these */		break;	};	return ret;}static int solaris_O(unsigned int fd, unsigned int cmd, u32 arg){	int ret = -EINVAL;	switch (cmd & 0xff) {	case 1: /* OPROMGETOPT */		ret = sys_ioctl(fd, OPROMGETOPT, arg);		break;	case 2: /* OPROMSETOPT */		ret = sys_ioctl(fd, OPROMSETOPT, arg);		break;	case 3: /* OPROMNXTOPT */		ret = sys_ioctl(fd, OPROMNXTOPT, arg);		break;	case 4: /* OPROMSETOPT2 */		ret = sys_ioctl(fd, OPROMSETOPT2, arg);		break;	case 5: /* OPROMNEXT */		ret = sys_ioctl(fd, OPROMNEXT, arg);		break;	case 6: /* OPROMCHILD */		ret = sys_ioctl(fd, OPROMCHILD, arg);		break;	case 7: /* OPROMGETPROP */		ret = sys_ioctl(fd, OPROMGETPROP, arg);		break;	case 8: /* OPROMNXTPROP */		ret = sys_ioctl(fd, OPROMNXTPROP, arg);		break;	case 9: /* OPROMU2P */		ret = sys_ioctl(fd, OPROMU2P, arg);		break;	case 10: /* OPROMGETCONS */		ret = sys_ioctl(fd, OPROMGETCONS, arg);		break;	case 11: /* OPROMGETFBNAME */		ret = sys_ioctl(fd, OPROMGETFBNAME, arg);		break;	case 12: /* OPROMGETBOOTARGS */		ret = sys_ioctl(fd, OPROMGETBOOTARGS, arg);		break;	case 13: /* OPROMGETVERSION */	case 14: /* OPROMPATH2DRV */	case 15: /* OPROMDEV2PROMNAME */	case 16: /* OPROMPROM2DEVNAME */	case 17: /* OPROMGETPROPLEN */	default:		ret = -EINVAL;		break;	};	return ret;}/* }}} */asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg){	struct file *filp;	int error = -EBADF;	filp = fget(fd);	if (!filp)		goto out;	lock_kernel();	error = -EFAULT;	switch ((cmd >> 8) & 0xff) {	case 'S': error = solaris_S(filp, fd, cmd, arg); break;	case 'T': error = solaris_T(fd, cmd, arg); break;	case 'i': error = solaris_i(fd, cmd, arg); break;	case 'r': error = solaris_r(fd, cmd, arg); break;	case 's': error = solaris_s(fd, cmd, arg); break;	case 't': error = solaris_t(fd, cmd, arg); break;	case 'f': error = sys_ioctl(fd, cmd, arg); break;	case 'm': error = solaris_m(fd, cmd, arg); break;	case 'O': error = solaris_O(fd, cmd, arg); break;	default:		error = -ENOSYS;		break;	}	unlock_kernel();	fput(filp);out:	if (error == -ENOSYS) {		unsigned char c = cmd>>8;				if (c < ' ' || c > 126) c = '.';		printk("solaris_ioctl: Unknown cmd fd(%d) cmd(%08x '%c') arg(%08x)\n",		       (int)fd, (unsigned int)cmd, c, (unsigned int)arg);		error = -EINVAL;	}	return error;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -