kernel_fgets 内核态按行读取文件

kernel_fgets

1、kernel_fgets 说明

(等效于用户态fgets,若不太明白,可参考fgets函数)

函数说明:内核态从fp文件描述符里,读取最大max_size-1字节的一行字符串,并存储于buf中。

返回值:正确情况下返回buf指针,error情况下返回NULL

参数说明:buf,读取的字符串存储于buf中。max_size,最大读取的字节数+1。fp,内核态filp_open打开文件后获取的文件描述符。

char *kernel_fgets(char *buf, int max_size, struct file *fp)
{
    int i = 0;
    int read_size;

    if(0 > max_size)
    {
        printk(KERN_EMERG "read max_size invalid\n");
        return NULL;
    }

    read_size = vfs_read(fp, buf, max_size, &(fp->f_pos));
    if(1 > read_size)
    {
        return NULL;
    }

    while(buf[i++] != '\n' && i < read_size);
    buf[i-1] = '\0';
    fp->f_pos += i-read_size;
    return buf;
}

 

2、API使用示例代码:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/string.h>

    mm_segment_t fs;
    char buf_0[28] = "0";






char *kernel_fgets(char *buf, int max_size, struct file *fp)
{
    int i = 0;
    int read_size;

    if(0 > max_size)
    {
        printk(KERN_EMERG "read max_size invalid\n");
        return NULL;
    }

    read_size = vfs_read(fp, buf, max_size, &(fp->f_pos));
    if(1 > read_size)
    {
        return NULL;
    }

    while(buf[i++] != '\n' && i < read_size);
    buf[i-1] = '\0';
    fp->f_pos += i-read_size;
    return buf;
}


static int read_line(struct file *fp, char *buf1, int buf1_len, loff_t *point_pos)
{
        int i = 0;
        int read_size;
        printk(KERN_EMERG "read i=%d pos=%d fp-f_ops=%d--%d\n", i, (int)*point_pos, (int)fp->f_pos, __LINE__);
        read_size = vfs_read(fp, buf1, buf1_len, point_pos);
        if(read_size < 1)
        {
            printk(KERN_EMERG "read end.\n");
            return 0;
        }

        while(buf1[i++] != '\n' && i < read_size);

        if(i < read_size) {
            buf1[i] = '\0';
            //if(0 == strcmp("  dialer number *999# autodial", buf1))
            if(NULL != strstr(buf1, "dialer number *999# autodial"))
            {
                *point_pos = *point_pos - read_size;
                printk(KERN_EMERG "read i=%d pos=%d\n", i, (int)*point_pos);
                vfs_write(fp, "                            ", 28, point_pos);
            }
            *point_pos += i-read_size;
        }
        printk(KERN_EMERG "read i=%d pos=%d--%d\n", i, (int)*point_pos, __LINE__);

        return i;
}

int __init hello_init(void)
{
    char buf1[100];
    struct file *fp;
    loff_t pos;
    int read_size;
    int read_line = 10;
    printk(KERN_EMERG "hello enter\n");
#if 0
    fp = filp_open("/root/test_ko/12345.cfg", O_RDWR, 0);
    if (IS_ERR(fp)) {
        printk(KERN_EMERG "create file error\n");
        return -1;
    }
    fs = get_fs();
    set_fs(KERNEL_DS);
    pos = fp->f_pos;

    while(1)
    {
        memset(buf1, 0, sizeof(buf1));
        //read_size = vfs_read(fp, buf1, sizeof(buf1), &pos);
        //printk("read ret:%d, pos:%ld\n", read_size, pos);
        read_size = read_line(fp, buf1, sizeof(buf1), &pos);
        if(read_size < 1)
        {
            printk(KERN_EMERG "read end.\n");
           filp_close(fp, NULL);
           set_fs(fs);
           return 0;
        }

        printk(KERN_EMERG "%s", buf1);
    }

    filp_close(fp, NULL);
    set_fs(fs);
#endif
    fp = filp_open("/root/test_ko/xxx.txt", O_RDWR, 0);
    if (IS_ERR(fp)) {
        printk(KERN_EMERG "create file error\n");
        return -1;
    }
    fs = get_fs();
    set_fs(KERNEL_DS);
    while(read_line--)
    {
        memset(buf1, 0, sizeof(buf1));
        if ( NULL == kernel_fgets(buf1, 100, fp))
        {
           printk(KERN_EMERG "read end.\n");
           filp_close(fp, NULL);
        }
        printk(KERN_EMERG "%s", buf1);
     }
    filp_close(fp, NULL);
    set_fs(fs);
    return 0;
}
void __exit hello_exit(void)
{
    printk(KERN_EMERG "hello exit\n");
}

MODULE_LICENSE("GPL");

module_init(hello_init);
module_exit(hello_exit);

 

posted on 2022-05-28 15:38  红旗kernel  阅读(630)  评论(0编辑  收藏  举报

导航