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

📄 ioctl32.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * *  S390 version *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation *    Author(s): Gerhard Tonn (ton@de.ibm.com) * * Heavily inspired by the 32-bit Sparc compat code which is   * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com)  * */#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/init.h>#include <linux/file.h>#include <linux/vt.h>#include <linux/kd.h>#include <linux/netdevice.h>#include <linux/route.h>#include <linux/ext2_fs.h>#include <linux/hdreg.h>#include <linux/if_bonding.h>#include <asm/types.h>#include <asm/uaccess.h>#include <asm/dasd.h>#include <asm/sockios.h>#include "linux32.h"long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);struct hd_geometry32 {	unsigned char	heads;	unsigned char	sectors;	unsigned short	cylinders;	__u32		start;};  static inline int hd_geometry_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){	struct hd_geometry32 *hg32 = (struct hd_geometry32 *) A(arg);	struct hd_geometry hg;	int ret;	mm_segment_t old_fs = get_fs();		set_fs (KERNEL_DS);	ret = sys_ioctl (fd, cmd, (long)&hg);	set_fs (old_fs);	if (ret)		return ret;	ret = put_user (hg.heads, &(hg32->heads));	ret |= __put_user (hg.sectors, &(hg32->sectors));	ret |= __put_user (hg.cylinders, &(hg32->cylinders));	ret |= __put_user (hg.start, &(hg32->start));	return ret;}struct timeval32 {	int tv_sec;	int tv_usec;};#define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)#define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)#define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)#define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)struct ifmap32 {	unsigned int mem_start;	unsigned int mem_end;	unsigned short base_addr;	unsigned char irq;	unsigned char dma;	unsigned char port;};struct ifreq32 {#define IFHWADDRLEN     6#define IFNAMSIZ        16        union {                char    ifrn_name[IFNAMSIZ];	/* if name, e.g. "en0" */        } ifr_ifrn;        union {                struct  sockaddr ifru_addr;                struct  sockaddr ifru_dstaddr;                struct  sockaddr ifru_broadaddr;                struct  sockaddr ifru_netmask;                struct  sockaddr ifru_hwaddr;                short   ifru_flags;                int     ifru_ivalue;                int     ifru_mtu;                struct  ifmap32 ifru_map;                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */		char	ifru_newname[IFNAMSIZ];                __u32	ifru_data;        } ifr_ifru;};struct ifconf32 {        int     ifc_len;                        /* size of buffer       */        __u32	ifcbuf;};static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ireq32 *uir32 = (struct ireq32 *) A(arg);	struct net_device *dev;	struct ifreq32 ifr32;	if (copy_from_user(&ifr32, uir32, sizeof(struct ifreq32)))		return -EFAULT;	read_lock(&dev_base_lock);	dev = __dev_get_by_index(ifr32.ifr_ifindex);	if (!dev) {		read_unlock(&dev_base_lock);		return -ENODEV;	}	strcpy(ifr32.ifr_name, dev->name);	read_unlock(&dev_base_lock);	if (copy_to_user(uir32, &ifr32, sizeof(struct ifreq32)))	    return -EFAULT;	return 0;}static inline int dev_ifconf(unsigned int fd, unsigned int cmd,			     unsigned long arg){	struct ioconf32 *uifc32 = (struct ioconf32 *) A(arg);	struct ifconf32 ifc32;	struct ifconf ifc;	struct ifreq32 *ifr32;	struct ifreq *ifr;	mm_segment_t old_fs;	int len;	int err;	if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32)))		return -EFAULT;	if(ifc32.ifcbuf == 0) {		ifc32.ifc_len = 0;		ifc.ifc_len = 0;		ifc.ifc_buf = NULL;	} else {		ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32))) *			sizeof (struct ifreq);		ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);		if (!ifc.ifc_buf)			return -ENOMEM;	}	ifr = ifc.ifc_req;	ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf);	len = ifc32.ifc_len / sizeof (struct ifreq32);	while (len--) {		if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {			err = -EFAULT;			goto out;		}	}	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);		set_fs (old_fs);	if (err)		goto out;	ifr = ifc.ifc_req;	ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf);	len = ifc.ifc_len / sizeof (struct ifreq);	ifc32.ifc_len = len * sizeof (struct ifreq32);	while (len--) {		if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {			err = -EFAULT;			goto out;		}	}	if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) {		err = -EFAULT;		goto out;	}out:	if(ifc.ifc_buf != NULL)		kfree (ifc.ifc_buf);	return err;}static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg){	struct ifreq ifr;	mm_segment_t old_fs;	int err, len;	u32 data;		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))		return -EFAULT;	ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);	if (!ifr.ifr_data)		return -EAGAIN;	switch (cmd) {	case SIOCBONDENSLAVE:	case SIOCBONDRELEASE:	case SIOCBONDSETHWADDR:	case SIOCBONDCHANGEACTIVE:		len = IFNAMSIZ * sizeof(char);		break;	case SIOCBONDSLAVEINFOQUERY:		len = sizeof(struct ifslave);		break;	case SIOCBONDINFOQUERY:		len = sizeof(struct ifbond);		break;	default:		err = -EINVAL;		goto out;	};	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));	if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {		err = -EFAULT;		goto out;	}	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);	set_fs (old_fs);	if (!err) {		len = copy_to_user((char *)A(data), ifr.ifr_data, len);		if (len)			err = -EFAULT;	}out:	free_page((unsigned long)ifr.ifr_data);	return err;}static inline int dev_ifsioc(unsigned int fd, unsigned int cmd,			     unsigned long arg){	struct ifreq32 *uifr = (struct ifreq32 *) A(arg);	struct ifreq ifr;	mm_segment_t old_fs;	int err;		switch (cmd) {	case SIOCSIFMAP:		err = copy_from_user(&ifr, uifr, sizeof(ifr.ifr_name));		err |= __get_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));		err |= __get_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));		err |= __get_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));		err |= __get_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));		err |= __get_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));		err |= __get_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));		if (err)			return -EFAULT;		break;	default:		if (copy_from_user(&ifr, uifr, sizeof(struct ifreq32)))			return -EFAULT;		break;	}	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);	set_fs (old_fs);	if (!err) {		switch (cmd) {		case SIOCGIFFLAGS:		case SIOCGIFMETRIC:		case SIOCGIFMTU:		case SIOCGIFMEM:		case SIOCGIFHWADDR:		case SIOCGIFINDEX:		case SIOCGIFADDR:		case SIOCGIFBRDADDR:		case SIOCGIFDSTADDR:		case SIOCGIFNETMASK:		case SIOCGIFTXQLEN:			if (copy_to_user(uifr, &ifr, sizeof(struct ifreq32)))				return -EFAULT;			break;		case SIOCGIFMAP:			err = copy_to_user(uifr, &ifr, sizeof(ifr.ifr_name));			err |= __put_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));			err |= __put_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));			err |= __put_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));			err |= __put_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));			err |= __put_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));			err |= __put_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));			if (err)				err = -EFAULT;			break;		}	}	return err;}

⌨️ 快捷键说明

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