Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4450756
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: LINUX

2011-05-26 00:05:16

linux内核空间访问文件系统代码实现

转载处: http://blog.csdn.net/gxfan/archive/2008/10/28/3168643.aspx

本文代码是从互联网收集而来,我记录下来主要为学习方便,版权归原作者所有。
以下代码实现了在linux内核空间打开、读、写文件等相关函数,有兴趣的可以研究一下并在此基础上扩展。
 
#include  
#include  
#include  
#include  
#include  
#include  
#include
 
/* 
  file I/O in kernel module 
*/ 
#define EOF (-1) 
#define SEEK_SET 0 
#define SEEK_CUR 1 
#define SEEK_END 2 
 
// Context : User 
// Parameter : 
// filename : filename to open 
// flags : 
// O_RDONLY, O_WRONLY, O_RDWR 
// O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_NONBLOCK, O_SYNC, ... 
// mode : file creation permission. 
// S_IRxxx S_IWxxx S_IXxxx (xxx = USR, GRP, OTH), S_IRWXx (x = U, G, O) 
// Return : 
// file pointer. if error, return NULL 
 
struct file *klib_fopen(const char *filename, int flags, int mode) 
 
    struct file *filp = filp_open(filename, flags, mode); 
 
    return (IS_ERR(filp)) ? NULL : filp; 
} 
 
// Context : User 
// Parameter : 
// filp : file pointer 
// Return : 
void klib_fclose(struct file *filp) 
{ 
    if (filp) 
        fput(filp); 
} 
 
// Context : User 
// Parameter : 
// filp : file pointer 
// offset : 
// whence : SEEK_SET, SEEK_CUR 
// Comment : 
// do not support SEEK_END 
// no boundary check (file position may exceed file size) 
int klib_fseek(struct file *filp, int offset, int whence) 
{ 
 
    int pos = filp->f_pos; 
 
    if (filp) { 
 
        if (whence == SEEK_SET) 
            pos = offset; 
        else if (whence == SEEK_CUR) 
            pos = offset; 
 
        if (pos < 0) 
            pos = 0; 
 
        return (filp->f_pos = pos); 
    } else 
        return -ENOENT; 
 
} 
 
// Context : User 
// Parameter : 
// buf : buffer to read into 
// len : number of bytes to read 
// filp : file pointer 
// Return : 
// actually read number. 0 = EOF, negative = error 
int klib_fread(char *buf, int len, struct file *filp) 
{ 
    int readlen; 
 
    mm_segment_t oldfs; 
 
    if (filp == NULL) 
        return -ENOENT; 
 
    if (filp->f_op->read == NULL) 
        return -ENOSYS; 
 
    if (((filp->f_flags & O_ACCMODE) & O_RDONLY) != 0) 
        return -EACCES; 
 
    oldfs = get_fs(); 
    set_fs(KERNEL_DS); 
 
    readlen = filp->f_op->read(filp, buf, len, &filp->f_pos); 
 
    set_fs(oldfs); 
 
    return readlen; 
} 
 
// Context : User 
// Parameter : 
// filp : file pointer 
// Return : 
// read character, EOF if end of file 
 
int klib_fgetc(struct file *filp) 
{ 
 
    int len; 
    unsigned char buf[4]; 
 
    len = klib_fread((char *)buf, 1, filp); 
 
    if (len > 0) 
        return buf[0]; 
    else if (len == 0) 
        return EOF; 
    else 
        return len; 
} 
 
// Context : User 
// Parameter : 
// str : string 
// size : size of str buffer 
// filp : file pointer 
// Return : 
// read string. NULL if end of file 
// Comment : 
// Always append trailing null character 
 
char *klib_fgets(char *str, int size, struct file *filp) 
{ 
 
    char *cp; 
    int len, readlen; 
    mm_segment_t oldfs; 
 
    if (filp && filp->f_op->read 
        && ((filp->f_flags & O_ACCMODE) & O_WRONLY) == 0) { 
        oldfs = get_fs(); 
        set_fs(KERNEL_DS); 
 
        for (cp = str, len = -1, readlen = 0; readlen < size - 1; 
             cp, readlen) { 
 
            if ((len = 
                 filp->f_op->read(filp, cp, 1, &filp->f_pos)) <= 0) 
                break; 
 
            if (*cp == '\n') { 
                cp; 
                readlen; 
                break; 
 
            } 
        } 
 
        *cp = 0; 
        set_fs(oldfs); 
 
        return (len < 0 || readlen == 0) ? NULL : str; 
    } else 
        return NULL; 
 
} 
 
// Context : User 
// Parameter : 
// buf : buffer containing data to write 
// len : number of bytes to write 
// filp : file pointer 
// Return : 
// actually written number. 0 = retry, negative = error 
 
int klib_fwrite(char *buf, int len, struct file *filp) 
{ 
    int writelen; 
    mm_segment_t oldfs; 
 
    if (filp == NULL) 
        return -ENOENT; 
 
    if (filp->f_op->write == NULL) 
        return -ENOSYS; 
 
    if (((filp->f_flags & O_ACCMODE) & (O_WRONLY | O_RDWR)) == 0) 
        return -EACCES; 
 
    oldfs = get_fs(); 
    set_fs(KERNEL_DS); 
    writelen = filp->f_op->write(filp, buf, len, &filp->f_pos); 
    set_fs(oldfs); 
 
    return writelen; 
} 
 
// Context : User 
// Parameter : 
// filp : file pointer 
// Return : 
// written character, EOF if error 
int klib_fputc(int ch, struct file *filp) 
{ 
    int len; 
    unsigned char buf[4]; 
 
    buf[0] = (unsigned char)ch; 
    len = klib_fwrite(buf, 1, filp); 
 
    if (len > 0) 
        return buf[0]; 
    else 
        return EOF; 
} 
 
// Context : User 
// Parameter : 
// str : string 
// filp : file pointer 
// Return : 
// count of written characters. 0 = retry, negative = error 
int klib_fputs(char *str, struct file *filp) 
{ 
    return klib_fwrite(str, strlen(str), filp); 
} 
 
// Context : User 
// Parameter : 
// filp : file pointer 
// fmt : printf() style formatting string 
// Return : 
// same as klib_fputs() 
int klib_fprintf(struct file *filp, const char *fmt, ...) 
{ 
    static char s_buf[1024]; 
 
    va_list args; 
    va_start(args, fmt); 
    vsprintf(s_buf, fmt, args); 
    va_end(args); 
    return klib_fputs(s_buf, filp); 
}
阅读(986) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~