查看文章 |
linux内核空间访问文件系统代码实现[转载]
2011-05-23 15:26
linux内核空间访问文件系统代码实现 转载处: http://blog.csdn.net/gxfan/archive/2008/10/28/3168643.aspx 本文代码是从互联网收集而来,我记录下来主要为学习方便,版权归原作者所有。 以下代码实现了在linux内核空间打开、读、写文件等相关函数,有兴趣的可以研究一下并在此基础上扩展。 #include <linux/config.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/sched.h> #include <linux/file.h> #include <asm/processor.h> #include <asm/uaccess.h> /* 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); } |
最近读者:

