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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? pipe.c

?? linux設(shè)備驅(qū)動第二版例子程序
?? 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. * */ #ifndef __KERNEL__#  define __KERNEL__#endif#ifndef MODULE#  define MODULE#endif#define __NO_VERSION__#include <linux/module.h>  /* get MOD_DEC_USE_COUNT, not the version string */#include <linux/version.h> /* needed for the conditionals in scull.h */#include <linux/kernel.h> /* printk() */#include <linux/malloc.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 "scull.h"        /* local definitions and sysdep.h */#ifndef min#  define min(a,b) ((a)<(b) ? (a) : (b)) /* we use it in this file */#endiftypedef 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 */    devfs_handle_t handle;         /* only used if devfs is there */} Scull_Pipe;/* parameters */int scull_p_nr_devs = SCULL_P_NR_DEVS;  /* number of pipe devices */int scull_p_buffer =  SCULL_P_BUFFER;   /* buffer size */MODULE_PARM(scull_p_nr_devs,"i");MODULE_PARM(scull_p_buffer,"i");Scull_Pipe *scull_p_devices;/* * Open and close */int scull_p_open(struct inode *inode, struct file *filp){    Scull_Pipe *dev;    int num = NUM(inode->i_rdev);    if (!filp->private_data) {        if (num >= scull_p_nr_devs) return -ENODEV;        dev = &scull_p_devices[num];        filp->private_data = dev;    } else {        dev = filp->private_data;    }    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);        filp->private_data = dev;    MOD_INC_USE_COUNT;    return 0;}int scull_p_release(struct inode *inode, struct file *filp){    Scull_Pipe *dev = filp->private_data;    int scull_p_fasync(fasync_file fd, struct file *filp, int mode);#ifdef LINUX_20    scull_p_fasync(inode, filp, 0);#else    /* remove this filp from the asynchronously notified filp's */    scull_p_fasync(-1, filp, 0);#endif    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);    MOD_DEC_USE_COUNT;    return 0;}/* * Data management: read and write */ssize_t scull_p_read (struct file *filp, char *buf, size_t count,                loff_t *f_pos){    Scull_Pipe *dev = filp->private_data;    if (f_pos != &filp->f_pos) return -ESPIPE;    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, dev->wp - dev->rp);    else /* the write pointer has wrapped, return data up to dev->end */        count = min(count, 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;}static inline int spacefree(Scull_Pipe *dev){    if (dev->rp == dev->wp)        return dev->buffersize - 1;    return ((dev->rp + dev->buffersize - dev->wp) % dev->buffersize) - 1;}ssize_t scull_p_write(struct file *filp, const char *buf, size_t count,                loff_t *f_pos){    Scull_Pipe *dev = filp->private_data;        if (f_pos != &filp->f_pos) return -ESPIPE;    if (down_interruptible(&dev->sem))        return -ERESTARTSYS;        /* Make sure there's space to write */    while (spacefree(dev) == 0) { /* full */        up(&dev->sem);        if (filp->f_flags & O_NONBLOCK)            return -EAGAIN;        PDEBUG("\"%s\" writing: going to sleep\n",current->comm);        if (wait_event_interruptible(dev->outq, spacefree(dev) > 0))            return -ERESTARTSYS; /* signal: tell the fs layer to handle it */        if (down_interruptible(&dev->sem))            return -ERESTARTSYS;    }    /* ok, space is there, accept something */    count = min(count, spacefree(dev));    if (dev->wp >= dev->rp)        count = min(count, dev->end - dev->wp); /* up to end-of-buffer */    else /* the write pointer has wrapped, fill up to rp-1 */        count = min(count, 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;}#ifdef __USE_OLD_SELECT__int scull_p_poll(struct inode *inode, struct file *filp,                  int mode, select_table *table){    Scull_Pipe *dev = filp->private_data;    if (mode == SEL_IN) {        if (dev->rp != dev->wp) return 1; /* readable */        PDEBUG("Waiting to read\n");        select_wait(&dev->inq, table); /* wait for data */        return 0;    }    if (mode == SEL_OUT) {        /*         * The buffer is circular; it is considered full         * if "wp" is right behind "rp". "left" is 0 if the         * buffer is empty, and it is "1" if it is completely full.         */        int left = (dev->rp + dev->buffersize - dev->wp) % dev->buffersize;        if (left != 1) return 1; /* writable */        PDEBUG("Waiting to write\n");        select_wait(&dev->outq, table); /* wait for free space */        return 0;    }    return 0; /* never exception-able */}#else /* Use poll instead, already shown */unsigned int scull_p_poll(struct file *filp, poll_table *wait){    Scull_Pipe *dev = filp->private_data;    unsigned int mask = 0;    /*     * The buffer is circular; it is considered full     * if "wp" is right behind "rp". "left" is 0 if the     * buffer is empty, and it is "1" if it is completely full.     */    int left = (dev->rp + dev->buffersize - dev->wp) % dev->buffersize;    poll_wait(filp, &dev->inq,  wait);    poll_wait(filp, &dev->outq, wait);    if (dev->rp != dev->wp) mask |= POLLIN | POLLRDNORM;  /* readable */    if (left != 1)          mask |= POLLOUT | POLLWRNORM; /* writable */    return mask;}#endifint scull_p_fasync(fasync_file fd, struct file *filp, int mode){    Scull_Pipe *dev = filp->private_data;    return fasync_helper(fd, filp, mode, &dev->async_queue);}loff_t scull_p_llseek(struct file *filp,  loff_t off, int whence){    return -ESPIPE; /* unseekable */}#ifdef SCULL_DEBUGvoid 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;    }}int scull_read_p_mem(char *buf, char **start, off_t offset,                   int count, int *eof, void *data){    int i, len;    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;}#ifdef USE_PROC_REGISTERstatic int scull_p_get_info(char *buf, char **start, off_t offset, int len,                int unused){    int eof = 0;    return scull_read_p_mem(buf, start, offset, len, &eof, NULL);}struct proc_dir_entry scull_proc_p_entry = {        0,                  /* low_ino: the inode -- dynamic */        9, "scullpipe",     /* len of name and name */        S_IFREG | S_IRUGO,  /* mode */        1, 0, 0,            /* nlinks, owner, group */        0, NULL,            /* size - unused; operations -- use default */        &scull_p_get_info,  /* function used to read data */        /* nothing more */    };static inline void create_proc_read_entry(const char *name, mode_t mode,                struct proc_dir_entry *base, void *read_func, void *data){    proc_register_dynamic(&proc_root, &scull_proc_p_entry);}static inline void remove_proc_entry(char *name, void *parent){    proc_unregister(&proc_root, scull_proc_p_entry.low_ino);}#endif /* USE_PROC_REGISTER */#endif/* * 2.0 wrappers */#ifdef LINUX_20static int scull_p_lseek_20(struct inode *ino, struct file *f,                off_t offset, int whence){    return (int)scull_p_llseek(f, offset, whence);}int scull_p_read_20(struct inode *ino, struct file *f, char *buf, int count){    return (int)scull_p_read(f, buf, count, &f->f_pos);}int scull_p_write_20(struct inode *ino, struct file *f, const char *b, int c){    return (int)scull_p_write(f, b, c, &f->f_pos);}void scull_p_release_20(struct inode *ino, struct file *f){    scull_p_release(ino, f);}#define scull_p_llseek scull_p_lseek_20#define scull_p_read scull_p_read_20#define scull_p_write scull_p_write_20#define scull_p_release scull_p_release_20#define llseek lseek#define poll select#endif/* * The file operations for the pipe device * (some are overlayed with bare scull) */struct file_operations scull_pipe_fops = {    llseek:     scull_p_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,};char pipename[8]; /* only used for devfs names */int scull_p_init(void){    int i;    SET_MODULE_OWNER(&scull_pipe_fops);    scull_p_devices = kmalloc(scull_p_nr_devs * sizeof(Scull_Pipe),                              GFP_KERNEL);    if (scull_p_devices == NULL)        return -ENOMEM;    memset(scull_p_devices, 0, scull_p_nr_devs * sizeof(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));        sema_init(&scull_p_devices[i].sem, 1);#ifdef CONFIG_DEVFS_FS        sprintf(pipename, "pipe%i", i);        scull_p_devices[i].handle =            devfs_register(scull_devfs_dir, pipename,                           DEVFS_FL_AUTO_DEVNUM,                           0, 0, S_IFCHR | S_IRUGO | S_IWUGO,                           &scull_pipe_fops,                           scull_p_devices + i);        if (!scull_p_devices[i].handle) {            /* ignore errors, at worse we have less devices */            printk(KERN_WARNING                   "scull: can't register pipe device nr. %i\n", i);        }#endif    }#ifdef SCULL_DEBUG    create_proc_read_entry("scullpipe", 0, NULL, scull_read_p_mem, NULL);#endif    return 0;}/* * 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", 0);#endif    if (!scull_p_devices) return; /* nothing else to release */    for (i=0; i < scull_p_nr_devs; i++) {        if (scull_p_devices[i].buffer)            kfree(scull_p_devices[i].buffer);        devfs_unregister(scull_p_devices[i].handle);    }    kfree(scull_p_devices);    scull_p_devices = NULL; /* pedantic */    return;}

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91丝袜美腿高跟国产极品老师| 国产精品电影一区二区| 日韩欧美国产一二三区| 日韩色视频在线观看| 欧美一区中文字幕| 日韩限制级电影在线观看| 日韩一区国产二区欧美三区| 日韩免费福利电影在线观看| 精品国产乱码久久久久久蜜臀| 色婷婷综合久久久久中文一区二区| 91福利精品第一导航| 欧美日韩视频第一区| 日韩欧美在线一区二区三区| 精品对白一区国产伦| 中文字幕免费观看一区| 亚洲老妇xxxxxx| 天天av天天翘天天综合网色鬼国产| 日韩成人免费看| 国产一区二区三区国产| zzijzzij亚洲日本少妇熟睡| 在线看国产日韩| 日韩免费性生活视频播放| 欧美一区二区三级| 久久久国际精品| 亚洲精品日日夜夜| 一区二区在线免费观看| 麻豆专区一区二区三区四区五区| 激情欧美一区二区| 播五月开心婷婷综合| 欧美三级电影在线看| 精品91自产拍在线观看一区| 1区2区3区欧美| 午夜久久久久久| 国产成人av电影在线| 欧美日韩综合在线| 亚洲精品亚洲人成人网在线播放| 激情伊人五月天久久综合| 丁香五精品蜜臀久久久久99网站| 欧美日韩国产片| 国产精品网曝门| 久久精品国产久精国产| 欧美少妇bbb| 国产欧美日韩视频一区二区 | 日韩一级免费一区| 一区二区三区在线视频免费| 国产大片一区二区| 日韩欧美资源站| 午夜精品久久久久久久99樱桃| 99视频国产精品| 国产夜色精品一区二区av| 免费亚洲电影在线| 7777女厕盗摄久久久| 亚洲激情在线激情| 99这里只有久久精品视频| 久久久噜噜噜久噜久久综合| 麻豆成人在线观看| 91精品国产综合久久精品app| 一区二区三区资源| 91丨九色丨尤物| 中文字幕制服丝袜一区二区三区| 国产精品自拍av| 精品国产第一区二区三区观看体验 | 中文字幕一区二区三区四区不卡 | 欧美一区二区三区视频在线| 午夜亚洲国产au精品一区二区| 91小视频在线观看| 亚洲欧洲国产专区| 福利一区二区在线| 国产精品日产欧美久久久久| 成人一区在线观看| 中文字幕精品一区| 成人的网站免费观看| 国产精品午夜在线观看| 不卡高清视频专区| 亚洲日本在线天堂| 色婷婷狠狠综合| 一区二区三区欧美亚洲| 在线观看视频一区二区欧美日韩| 一区二区三区中文字幕精品精品 | 亚洲最新视频在线播放| 91精品办公室少妇高潮对白| 亚洲一区二区三区中文字幕| 欧美性大战久久久久久久| 图片区日韩欧美亚洲| 91精品国产综合久久久久久久 | 久久久综合视频| 成人综合婷婷国产精品久久蜜臀 | 成人黄色软件下载| 中文字幕一区视频| 欧美中文字幕久久| 日韩有码一区二区三区| 精品国免费一区二区三区| 国产综合色在线| 国产精品对白交换视频| 91美女蜜桃在线| 亚洲国产精品久久久久秋霞影院| 6080午夜不卡| 国产精品一二三四区| 欧美国产国产综合| 色婷婷精品大视频在线蜜桃视频| 亚洲国产欧美一区二区三区丁香婷| 欧美久久一二区| 精品一区二区三区视频| 国产精品免费久久久久| 欧洲色大大久久| 琪琪一区二区三区| 欧美国产亚洲另类动漫| 在线观看日韩精品| 六月婷婷色综合| 国产精品女主播av| 精品视频一区二区不卡| 蜜桃精品视频在线观看| 日本一区二区免费在线观看视频 | 国产欧美综合色| 97国产一区二区| 欧美aaaaa成人免费观看视频| 国产亚洲视频系列| 欧美日韩高清在线| 国产夫妻精品视频| 亚洲国产视频在线| 国产色产综合色产在线视频| 欧美日韩综合色| 高清不卡一区二区| 亚洲国产精品久久久久秋霞影院| 久久网站最新地址| 欧美色综合久久| 国产精品888| 亚洲国产中文字幕在线视频综合| 久久精品欧美一区二区三区不卡| 欧美性高清videossexo| 国产馆精品极品| 日韩av一区二区在线影视| 日韩一区在线看| 精品嫩草影院久久| 91成人看片片| 国产成人精品一区二区三区四区| 亚洲高清三级视频| 中文字幕一区二区三区视频| 精品日韩在线观看| 欧美最猛性xxxxx直播| 国产不卡高清在线观看视频| 日韩高清在线一区| 亚洲柠檬福利资源导航| 久久精品视频在线免费观看 | 久久精品国产精品亚洲精品| 亚洲最新视频在线观看| 国产精品久久网站| 久久婷婷久久一区二区三区| 69久久夜色精品国产69蝌蚪网| 色综合天天狠狠| 国产69精品一区二区亚洲孕妇 | 国产日本亚洲高清| 日韩一卡二卡三卡四卡| 欧洲生活片亚洲生活在线观看| 本田岬高潮一区二区三区| 精品一区免费av| 日韩电影一区二区三区| 亚洲一区二区精品3399| 亚洲欧美综合网| 国产日韩欧美精品电影三级在线| 日韩免费看网站| 91精品国产麻豆国产自产在线| 91福利精品第一导航| 91在线精品一区二区| 风流少妇一区二区| 精彩视频一区二区| 蜜桃91丨九色丨蝌蚪91桃色| 亚洲va欧美va人人爽午夜| 亚洲激情校园春色| 亚洲乱码日产精品bd| 亚洲欧美成aⅴ人在线观看| 国产精品国产三级国产普通话三级 | 136国产福利精品导航| 国产亚洲美州欧州综合国 | 成人免费高清视频| 国产一区二区三区电影在线观看| 精品一二线国产| 国内精品久久久久影院薰衣草| 麻豆精品国产91久久久久久| 欧美aaaaa成人免费观看视频| 免费在线观看精品| 久久精品国产精品亚洲精品| 极品少妇xxxx精品少妇| 蜜桃91丨九色丨蝌蚪91桃色| 久久69国产一区二区蜜臀| 久久国产精品区| 国产精品123| eeuss鲁片一区二区三区在线观看 eeuss鲁片一区二区三区在线看 | 在线观看免费一区| 欧美天堂亚洲电影院在线播放| 欧美日韩综合在线| 欧美精品一级二级三级| 欧美一级专区免费大片| 日韩视频在线永久播放| 精品久久久久久久久久久久久久久久久 | 夜色激情一区二区| 天天av天天翘天天综合网| 日韩精品乱码免费| 精品亚洲aⅴ乱码一区二区三区| 精品亚洲国产成人av制服丝袜|