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

📄 ioctl32.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) * Copyright (C) 2000 Ralf Baechle * * Mostly stolen from the sparc64 ioctl32 implementation. */#include <linux/config.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/mtio.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/hdreg.h>#include <linux/blkpg.h>#include <linux/blkdev.h>#include <linux/elevator.h>#include <linux/auto_fs.h>#include <linux/ext2_fs.h>#include <linux/raid/md_u.h>#include <asm/types.h>#include <asm/uaccess.h>long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);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;}static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	int err;	unsigned long val;	if (get_user(val, (u32 *)arg))		return -EFAULT;	set_fs(KERNEL_DS);	err = sys_ioctl(fd, cmd, (unsigned long)&val);	set_fs (old_fs);	if (!err && put_user(val, (u32 *)arg))		return -EFAULT;	return err;}#define A(__x) ((unsigned long)(__x))struct timeval32 {	int tv_sec;	int tv_usec;};static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg){	struct timeval32 *up = (struct timeval32 *)arg;	struct timeval ktv;	mm_segment_t old_fs = get_fs();	int err;	set_fs(KERNEL_DS);	err = sys_ioctl(fd, cmd, (unsigned long)&ktv);	set_fs(old_fs);	if (!err) {		err = put_user(ktv.tv_sec, &up->tv_sec);		err |= __put_user(ktv.tv_usec, &up->tv_usec);	}	return err;}#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];                __kernel_caddr_t32 ifru_data;        } ifr_ifru;};struct ifconf32 {        int     ifc_len;                        /* size of buffer       */        __kernel_caddr_t32  ifcbuf;};#ifdef CONFIG_NETstatic int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ireq32 *uir32 = (struct ireq32 *)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 *)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 inline int dev_ifsioc(unsigned int fd, unsigned int cmd,			     unsigned long arg){	struct ifreq32 *uifr = (struct ifreq32 *)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;}struct rtentry32{	unsigned int	rt_pad1;	struct sockaddr	rt_dst;		/* target address		*/	struct sockaddr	rt_gateway;	/* gateway addr (RTF_GATEWAY)	*/	struct sockaddr	rt_genmask;	/* target network mask (IP)	*/	unsigned short	rt_flags;	short		rt_pad2;	unsigned int	rt_pad3;	unsigned int	rt_pad4;	short		rt_metric;	/* +1 for binary compatibility!	*/	unsigned int	rt_dev;		/* forcing the device at add	*/	unsigned int	rt_mtu;		/* per route MTU/Window 	*/#ifndef __KERNEL__#define rt_mss	rt_mtu			/* Compatibility :-(            */#endif	unsigned int	rt_window;	/* Window clamping 		*/	unsigned short	rt_irtt;	/* Initial RTT			*/};static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){	struct rtentry32 *ur = (struct rtentry32 *)arg;	struct rtentry r;	char devname[16];	u32 rtdev;	int ret;	mm_segment_t old_fs = get_fs();		ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr));	ret |= __get_user (r.rt_flags, &(ur->rt_flags));	ret |= __get_user (r.rt_metric, &(ur->rt_metric));	ret |= __get_user (r.rt_mtu, &(ur->rt_mtu));	ret |= __get_user (r.rt_window, &(ur->rt_window));	ret |= __get_user (r.rt_irtt, &(ur->rt_irtt));	ret |= __get_user (rtdev, &(ur->rt_dev));	if (rtdev) {		ret |= copy_from_user (devname, (char *)A(rtdev), 15);		r.rt_dev = devname; devname[15] = 0;	} else		r.rt_dev = 0;	if (ret)		return -EFAULT;	set_fs (KERNEL_DS);	ret = sys_ioctl (fd, cmd, (long)&r);	set_fs (old_fs);	return ret;}#endif /* CONFIG_NET */static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){	/* These are just misnamed, they actually get/put from/to user an int */	switch (cmd) {	case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;	case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;	case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;	case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;	}	return sys_ioctl(fd, cmd, arg);}struct hd_geometry32 {	unsigned char heads;	unsigned char sectors;	unsigned short cylinders;	u32 start;};static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct hd_geometry geo;	int err;	set_fs (KERNEL_DS);	err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);	set_fs (old_fs);	if (!err) {		err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);		err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));	}	return err ? -EFAULT : 0;}static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	unsigned long kval;	unsigned int *uvp;	int error;	set_fs(KERNEL_DS);	error = sys_ioctl(fd, cmd, (long)&kval);	set_fs(old_fs);	if (error == 0) {		uvp = (unsigned int *)arg;		if (put_user(kval, uvp))			error = -EFAULT;	}	return error;}static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg){	return -EINVAL;}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;}struct mtget32 {	__u32	mt_type;	__u32	mt_resid;	__u32	mt_dsreg;	__u32	mt_gstat;	__u32	mt_erreg;	__kernel_daddr_t32	mt_fileno;	__kernel_daddr_t32	mt_blkno;};#define MTIOCGET32	_IOR('m', 2, struct mtget32)struct mtpos32 {	__u32	mt_blkno;};#define MTIOCPOS32	_IOR('m', 3, struct mtpos32)

⌨️ 快捷键说明

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