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

📄 ioctl32.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id: ioctl32.c,v 1.12 2002/07/08 20:52:15 grundler Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com) * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be) * * These routines maintain argument size conversion between 32bit and 64bit * ioctls. */#include <linux/config.h>#include <linux/types.h>#include "sys32.h"#include <linux/kernel.h>#include <linux/sched.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/ioctl.h>#include <linux/if.h>#include <linux/slab.h>#include <linux/hdreg.h>#include <linux/raid/md.h>#include <linux/kd.h>#include <linux/route.h>#include <linux/skbuff.h>#include <linux/netlink.h>#include <linux/vt.h>#include <linux/fs.h>#include <linux/file.h>#include <linux/fd.h>#include <linux/ppp_defs.h>#include <linux/if_ppp.h>#include <linux/if_pppox.h>#include <linux/mtio.h>#include <linux/cdrom.h>#include <linux/loop.h>#include <linux/auto_fs.h>#include <linux/devfs_fs.h>#include <linux/tty.h>#include <linux/vt_kern.h>#include <linux/fb.h>#include <linux/ext2_fs.h>#include <linux/videodev.h>#include <linux/netdevice.h>#include <linux/raw.h>#include <linux/smb_fs.h>#include <linux/blkpg.h>#include <linux/blk.h>#include <linux/elevator.h>#include <linux/rtc.h>#include <linux/serial.h>#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)/* Ugh. This header really is not clean *//* #define min min#define max max */#include <linux/lvm.h>#endif /* LVM */#include <scsi/scsi.h>/* Ugly hack. */#undef __KERNEL__#include <scsi/scsi_ioctl.h>#define __KERNEL__#include <scsi/sg.h>#include <asm/types.h>#include <asm/uaccess.h>#include <asm/perf.h>#include <linux/ethtool.h>#include <linux/soundcard.h>#include <linux/atm.h>#include <linux/atmarp.h>#include <linux/atmclip.h>#include <linux/atmdev.h>#include <linux/atmioc.h>#include <linux/atmlec.h>#include <linux/atmmpc.h>#include <linux/atmsvc.h>#include <linux/atm_tcp.h>#include <linux/sonet.h>#include <linux/atm_suni.h>#include <asm/module.h>	/* get #define module_map() *//* Use this to get at 32-bit user passed pointers.    See sys_sparc32.c for description about these. */#define A(__x) ((unsigned long)(__x))/* Aiee. Someone does not find a difference between int and long */#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)extern asmlinkage int 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(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;}static int siocprivate(unsigned int fd, unsigned int cmd, unsigned long arg){	int err = sys_ioctl(fd, cmd, arg);	if ((unsigned) err > -4095)		printk(KERN_WARNING 			"ioctl(%d, 0x%x, %p) -- SIOCDEVPRIVATE-based ioctls aren't really\n"			"supported, though some will work by accident.\n",		    fd, cmd, (void *)arg);	return err;}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);} 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;}struct ifmap32 {	u32 mem_start;	u32 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;};static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg){	struct net_device *dev;	struct ifreq32 ifr32;	int err;	if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))		return -EFAULT;	dev = dev_get_by_index(ifr32.ifr_ifindex);	if (!dev)		return -ENODEV;	strcpy(ifr32.ifr_name, dev->name);	err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));	return (err ? -EFAULT : 0);}static inline int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ifconf32 ifc32;	struct ifconf ifc;	struct ifreq32 *ifr32;	struct ifreq *ifr;	mm_segment_t old_fs;	unsigned int i, j;	int err;	if (copy_from_user(&ifc32, (struct ifconf32 *)arg, 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)) + 1) *			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);	for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {		if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {			kfree (ifc.ifc_buf);			return -EFAULT;		}	}	old_fs = get_fs(); set_fs (KERNEL_DS);	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);		set_fs (old_fs);	if (!err) {		ifr = ifc.ifc_req;		ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);		for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;		     i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {			if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {				err = -EFAULT;				break;			}		}		if (!err) {			if (i <= ifc32.ifc_len)				ifc32.ifc_len = i;			else				ifc32.ifc_len = i - sizeof (struct ifreq32);			if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))				err = -EFAULT;		}	}	if(ifc.ifc_buf != NULL)		kfree (ifc.ifc_buf);	return err;}static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ifreq ifr;	mm_segment_t old_fs;	int err;		switch (cmd) {	case SIOCSIFMAP:		err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));		err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));		err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));		err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));		err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));		err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));		err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));		if (err)			return -EFAULT;		break;	case SIOCGPPPSTATS:	case SIOCGPPPCSTATS:	case SIOCGPPPVER:	case SIOCETHTOOL:		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;		if(cmd == SIOCETHTOOL) {			u32 data;			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));			if(copy_from_user(ifr.ifr_data,					  (char *)A(data),					  sizeof(struct ethtool_cmd))) {				free_page((unsigned long)ifr.ifr_data);				return -EFAULT;			}		}		break;	default:		if (copy_from_user(&ifr, (struct ifreq32 *)arg, 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((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))				return -EFAULT;			break;		case SIOCGPPPSTATS:		case SIOCGPPPCSTATS:		case SIOCGPPPVER:		case SIOCETHTOOL:		{			u32 data;			int len;			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));			if(cmd == SIOCETHTOOL)				len = sizeof(struct ethtool_cmd);			if(cmd == SIOCGPPPVER)				len = strlen((char *)ifr.ifr_data) + 1;			else if(cmd == SIOCGPPPCSTATS)				len = sizeof(struct ppp_comp_stats);			else				len = sizeof(struct ppp_stats);			len = copy_to_user((char *)A(data), ifr.ifr_data, len);			free_page((unsigned long)ifr.ifr_data);			if(len)				return -EFAULT;			break;		}		case SIOCGIFMAP:			err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));			err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));			err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));			err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));			err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));			err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));			err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));			if (err)				err = -EFAULT;			break;		}	}	return err;}struct rtentry32 {        u32   		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;        u32   		rt_pad3;        unsigned char   rt_tos;        unsigned char   rt_class;        short           rt_pad4;        short           rt_metric;      /* +1 for binary compatibility! */        /* char * */ u32 rt_dev;        /* forcing the device at add    */        u32   		rt_mtu;         /* per route MTU/Window         */        u32   		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 rtentry r;	char devname[16];	u32 rtdev;	int ret;	mm_segment_t old_fs = get_fs();		ret = copy_from_user (&r.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));	ret |= __get_user (r.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));	ret |= __get_user (r.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));	ret |= __get_user (r.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));	ret |= __get_user (r.rt_window, &(((struct rtentry32 *)arg)->rt_window));	ret |= __get_user (r.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));	ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->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;}struct hd_geometry32 {	unsigned char heads;	unsigned char sectors;	unsigned short cylinders;	u32 start;};                        static inline 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) {

⌨️ 快捷键说明

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