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

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

?? access.c

?? Linux設備驅動的經典教材, 該電子書是第三版,并附有全部配套代碼.
?? C
字號:
/* * access.c -- the files with access control on open * * 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. * * $Id: access.c,v 1.17 2004/09/26 07:29:56 gregkh Exp $ *//* FIXME: cloned devices as a use for kobjects? */ #include <linux/kernel.h> /* printk() */#include <linux/module.h>#include <linux/slab.h>   /* kmalloc() */#include <linux/fs.h>     /* everything... */#include <linux/errno.h>  /* error codes */#include <linux/types.h>  /* size_t */#include <linux/fcntl.h>#include <linux/cdev.h>#include <linux/tty.h>#include <asm/atomic.h>#include <linux/list.h>#include "scull.h"        /* local definitions */static dev_t scull_a_firstdev;  /* Where our range begins *//* * These devices fall back on the main scull operations. They only * differ in the implementation of open() and close() *//************************************************************************ * * The first device is the single-open one, *  it has an hw structure and an open count */static struct scull_dev scull_s_device;static atomic_t scull_s_available = ATOMIC_INIT(1);static int scull_s_open(struct inode *inode, struct file *filp){	struct scull_dev *dev = &scull_s_device; /* device information */	if (! atomic_dec_and_test (&scull_s_available)) {		atomic_inc(&scull_s_available);		return -EBUSY; /* already open */	}	/* then, everything else is copied from the bare scull device */	if ( (filp->f_flags & O_ACCMODE) == O_WRONLY)		scull_trim(dev);	filp->private_data = dev;	return 0;          /* success */}static int scull_s_release(struct inode *inode, struct file *filp){	atomic_inc(&scull_s_available); /* release the device */	return 0;}/* * The other operations for the single-open device come from the bare device */struct file_operations scull_sngl_fops = {	.owner =	THIS_MODULE,	.llseek =     	scull_llseek,	.read =       	scull_read,	.write =      	scull_write,	.ioctl =      	scull_ioctl,	.open =       	scull_s_open,	.release =    	scull_s_release,};/************************************************************************ * * Next, the "uid" device. It can be opened multiple times by the * same user, but access is denied to other users if the device is open */static struct scull_dev scull_u_device;static int scull_u_count;	/* initialized to 0 by default */static uid_t scull_u_owner;	/* initialized to 0 by default */static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED;static int scull_u_open(struct inode *inode, struct file *filp){	struct scull_dev *dev = &scull_u_device; /* device information */	spin_lock(&scull_u_lock);	if (scull_u_count && 			(scull_u_owner != current->uid) &&  /* allow user */			(scull_u_owner != current->euid) && /* allow whoever did su */			!capable(CAP_DAC_OVERRIDE)) { /* still allow root */		spin_unlock(&scull_u_lock);		return -EBUSY;   /* -EPERM would confuse the user */	}	if (scull_u_count == 0)		scull_u_owner = current->uid; /* grab it */	scull_u_count++;	spin_unlock(&scull_u_lock);/* then, everything else is copied from the bare scull device */	if ((filp->f_flags & O_ACCMODE) == O_WRONLY)		scull_trim(dev);	filp->private_data = dev;	return 0;          /* success */}static int scull_u_release(struct inode *inode, struct file *filp){	spin_lock(&scull_u_lock);	scull_u_count--; /* nothing else */	spin_unlock(&scull_u_lock);	return 0;}/* * The other operations for the device come from the bare device */struct file_operations scull_user_fops = {	.owner =      THIS_MODULE,	.llseek =     scull_llseek,	.read =       scull_read,	.write =      scull_write,	.ioctl =      scull_ioctl,	.open =       scull_u_open,	.release =    scull_u_release,};/************************************************************************ * * Next, the device with blocking-open based on uid */static struct scull_dev scull_w_device;static int scull_w_count;	/* initialized to 0 by default */static uid_t scull_w_owner;	/* initialized to 0 by default */static DECLARE_WAIT_QUEUE_HEAD(scull_w_wait);static spinlock_t scull_w_lock = SPIN_LOCK_UNLOCKED;static inline int scull_w_available(void){	return scull_w_count == 0 ||		scull_w_owner == current->uid ||		scull_w_owner == current->euid ||		capable(CAP_DAC_OVERRIDE);}static int scull_w_open(struct inode *inode, struct file *filp){	struct scull_dev *dev = &scull_w_device; /* device information */	spin_lock(&scull_w_lock);	while (! scull_w_available()) {		spin_unlock(&scull_w_lock);		if (filp->f_flags & O_NONBLOCK) return -EAGAIN;		if (wait_event_interruptible (scull_w_wait, scull_w_available()))			return -ERESTARTSYS; /* tell the fs layer to handle it */		spin_lock(&scull_w_lock);	}	if (scull_w_count == 0)		scull_w_owner = current->uid; /* grab it */	scull_w_count++;	spin_unlock(&scull_w_lock);	/* then, everything else is copied from the bare scull device */	if ((filp->f_flags & O_ACCMODE) == O_WRONLY)		scull_trim(dev);	filp->private_data = dev;	return 0;          /* success */}static int scull_w_release(struct inode *inode, struct file *filp){	int temp;	spin_lock(&scull_w_lock);	scull_w_count--;	temp = scull_w_count;	spin_unlock(&scull_w_lock);	if (temp == 0)		wake_up_interruptible_sync(&scull_w_wait); /* awake other uid's */	return 0;}/* * The other operations for the device come from the bare device */struct file_operations scull_wusr_fops = {	.owner =      THIS_MODULE,	.llseek =     scull_llseek,	.read =       scull_read,	.write =      scull_write,	.ioctl =      scull_ioctl,	.open =       scull_w_open,	.release =    scull_w_release,};/************************************************************************ * * Finally the `cloned' private device. This is trickier because it * involves list management, and dynamic allocation. *//* The clone-specific data structure includes a key field */struct scull_listitem {	struct scull_dev device;	dev_t key;	struct list_head list;    };/* The list of devices, and a lock to protect it */static LIST_HEAD(scull_c_list);static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED;/* A placeholder scull_dev which really just holds the cdev stuff. */static struct scull_dev scull_c_device;   /* Look for a device or create one if missing */static struct scull_dev *scull_c_lookfor_device(dev_t key){	struct scull_listitem *lptr;	list_for_each_entry(lptr, &scull_c_list, list) {		if (lptr->key == key)			return &(lptr->device);	}	/* not found */	lptr = kmalloc(sizeof(struct scull_listitem), GFP_KERNEL);	if (!lptr)		return NULL;	/* initialize the device */	memset(lptr, 0, sizeof(struct scull_listitem));	lptr->key = key;	scull_trim(&(lptr->device)); /* initialize it */	init_MUTEX(&(lptr->device.sem));	/* place it in the list */	list_add(&lptr->list, &scull_c_list);	return &(lptr->device);}static int scull_c_open(struct inode *inode, struct file *filp){	struct scull_dev *dev;	dev_t key; 	if (!current->signal->tty) { 		PDEBUG("Process \"%s\" has no ctl tty\n", current->comm);		return -EINVAL;	}	key = tty_devnum(current->signal->tty);	/* look for a scullc device in the list */	spin_lock(&scull_c_lock);	dev = scull_c_lookfor_device(key);	spin_unlock(&scull_c_lock);	if (!dev)		return -ENOMEM;	/* then, everything else is copied from the bare scull device */	if ( (filp->f_flags & O_ACCMODE) == O_WRONLY)		scull_trim(dev);	filp->private_data = dev;	return 0;          /* success */}static int scull_c_release(struct inode *inode, struct file *filp){	/*	 * Nothing to do, because the device is persistent.	 * A `real' cloned device should be freed on last close	 */	return 0;}/* * The other operations for the device come from the bare device */struct file_operations scull_priv_fops = {	.owner =    THIS_MODULE,	.llseek =   scull_llseek,	.read =     scull_read,	.write =    scull_write,	.ioctl =    scull_ioctl,	.open =     scull_c_open,	.release =  scull_c_release,};/************************************************************************ * * And the init and cleanup functions come last */static struct scull_adev_info {	char *name;	struct scull_dev *sculldev;	struct file_operations *fops;} scull_access_devs[] = {	{ "scullsingle", &scull_s_device, &scull_sngl_fops },	{ "sculluid", &scull_u_device, &scull_user_fops },	{ "scullwuid", &scull_w_device, &scull_wusr_fops },	{ "sullpriv", &scull_c_device, &scull_priv_fops }};#define SCULL_N_ADEVS 4/* * Set up a single device. */static void scull_access_setup (dev_t devno, struct scull_adev_info *devinfo){	struct scull_dev *dev = devinfo->sculldev;	int err;	/* Initialize the device structure */	dev->quantum = scull_quantum;	dev->qset = scull_qset;	init_MUTEX(&dev->sem);	/* Do the cdev stuff. */	cdev_init(&dev->cdev, devinfo->fops);	kobject_set_name(&dev->cdev.kobj, devinfo->name);	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 %s\n", err, devinfo->name);		kobject_put(&dev->cdev.kobj);	} else		printk(KERN_NOTICE "%s registered at %x\n", devinfo->name, devno);}int scull_access_init(dev_t firstdev){	int result, i;	/* Get our number space */	result = register_chrdev_region (firstdev, SCULL_N_ADEVS, "sculla");	if (result < 0) {		printk(KERN_WARNING "sculla: device number registration failed\n");		return 0;	}	scull_a_firstdev = firstdev;	/* Set up each device. */	for (i = 0; i < SCULL_N_ADEVS; i++)		scull_access_setup (firstdev + i, scull_access_devs + i);	return SCULL_N_ADEVS;}/* * This is called by cleanup_module or on failure. * It is required to never fail, even if nothing was initialized first */void scull_access_cleanup(void){	struct scull_listitem *lptr, *next;	int i;	/* Clean up the static devs */	for (i = 0; i < SCULL_N_ADEVS; i++) {		struct scull_dev *dev = scull_access_devs[i].sculldev;		cdev_del(&dev->cdev);		scull_trim(scull_access_devs[i].sculldev);	}    	/* And all the cloned devices */	list_for_each_entry_safe(lptr, next, &scull_c_list, list) {		list_del(&lptr->list);		scull_trim(&(lptr->device));		kfree(lptr);	}	/* Free up our number space */	unregister_chrdev_region(scull_a_firstdev, SCULL_N_ADEVS);	return;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产福利一区二区三区在线视频| 色先锋久久av资源部| 成人av电影在线观看| 欧美日韩电影一区| 亚洲国产电影在线观看| 天天综合色天天综合色h| www.在线成人| 国产午夜精品在线观看| 午夜精品123| 一本在线高清不卡dvd| 久久久久久亚洲综合| 日本不卡高清视频| 欧美视频中文一区二区三区在线观看| 国产亚洲欧美一级| 狠狠色丁香久久婷婷综| 欧美电影一区二区| 亚洲成人先锋电影| 91国产丝袜在线播放| 中文字幕乱码一区二区免费| 精品在线视频一区| 精品久久久久久综合日本欧美| 亚洲一区二区三区四区五区黄| 99麻豆久久久国产精品免费优播| 久久蜜桃av一区二区天堂| 久久99国产精品久久99| 欧美一区二区福利在线| 日本成人在线网站| 欧美嫩在线观看| 天天影视网天天综合色在线播放| 色综合天天综合色综合av| 中文字幕亚洲一区二区av在线 | 亚洲精品国产一区二区精华液 | 国产91露脸合集magnet | 国产一区二区三区蝌蚪| 欧美精品一区二区三区蜜桃 | 免费观看91视频大全| 欧美日韩高清不卡| 天天做天天摸天天爽国产一区| 欧美日韩在线观看一区二区 | 欧美mv日韩mv国产网站| 看电影不卡的网站| 久久亚洲综合色一区二区三区| 久国产精品韩国三级视频| 欧美videofree性高清杂交| 久久99国产精品久久99果冻传媒| 久久免费视频一区| 99国产精品久久久久久久久久| 中文字幕亚洲一区二区av在线 | 成人免费毛片高清视频| 中文字幕一区二区三区在线播放| 色综合天天综合网天天看片| 亚洲成人动漫精品| 欧美不卡123| 高清不卡一区二区| 亚洲永久免费av| 日韩一二三区不卡| 国产毛片精品一区| 亚洲卡通动漫在线| 欧美一区二区三区成人| 国产精品影视在线观看| 亚洲蜜臀av乱码久久精品蜜桃| 欧美影院精品一区| 国产自产v一区二区三区c| 国产精品色一区二区三区| 在线这里只有精品| 狠狠v欧美v日韩v亚洲ⅴ| 国产精品不卡一区二区三区| 精品视频免费看| 国产乱码精品一品二品| 亚洲一区二区黄色| 久久久国产精品午夜一区ai换脸| 91丝袜呻吟高潮美腿白嫩在线观看| 香蕉久久夜色精品国产使用方法 | 精品久久久三级丝袜| 91视频在线看| 精品一区二区在线观看| 亚洲精品伦理在线| 久久理论电影网| 欧美日韩久久一区二区| 成人动漫中文字幕| 美腿丝袜亚洲三区| 一区二区三区国产豹纹内裤在线| www欧美成人18+| 欧美日本一道本在线视频| 高清在线不卡av| 美女性感视频久久| 亚洲一区在线观看免费观看电影高清| 久久久久久久久久久久久女国产乱 | 亚洲国产成人午夜在线一区| 欧美日韩成人在线一区| 91在线精品一区二区三区| 久久国产视频网| 日韩电影在线观看电影| 一区二区三区四区蜜桃| 中文字幕一区二区三区在线观看| 久久久91精品国产一区二区精品| 9191国产精品| 欧美日韩日日摸| 色一情一乱一乱一91av| 99久久综合99久久综合网站| 国产一二精品视频| 美女在线一区二区| 日韩精品一二三| 亚州成人在线电影| 午夜影视日本亚洲欧洲精品| 亚洲国产美国国产综合一区二区| 成人欧美一区二区三区在线播放| 国产农村妇女毛片精品久久麻豆| 精品国产乱码久久久久久老虎| 在线观看91av| 91精品国产91久久久久久一区二区| 日本精品视频一区二区三区| 91免费精品国自产拍在线不卡| www.日韩av| 91日韩精品一区| 99re成人在线| 91激情五月电影| 欧美亚洲日本国产| 欧美精品视频www在线观看| 欧美精品在线一区二区| 日韩一区二区电影在线| 日韩亚洲欧美在线| 精品国产在天天线2019| 精品理论电影在线| 国产日韩精品一区二区三区| 国产免费观看久久| 国产精品狼人久久影院观看方式| 亚洲视频一区在线| 亚洲一区中文日韩| 久久成人18免费观看| 国产二区国产一区在线观看| 成人涩涩免费视频| 欧洲人成人精品| 日韩一卡二卡三卡四卡| 久久久久久一级片| 亚洲日本丝袜连裤袜办公室| 亚洲综合激情网| 久久精品久久99精品久久| 粉嫩在线一区二区三区视频| 91小视频免费观看| 日韩三级中文字幕| 欧美国产日韩精品免费观看| 一区二区三区波多野结衣在线观看 | 一区二区三区不卡在线观看 | 欧美一区三区二区| 国产欧美一区在线| 亚洲天堂成人在线观看| 日韩国产欧美在线视频| 国产精品99久久久久久似苏梦涵 | 日韩欧美你懂的| 中文字幕免费不卡在线| 天天射综合影视| 国产成人免费av在线| 色噜噜偷拍精品综合在线| 91精品在线免费| 国产精品久久久久久久浪潮网站| 亚洲va欧美va天堂v国产综合| 韩国女主播成人在线观看| 色综合久久久久久久久| 欧美精品一区视频| 亚洲午夜av在线| 国产成人在线看| 日韩一区二区三区电影在线观看| 中文字幕一区三区| 久久国产精品99精品国产| 色婷婷亚洲一区二区三区| 精品91自产拍在线观看一区| 亚洲国产综合人成综合网站| 丁香啪啪综合成人亚洲小说| 欧美成人精品高清在线播放| 一级做a爱片久久| 丁香桃色午夜亚洲一区二区三区| 日韩精品一区二区三区在线播放| 中文字幕一区二区三中文字幕| 极品销魂美女一区二区三区| 在线观看国产一区二区| 国产精品九色蝌蚪自拍| 国内精品伊人久久久久av影院| 欧美丰满一区二区免费视频| 亚洲男人天堂av网| 成人av资源在线观看| 精品国产不卡一区二区三区| 日韩经典一区二区| 欧美天天综合网| 亚洲欧美日韩国产综合在线| 成人亚洲一区二区一| 久久久久国产免费免费| 麻豆精品国产91久久久久久 | 欧美自拍偷拍午夜视频| 国产精品短视频| 国产aⅴ综合色| 欧美精品一区视频| 国产精品中文字幕日韩精品 | 五月激情综合色| 欧美日韩国产天堂| 亚洲国产日韩精品| 欧美色网一区二区| 午夜精品成人在线| 7777精品伊人久久久大香线蕉 | 国产精品国产三级国产普通话99 |