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

📄 ioctl32.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (sg_io64.iovec_count) {		int ret;		if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {			err = ret;			goto out;		}	} else {		sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);		if (!sg_io64.dxferp) {			err = -ENOMEM;			goto out;		}		if (copy_from_user(sg_io64.dxferp,				   (void *) A(dxferp32),				   sg_io64.dxfer_len)) {			err = -EFAULT;			goto out;		}	}	/* Unused internally, do not even bother to copy it over. */	sg_io64.usr_ptr = NULL;	if (err)		return -EFAULT;	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);	set_fs (old_fs);	if (err < 0)		goto out;	err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);	err |= __put_user(sg_io64.status, &sg_io32->status);	err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);	err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);	err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);	err |= __put_user(sg_io64.host_status, &sg_io32->host_status);	err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);	err |= __put_user(sg_io64.resid, &sg_io32->resid);	err |= __put_user(sg_io64.duration, &sg_io32->duration);	err |= __put_user(sg_io64.info, &sg_io32->info);	err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);	if (sg_io64.dxferp) {		if (sg_io64.iovec_count)			err |= copy_back_sg_iovec(&sg_io64, dxferp32);		else			err |= copy_to_user((void *)A(dxferp32),					    sg_io64.dxferp,					    sg_io64.dxfer_len);	}	if (err)		err = -EFAULT;out:	if (sg_io64.cmdp)		kfree(sg_io64.cmdp);	if (sg_io64.sbp)		kfree(sg_io64.sbp);	if (sg_io64.dxferp) {		if (sg_io64.iovec_count) {			free_sg_iovec(&sg_io64);		} else {			kfree(sg_io64.dxferp);		}	}	return err;}struct ppp_option_data32 {	__kernel_caddr_t32	ptr;	__u32			length;	int			transmit;};#define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)struct ppp_idle32 {	__kernel_time_t32 xmit_idle;	__kernel_time_t32 recv_idle;};#define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct ppp_option_data32 data32;	struct ppp_option_data data;	struct ppp_idle32 idle32;	struct ppp_idle idle;	unsigned int kcmd;	void *karg;	int err = 0;	switch (cmd) {	case PPPIOCGIDLE32:		kcmd = PPPIOCGIDLE;		karg = &idle;		break;	case PPPIOCSCOMPRESS32:		if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))			return -EFAULT;		data.ptr = kmalloc (data32.length, GFP_KERNEL);		if (!data.ptr)			return -ENOMEM;		if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {			kfree(data.ptr);			return -EFAULT;		}		data.length = data32.length;		data.transmit = data32.transmit;		kcmd = PPPIOCSCOMPRESS;		karg = &data;		break;	default:		do {			static int count = 0;			if (++count <= 20)				printk("ppp_ioctl: Unknown cmd fd(%d) "				       "cmd(%08x) arg(%08x)\n",				       (int)fd, (unsigned int)cmd, (unsigned int)arg);		} while (0);		return -EINVAL;	}	set_fs (KERNEL_DS);	err = sys_ioctl (fd, kcmd, (unsigned long)karg);	set_fs (old_fs);	switch (cmd) {	case PPPIOCGIDLE32:		if (err)			return err;		idle32.xmit_idle = idle.xmit_idle;		idle32.recv_idle = idle.recv_idle;		if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))			return -EFAULT;		break;	case PPPIOCSCOMPRESS32:		kfree(data.ptr);		break;	default:		break;	}	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)struct mtconfiginfo32 {	__u32	mt_type;	__u32	ifc_type;	__u16	irqnr;	__u16	dmanr;	__u16	port;	__u32	debug;	__u32	have_dens:1;	__u32	have_bsf:1;	__u32	have_fsr:1;	__u32	have_bsr:1;	__u32	have_eod:1;	__u32	have_seek:1;	__u32	have_tell:1;	__u32	have_ras1:1;	__u32	have_ras2:1;	__u32	have_ras3:1;	__u32	have_qfa:1;	__u32	pad1:5;	char	reserved[10];};#define	MTIOCGETCONFIG32	_IOR('m', 4, struct mtconfiginfo32)#define	MTIOCSETCONFIG32	_IOW('m', 5, struct mtconfiginfo32)static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct mtconfiginfo info;	struct mtget get;	struct mtpos pos;	unsigned long kcmd;	void *karg;	int err = 0;	switch(cmd) {	case MTIOCPOS32:		kcmd = MTIOCPOS;		karg = &pos;		break;	case MTIOCGET32:		kcmd = MTIOCGET;		karg = &get;		break;	case MTIOCGETCONFIG32:		kcmd = MTIOCGETCONFIG;		karg = &info;		break;	case MTIOCSETCONFIG32:		kcmd = MTIOCSETCONFIG;		karg = &info;		err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);		err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);		err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);		err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);		err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);		err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);		err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),				     (char *)&((struct mtconfiginfo32 *)arg)->debug				     + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));		if (err)			return -EFAULT;		break;	default:		do {			static int count = 0;			if (++count <= 20)				printk("mt_ioctl: Unknown cmd fd(%d) "				       "cmd(%08x) arg(%08x)\n",				       (int)fd, (unsigned int)cmd, (unsigned int)arg);		} while (0);		return -EINVAL;	}	set_fs (KERNEL_DS);	err = sys_ioctl (fd, kcmd, (unsigned long)karg);	set_fs (old_fs);	if (err)		return err;	switch (cmd) {	case MTIOCPOS32:		err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);		break;	case MTIOCGET32:		err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);		err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);		err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);		err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);		err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);		err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);		err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);		break;	case MTIOCGETCONFIG32:		err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);		err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);		err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);		err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);		err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);		err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);		err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug			    		   + sizeof(((struct mtconfiginfo32 *)arg)->debug),					   (char *)&info.debug + sizeof(info.debug), sizeof(__u32));		break;	case MTIOCSETCONFIG32:		break;	}	return err ? -EFAULT: 0;}struct cdrom_read_audio32 {	union cdrom_addr	addr;	u_char			addr_format;	int			nframes;	__kernel_caddr_t32	buf;};struct cdrom_generic_command32 {	unsigned char		cmd[CDROM_PACKET_SIZE];	__kernel_caddr_t32	buffer;	unsigned int		buflen;	int			stat;	__kernel_caddr_t32	sense;	__kernel_caddr_t32	reserved[3];};static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct cdrom_read_audio cdreadaudio;	struct cdrom_generic_command cgc;	__kernel_caddr_t32 addr;	char *data = 0;	void *karg;	int err = 0;	switch(cmd) {	case CDROMREADAUDIO:		karg = &cdreadaudio;		err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));		err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);		err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes); 		err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);		if (err)			return -EFAULT;		data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);		if (!data)			return -ENOMEM;		cdreadaudio.buf = data;		break;	case CDROM_SEND_PACKET:		karg = &cgc;		err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));		err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);		err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);		if (err)			return -EFAULT;		if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)			return -ENOMEM;		cgc.buffer = data;		break;	default:		do {			static int count = 0;			if (++count <= 20)				printk("cdrom_ioctl: Unknown cmd fd(%d) "				       "cmd(%08x) arg(%08x)\n",				       (int)fd, (unsigned int)cmd, (unsigned int)arg);		} while (0);		return -EINVAL;	}	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long)karg);	set_fs (old_fs);	if (err)		goto out;	switch (cmd) {	case CDROMREADAUDIO:		err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);		break;	case CDROM_SEND_PACKET:		err = copy_to_user((char *)A(addr), data, cgc.buflen);		break;	default:		break;	}out:	if (data)		kfree(data);	return err ? -EFAULT : 0;}struct loop_info32 {	int			lo_number;      /* ioctl r/o */	__kernel_dev_t32	lo_device;      /* ioctl r/o */	unsigned int		lo_inode;       /* ioctl r/o */	__kernel_dev_t32	lo_rdevice;     /* ioctl r/o */	int			lo_offset;	int			lo_encrypt_type;	int			lo_encrypt_key_size;    /* ioctl w/o */	int			lo_flags;       /* ioctl r/o */	char			lo_name[LO_NAME_SIZE];	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */	unsigned int		lo_init[2];	char			reserved[4];};static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct loop_info l;	int err = -EINVAL;	switch(cmd) {	case LOOP_SET_STATUS:		err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);		err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);		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;}extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);#ifdef CONFIG_VTstatic int vt_check(struct file *file){	struct tty_struct *tty;	struct inode *inode = file->f_dentry->d_inode;		if (file->f_op->ioctl != tty_ioctl)		return -EINVAL;	                	tty = (struct tty_struct *)file->private_data;	if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))		return -EINVAL;	                                                	if (tty->driver.ioctl != vt_ioctl)		return -EINVAL;		/*	 * To have permissions to do most of the vt ioctls, we either have	 * to be the owner of the tty, or super-user.	 */	if (current->tty == tty || suser())		return 1;	return 0;                                                    }

⌨️ 快捷键说明

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