fasync的使用

app程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>

#define DEVFILE "/dev/fa_dev"

static volatile unsigned long eflag = 1;

static void sigio_handler(int signo)
{
    printf("Get the SIGIO signal, we exit the application!\n");
    eflag = 0;
}

static int block_sigio(void)
{
    sigset_t set, old;
    int ret;

    sigemptyset(&set);
    sigaddset(&set, SIGIO);
    sigprocmask(SIG_BLOCK, &set, &old);
    ret = sigismember(&old, SIGIO);
    return ret;
}

static void unblock_sigio(int blocked)
{
    sigset_t set;
    if (!blocked) {
        sigemptyset(&set);
        sigaddset(&set, SIGIO);
        sigprocmask(SIG_UNBLOCK, &set, NULL);
    }
}

int main(void)
{
    int fd;
    struct sigaction sigact, oldact;
    int oflag;
    int blocked;

    blocked = block_sigio();
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigact.sa_handler = sigio_handler;
    if (sigaction(SIGIO, &sigact, &oldact) < 0) {
        printf("sigaction failed!\n");
        unblock_sigio(blocked);
        return -1;
    }
    unblock_sigio(blocked);
    fd = open(DEVFILE, O_RDWR);
    if (fd >= 0) {
        fcntl(fd, F_SETOWN, getpid());
        oflag = fcntl(fd, F_GETFL);
        fcntl(fd, F_SETFL, oflag | FASYNC);
        printf("loop...\n");
        while (eflag);
        close(fd);
    }
    return 0;
}

 

模块

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/signal.h>
#include <asm/siginfo.h>

static struct cdev *pcdev;
static dev_t ndev;
static struct class *fa_cls;
static struct device*fadev;

static unsigned long flag = 0;
static struct fasync_struct *sigio_list;

static ssize_t read_flag(struct device *dev, struct device_attribute *attr, char *buf)
{
    size_t count = 0;
    count += sprintf(&buf[count], "%lu\n", flag);
    return count;
}

static ssize_t write_flag(struct device *dev, struct device_attribute *attr, char *buf, size_t count)
{
    flag = buf[0] - '0';
    kill_fasync(&sigio_list, SIGIO, POLL_IN);
    return count;
}

static struct device_attribute flag_attr =
     __ATTR(flag, S_IRUGO|S_IWUSR, read_flag, write_flag);

static int fa_open(struct inode *inode, struct file *flp)
{
    return 0;
}

static int fa_async(int fd, struct file *filp, int onflag)
{
    return fasync_helper(fd, filp, onflag, &sigio_list);
}


static struct file_operations ops = {
    .owner = THIS_MODULE,
    .open = fa_open,
    .fasync = fa_async,
};


static int fa_init(void)
{
    int ret = 0;
    ret = alloc_chrdev_region(&ndev, 0, 1, "fa_dev");
    if (ret < 0)
        return ret;
    pcdev = cdev_alloc();
    cdev_init(pcdev, &ops);
    pcdev->owner = THIS_MODULE;
    cdev_add(pcdev, ndev, 1);
    fa_cls = class_create(THIS_MODULE, "fa_dev");
    if (IS_ERR(fa_cls))
        return PTR_ERR(fa_cls);
    fadev = device_create(fa_cls, NULL, ndev, NULL, "fa_dev");
    if (IS_ERR(fadev))
        return PTR_ERR(fadev);
    ret = device_create_file(fadev, &flag_attr);
    return ret;
}


static void fa_exit(void)
{
    device_remove_file(fadev, &flag_attr);
    device_destroy(fa_cls, ndev);
    class_destroy(fa_cls);
    cdev_del(pcdev);
    unregister_chrdev_region(ndev, 1);
}

module_init(fa_init);
module_exit(fa_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("dennis");

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值