亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? pipe.c

?? 典型的linux驅動程序
?? C
字號:
/* * pipe.c -- fifo driver for scull * * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet * Copyright (C) 2001 O'Reilly & Associates * * The source code in this file can be freely used, adapted, * and redistributed in source or binary form, so long as an * acknowledgment appears in derived source files.  The citation * should list that the code comes from the book "Linux Device * Drivers" by Alessandro Rubini and Jonathan Corbet, published * by O'Reilly & Associates.   No warranty is attached; * we cannot take responsibility for errors or fitness for use. * */ #include <linux/module.h>#include <linux/moduleparam.h>#include <linux/kernel.h>	/* printk(), min() */#include <linux/slab.h>		/* kmalloc() */#include <linux/fs.h>		/* everything... */#include <linux/proc_fs.h>#include <linux/errno.h>	/* error codes */#include <linux/types.h>	/* size_t */#include <linux/fcntl.h>#include <linux/poll.h>#include <linux/cdev.h>#include <asm/uaccess.h>#include "scull.h"		/* local definitions */struct scull_pipe {        wait_queue_head_t inq, outq;       /* read and write queues */        char *buffer, *end;                /* begin of buf, end of buf */        int buffersize;                    /* used in pointer arithmetic */        char *rp, *wp;                     /* where to read, where to write */        int nreaders, nwriters;            /* number of openings for r/w */        struct fasync_struct *async_queue; /* asynchronous readers */        struct semaphore sem;              /* mutual exclusion semaphore */        struct cdev cdev;                  /* Char device structure */};/* parameters */static int scull_p_nr_devs = SCULL_P_NR_DEVS;	/* number of pipe devices */int scull_p_buffer =  SCULL_P_BUFFER;	/* buffer size */dev_t scull_p_devno;			/* Our first device number */module_param(scull_p_nr_devs, int, 0);	/* FIXME check perms */module_param(scull_p_buffer, int, 0);static struct scull_pipe *scull_p_devices;static int scull_p_fasync(int fd, struct file *filp, int mode);static int spacefree(struct scull_pipe *dev);/* * Open and close */static int scull_p_open(struct inode *inode, struct file *filp){	struct scull_pipe *dev;	dev = container_of(inode->i_cdev, struct scull_pipe, cdev);	filp->private_data = dev;	if (down_interruptible(&dev->sem))		return -ERESTARTSYS;	if (!dev->buffer) {		/* allocate the buffer */		dev->buffer = kmalloc(scull_p_buffer, GFP_KERNEL);		if (!dev->buffer) {			up(&dev->sem);			return -ENOMEM;		}	}	dev->buffersize = scull_p_buffer;	dev->end = dev->buffer + dev->buffersize;	dev->rp = dev->wp = dev->buffer; /* rd and wr from the beginning */	/* use f_mode,not  f_flags: it's cleaner (fs/open.c tells why) */	if (filp->f_mode & FMODE_READ)		dev->nreaders++;	if (filp->f_mode & FMODE_WRITE)		dev->nwriters++;	up(&dev->sem);	return nonseekable_open(inode, filp);}static int scull_p_release(struct inode *inode, struct file *filp){	struct scull_pipe *dev = filp->private_data;	/* remove this filp from the asynchronously notified filp's */	scull_p_fasync(-1, filp, 0);	down(&dev->sem);	if (filp->f_mode & FMODE_READ)		dev->nreaders--;	if (filp->f_mode & FMODE_WRITE)		dev->nwriters--;	if (dev->nreaders + dev->nwriters == 0) {		kfree(dev->buffer);		dev->buffer = NULL; /* the other fields are not checked on open */	}	up(&dev->sem);	return 0;}/* * Data management: read and write */static ssize_t scull_p_read (struct file *filp, char __user *buf, size_t count,                loff_t *f_pos){	struct scull_pipe *dev = filp->private_data;	if (down_interruptible(&dev->sem))		return -ERESTARTSYS;	while (dev->rp == dev->wp) { /* nothing to read */		up(&dev->sem); /* release the lock */		if (filp->f_flags & O_NONBLOCK)			return -EAGAIN;		PDEBUG("\"%s\" reading: going to sleep\n", current->comm);		if (wait_event_interruptible(dev->inq, (dev->rp != dev->wp)))			return -ERESTARTSYS; /* signal: tell the fs layer to handle it */		/* otherwise loop, but first reacquire the lock */		if (down_interruptible(&dev->sem))			return -ERESTARTSYS;	}	/* ok, data is there, return something */	if (dev->wp > dev->rp)		count = min(count, (size_t)(dev->wp - dev->rp));	else /* the write pointer has wrapped, return data up to dev->end */		count = min(count, (size_t)(dev->end - dev->rp));	if (copy_to_user(buf, dev->rp, count)) {		up (&dev->sem);		return -EFAULT;	}	dev->rp += count;	if (dev->rp == dev->end)		dev->rp = dev->buffer; /* wrapped */	up (&dev->sem);	/* finally, awake any writers and return */	wake_up_interruptible(&dev->outq);	PDEBUG("\"%s\" did read %li bytes\n",current->comm, (long)count);	return count;}/* Wait for space for writing; caller must hold device semaphore.  On * error the semaphore will be released before returning. */static int scull_getwritespace(struct scull_pipe *dev, struct file *filp){	while (spacefree(dev) == 0) { /* full */		DEFINE_WAIT(wait);				up(&dev->sem);		if (filp->f_flags & O_NONBLOCK)			return -EAGAIN;		PDEBUG("\"%s\" writing: going to sleep\n",current->comm);		prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);		if (spacefree(dev) == 0)			schedule();		finish_wait(&dev->outq, &wait);		if (signal_pending(current))			return -ERESTARTSYS; /* signal: tell the fs layer to handle it */		if (down_interruptible(&dev->sem))			return -ERESTARTSYS;	}	return 0;}	/* How much space is free? */static int spacefree(struct scull_pipe *dev){	if (dev->rp == dev->wp)		return dev->buffersize - 1;	return ((dev->rp + dev->buffersize - dev->wp) % dev->buffersize) - 1;}static ssize_t scull_p_write(struct file *filp, const char __user *buf, size_t count,                loff_t *f_pos){	struct scull_pipe *dev = filp->private_data;	int result;	if (down_interruptible(&dev->sem))		return -ERESTARTSYS;	/* Make sure there's space to write */	result = scull_getwritespace(dev, filp);	if (result)		return result; /* scull_getwritespace called up(&dev->sem) */	/* ok, space is there, accept something */	count = min(count, (size_t)spacefree(dev));	if (dev->wp >= dev->rp)		count = min(count, (size_t)(dev->end - dev->wp)); /* to end-of-buf */	else /* the write pointer has wrapped, fill up to rp-1 */		count = min(count, (size_t)(dev->rp - dev->wp - 1));	PDEBUG("Going to accept %li bytes to %p from %p\n", (long)count, dev->wp, buf);	if (copy_from_user(dev->wp, buf, count)) {		up (&dev->sem);		return -EFAULT;	}	dev->wp += count;	if (dev->wp == dev->end)		dev->wp = dev->buffer; /* wrapped */	up(&dev->sem);	/* finally, awake any reader */	wake_up_interruptible(&dev->inq);  /* blocked in read() and select() */	/* and signal asynchronous readers, explained late in chapter 5 */	if (dev->async_queue)		kill_fasync(&dev->async_queue, SIGIO, POLL_IN);	PDEBUG("\"%s\" did write %li bytes\n",current->comm, (long)count);	return count;}static unsigned int scull_p_poll(struct file *filp, poll_table *wait){	struct scull_pipe *dev = filp->private_data;	unsigned int mask = 0;	/*	 * The buffer is circular; it is considered full	 * if "wp" is right behind "rp" and empty if the	 * two are equal.	 */	down(&dev->sem);	poll_wait(filp, &dev->inq,  wait);	poll_wait(filp, &dev->outq, wait);	if (dev->rp != dev->wp)		mask |= POLLIN | POLLRDNORM;	/* readable */	if (spacefree(dev))		mask |= POLLOUT | POLLWRNORM;	/* writable */	up(&dev->sem);	return mask;}static int scull_p_fasync(int fd, struct file *filp, int mode){	struct scull_pipe *dev = filp->private_data;	return fasync_helper(fd, filp, mode, &dev->async_queue);}/* FIXME this should use seq_file */#ifdef SCULL_DEBUGstatic void scullp_proc_offset(char *buf, char **start, off_t *offset, int *len){	if (*offset == 0)		return;	if (*offset >= *len) {	/* Not there yet */		*offset -= *len;		*len = 0;	}	else {			/* We're into the interesting stuff now */		*start = buf + *offset;		*offset = 0;	}}static int scull_read_p_mem(char *buf, char **start, off_t offset, int count,		int *eof, void *data){	int i, len;	struct scull_pipe *p;#define LIMIT (PAGE_SIZE-200)	/* don't print any more after this size */	*start = buf;	len = sprintf(buf, "Default buffersize is %i\n", scull_p_buffer);	for(i = 0; i<scull_p_nr_devs && len <= LIMIT; i++) {		p = &scull_p_devices[i];		if (down_interruptible(&p->sem))			return -ERESTARTSYS;		len += sprintf(buf+len, "\nDevice %i: %p\n", i, p);/*		len += sprintf(buf+len, "   Queues: %p %p\n", p->inq, p->outq);*/		len += sprintf(buf+len, "   Buffer: %p to %p (%i bytes)\n", p->buffer, p->end, p->buffersize);		len += sprintf(buf+len, "   rp %p   wp %p\n", p->rp, p->wp);		len += sprintf(buf+len, "   readers %i   writers %i\n", p->nreaders, p->nwriters);		up(&p->sem);		scullp_proc_offset(buf, start, &offset, &len);	}	*eof = (len <= LIMIT);	return len;}#endif/* * The file operations for the pipe device * (some are overlayed with bare scull) */struct file_operations scull_pipe_fops = {	.owner =	THIS_MODULE,	.llseek =	no_llseek,	.read =		scull_p_read,	.write =	scull_p_write,	.poll =		scull_p_poll,	.ioctl =	scull_ioctl,	.open =		scull_p_open,	.release =	scull_p_release,	.fasync =	scull_p_fasync,};/* * Set up a cdev entry. */static void scull_p_setup_cdev(struct scull_pipe *dev, int index){	int err, devno = scull_p_devno + index;    	cdev_init(&dev->cdev, &scull_pipe_fops);	dev->cdev.owner = THIS_MODULE;	err = cdev_add (&dev->cdev, devno, 1);	/* Fail gracefully if need be */	if (err)		printk(KERN_NOTICE "Error %d adding scullpipe%d", err, index);} /* * Initialize the pipe devs; return how many we did. */int scull_p_init(dev_t firstdev){	int i, result;	result = register_chrdev_region(firstdev, scull_p_nr_devs, "scullp");	if (result < 0) {		printk(KERN_NOTICE "Unable to get scullp region, error %d\n", result);		return 0;	}	scull_p_devno = firstdev;	scull_p_devices = kmalloc(scull_p_nr_devs * sizeof(struct scull_pipe), GFP_KERNEL);	if (scull_p_devices == NULL) {		unregister_chrdev_region(firstdev, scull_p_nr_devs);		return 0;	}	memset(scull_p_devices, 0, scull_p_nr_devs * sizeof(struct scull_pipe));	for (i = 0; i < scull_p_nr_devs; i++) {		init_waitqueue_head(&(scull_p_devices[i].inq));		init_waitqueue_head(&(scull_p_devices[i].outq));		init_MUTEX(&scull_p_devices[i].sem);		scull_p_setup_cdev(scull_p_devices + i, i);	}#ifdef SCULL_DEBUG	create_proc_read_entry("scullpipe", 0, NULL, scull_read_p_mem, NULL);#endif	return scull_p_nr_devs;}/* * This is called by cleanup_module or on failure. * It is required to never fail, even if nothing was initialized first */void scull_p_cleanup(void){	int i;#ifdef SCULL_DEBUG	remove_proc_entry("scullpipe", NULL);#endif	if (!scull_p_devices)		return; /* nothing else to release */	for (i = 0; i < scull_p_nr_devs; i++) {		cdev_del(&scull_p_devices[i].cdev);		kfree(scull_p_devices[i].buffer);	}	kfree(scull_p_devices);	unregister_chrdev_region(scull_p_devno, scull_p_nr_devs);	scull_p_devices = NULL; /* pedantic */}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
一本一道综合狠狠老| a亚洲天堂av| 亚洲高清在线精品| 亚洲一区二三区| 亚洲午夜在线电影| 图片区日韩欧美亚洲| 亚洲成人自拍一区| 男女性色大片免费观看一区二区| 亚洲综合偷拍欧美一区色| 亚洲最色的网站| 亚洲va韩国va欧美va精品| 视频一区视频二区中文字幕| 日韩av电影天堂| 国产精品 欧美精品| 成人在线综合网| 91激情在线视频| 日韩一区二区免费高清| 日韩女优av电影| 国产午夜亚洲精品理论片色戒| 国产精品天天摸av网| 有码一区二区三区| 日韩国产欧美在线视频| 黄页网站大全一区二区| 成人综合在线观看| 在线观看亚洲a| 日韩亚洲电影在线| 中文字幕制服丝袜成人av| 亚洲午夜久久久久中文字幕久| 免费亚洲电影在线| 99久久综合国产精品| 911国产精品| 国产精品乱码久久久久久| 亚洲妇熟xx妇色黄| 国产精品一区免费在线观看| 色域天天综合网| 久久久久久久综合日本| 亚洲最大成人网4388xx| 国产一区二区免费视频| 欧美日韩亚洲丝袜制服| 国产精品视频九色porn| 日韩av一区二| 在线视频国内一区二区| 久久综合五月天婷婷伊人| 亚洲综合激情网| 成人国产在线观看| 日韩一卡二卡三卡| 一区二区高清视频在线观看| 国产91对白在线观看九色| 欧美视频在线不卡| 国产精品国产三级国产普通话蜜臀| 色88888久久久久久影院按摩 | 日韩亚洲欧美成人一区| 国产精品女主播在线观看| 日韩不卡免费视频| 91黄色在线观看| 久久青草欧美一区二区三区| 午夜久久久久久电影| www.av亚洲| 国产农村妇女毛片精品久久麻豆 | 国产麻豆精品一区二区| 欧美精品第1页| 一区二区三区精品视频在线| 99久久综合色| 中文字幕在线一区| 国产精品亚洲视频| 欧美精品一区二区三区在线播放| 婷婷亚洲久悠悠色悠在线播放 | 狠狠狠色丁香婷婷综合激情 | 国产伦精一区二区三区| 日韩免费在线观看| 毛片不卡一区二区| 精品欧美乱码久久久久久1区2区| 日韩国产成人精品| 日韩一区二区三免费高清| 久久国产福利国产秒拍| 欧美zozozo| 国产成都精品91一区二区三 | 91亚洲男人天堂| 亚洲精品国产无天堂网2021| 91看片淫黄大片一级在线观看| 中文字幕中文字幕一区二区| 99久久免费精品高清特色大片| 国产精品久久精品日日| 91网站在线播放| 一区二区三区四区五区视频在线观看| 欧美专区日韩专区| 日本一不卡视频| 亚洲精品在线三区| 成人国产视频在线观看| 一二三区精品福利视频| 欧美丰满少妇xxxbbb| 精品制服美女丁香| 日本一区二区三区电影| 99re视频这里只有精品| 亚洲影视资源网| 精品成人一区二区三区四区| 成人精品视频.| 亚洲一区二区中文在线| 久久先锋影音av鲁色资源| 97超碰欧美中文字幕| 亚洲国产人成综合网站| 亚洲精品一区二区三区影院| k8久久久一区二区三区| 日精品一区二区| 国产欧美日本一区二区三区| 色一区在线观看| 久久精品999| 亚洲精品国产一区二区三区四区在线| 91精品国产一区二区人妖| 国产麻豆精品久久一二三| 亚洲国产aⅴ成人精品无吗| 久久久久久久性| 欧美熟乱第一页| 成人app下载| 久久国产精品区| 亚洲国产乱码最新视频 | 粉嫩在线一区二区三区视频| 一区二区三区不卡在线观看| 久久蜜桃一区二区| 欧美绝品在线观看成人午夜影视| 国产黄色精品网站| 日本亚洲视频在线| 一区二区三区中文字幕精品精品| 久久影院午夜论| 日韩三级精品电影久久久 | 日韩一级免费一区| av电影在线观看一区| 精品一区二区三区免费观看 | 亚洲婷婷综合久久一本伊一区| 欧美大片一区二区| 欧美精品乱码久久久久久按摩| av亚洲精华国产精华精| 国产不卡视频在线观看| 国产一区二区三区久久悠悠色av | 激情另类小说区图片区视频区| 一区二区三区在线视频免费观看| 国产片一区二区三区| 日韩欧美视频在线| 91精品国产欧美一区二区18 | 99re6这里只有精品视频在线观看| 韩国视频一区二区| 久久精品999| 久久99精品久久久久| 免费精品99久久国产综合精品| 首页国产欧美久久| 免费黄网站欧美| 蜜臂av日日欢夜夜爽一区| 奇米888四色在线精品| 天堂成人国产精品一区| 亚瑟在线精品视频| 日韩经典中文字幕一区| 午夜精品免费在线观看| 天天做天天摸天天爽国产一区| 亚洲123区在线观看| 日本成人在线不卡视频| 美日韩一区二区三区| 精品一区二区综合| 国产一区二区三区四区在线观看 | 欧美在线高清视频| 欧美色精品天天在线观看视频| 欧美日韩国产片| 欧美一级欧美三级在线观看| 日韩欧美电影在线| 国产人妖乱国产精品人妖| 亚洲欧美综合另类在线卡通| 亚洲欧美国产77777| 亚洲va韩国va欧美va| 韩日精品视频一区| 成人av在线播放网站| 欧美日韩性生活| 26uuu精品一区二区在线观看| 国产午夜精品美女毛片视频| 亚洲免费视频中文字幕| 亚洲3atv精品一区二区三区| 极品销魂美女一区二区三区| 粉嫩aⅴ一区二区三区四区五区| www.久久久久久久久| 欧美精品色综合| 久久久99久久| 亚洲另类一区二区| 日本午夜精品视频在线观看| 丁香亚洲综合激情啪啪综合| 在线亚洲一区观看| 26uuu精品一区二区三区四区在线| 日韩一区欧美一区| 免费高清视频精品| 91一区二区在线观看| 欧美mv日韩mv国产网站| 自拍偷拍欧美精品| 国内精品在线播放| 欧美人伦禁忌dvd放荡欲情| 久久九九久久九九| 首页国产欧美久久| 91视频免费观看| 日韩久久精品一区| 亚洲高清免费在线| 成人免费观看视频| 久久影音资源网| 日本美女一区二区| 欧美日韩一区二区三区不卡|