当前位置: 技术问答>linux和unix
内核空间和用户空间通信
来源: 互联网 发布时间:2015-11-12
本文导语: 我编写了一个模块 在netfilter得钩子NF_IP_PRE_ROUTING上注册了一个函数 这个函数要读一个磁盘文件 也就是说问题是:在linux内核空间如何读取磁盘文件?文件得内容是一个16bits得数字 最好能给出具体得程序 因为网上...
我编写了一个模块 在netfilter得钩子NF_IP_PRE_ROUTING上注册了一个函数 这个函数要读一个磁盘文件 也就是说问题是:在linux内核空间如何读取磁盘文件?文件得内容是一个16bits得数字
最好能给出具体得程序 因为网上有很多关于内核与用户空间通信得 但是都很泛 针对性不强
比如 我觉得netlink好像并不适合我遇到得这种情况
这是我得想法 请高手指点
最好能给出具体得程序 因为网上有很多关于内核与用户空间通信得 但是都很泛 针对性不强
比如 我觉得netlink好像并不适合我遇到得这种情况
这是我得想法 请高手指点
|
我是在论坛上找到的,很好用的,希望对你有帮助
/*
file I/O in kernel module
by flyduck 2001/03/21
*/
#define __KERNEL__
#define MODULE
#include
#include
#include
#include
#include
#include
#include
#define EOF (-1)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
//
// Function Prototypes
//
struct file *klib_fopen(const char *filename, int flags, int mode);
void klib_fclose(struct file *filp);
int klib_fseek(struct file *filp, int offset, int whence);
int klib_fread(char *buf, int len, struct file *filp);
int klib_fgetc(struct file *filp);
char *klib_fgets(char *str, int size, struct file *filp);
int klib_fwrite(char *buf, int len, struct file *filp);
int klib_fputc(int ch, struct file *filp);
int klib_fputs(char *str, struct file *filp);
int klib_fprintf(struct file *filp, const char *fmt, ...);
//
// Library Functions
//
// 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 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 f_op->read(filp, cp, 1, &filp->f_pos)) 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);
}
//
// Test Functions
//
#define MAXLINELEN 1024
int init_module(void)
{
char str[MAXLINELEN];
struct file *filp;
int i, ch, line;
printk("# Loading klib_filen");
printk("# klib_file : open for readn");
if ((filp = klib_fopen("./fileio.c", O_RDONLY, 0)) == NULL) {
printk("Can't open filen");
return 1;
}
printk("# klib_file : fgetcn");
for (i = 0; ; ++i) {
ch = klib_fgetc(filp);
printk("%c", ch);
if (ch == 'n')
break;
}
printk("# klib_file : fgetsn");
klib_fseek(filp, 4450, SEEK_SET);
klib_fgets(str, MAXLINELEN, filp);
printk("%s", str);
printk("# klib_file : fgets #2n");
klib_fseek(filp, 0, SEEK_SET);
for (line = 0; klib_fgets(str, MAXLINELEN, filp) != NULL; ++line)
printk("%04d : %s", line, str);
klib_fclose(filp);
printk("# klib_file : open for writen");
if ((filp = klib_fopen("./tmpfile", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)) == NULL) {
printk("Can't open filen");
return 1;
}
printk("# klib_file : fputcn");
klib_fputc('*', filp);
klib_fputc('n', filp);
printk("# klib_file : fputsn");
klib_fputs("Hello, Worldn", filp);
printk("# klib_file : fprintfn");
klib_fprintf(filp, "Write %d, %d, %dn", 1, 2, 3);
klib_fclose(filp);
printk("Unloading klib_filen");
return 1;
}
void cleanup_module(void)
{
return;
}
/*
file I/O in kernel module
by flyduck 2001/03/21
*/
#define __KERNEL__
#define MODULE
#include
#include
#include
#include
#include
#include
#include
#define EOF (-1)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
//
// Function Prototypes
//
struct file *klib_fopen(const char *filename, int flags, int mode);
void klib_fclose(struct file *filp);
int klib_fseek(struct file *filp, int offset, int whence);
int klib_fread(char *buf, int len, struct file *filp);
int klib_fgetc(struct file *filp);
char *klib_fgets(char *str, int size, struct file *filp);
int klib_fwrite(char *buf, int len, struct file *filp);
int klib_fputc(int ch, struct file *filp);
int klib_fputs(char *str, struct file *filp);
int klib_fprintf(struct file *filp, const char *fmt, ...);
//
// Library Functions
//
// 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 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 f_op->read(filp, cp, 1, &filp->f_pos)) 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);
}
//
// Test Functions
//
#define MAXLINELEN 1024
int init_module(void)
{
char str[MAXLINELEN];
struct file *filp;
int i, ch, line;
printk("# Loading klib_filen");
printk("# klib_file : open for readn");
if ((filp = klib_fopen("./fileio.c", O_RDONLY, 0)) == NULL) {
printk("Can't open filen");
return 1;
}
printk("# klib_file : fgetcn");
for (i = 0; ; ++i) {
ch = klib_fgetc(filp);
printk("%c", ch);
if (ch == 'n')
break;
}
printk("# klib_file : fgetsn");
klib_fseek(filp, 4450, SEEK_SET);
klib_fgets(str, MAXLINELEN, filp);
printk("%s", str);
printk("# klib_file : fgets #2n");
klib_fseek(filp, 0, SEEK_SET);
for (line = 0; klib_fgets(str, MAXLINELEN, filp) != NULL; ++line)
printk("%04d : %s", line, str);
klib_fclose(filp);
printk("# klib_file : open for writen");
if ((filp = klib_fopen("./tmpfile", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)) == NULL) {
printk("Can't open filen");
return 1;
}
printk("# klib_file : fputcn");
klib_fputc('*', filp);
klib_fputc('n', filp);
printk("# klib_file : fputsn");
klib_fputs("Hello, Worldn", filp);
printk("# klib_file : fprintfn");
klib_fprintf(filp, "Write %d, %d, %dn", 1, 2, 3);
klib_fclose(filp);
printk("Unloading klib_filen");
return 1;
}
void cleanup_module(void)
{
return;
}