【问题标题】:Dereferencing pointer to incomplete type in Linux Module在 Linux 模块中取消引用指向不完整类型的指针
【发布时间】:2015-07-15 13:48:13
【问题描述】:

在 Linux 中编译模块时遇到编译错误“取消引用指向不完整类型的指针”。我创建了一个 inode_operations 表,我想将它分配给 proc_dir_entry 中的 proc_iops 指针。我搜索了告诉我使用 procfs API 的答案。使用 fs/proc/internal.h 是不可能的,因为它不在包含目录下。我知道不完整的类型,但我仍然无法在 init_module 中执行该分配。需要帮助。

在 Linux Kernel 3.16 GCC 4.8 版中使用 Debian 8

#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>

#define MESSAGE_LENGTH 80

#define PROC_ENTRY_FILENAME "sleep"

static char message[MESSAGE_LENGTH];

int already_open = 0;

static ssize_t module_output(struct file *file,
                 char *buf,
                 size_t len,
                 loff_t *offset)
{
    static int finished = 0;
    int i;
    char message[MESSAGE_LENGTH + 30];

    if (finished){
        finished = 0;
        return 0;
    }

    sprintf(message, "Last input: %s\n",message);

    for(i = 0;i < len && message[i]; i++)
        put_user(message[i], buf + i);

    finished = 1;
    return i;
}

static ssize_t module_input(struct file *file,
                const char *buf,
                size_t length,
                loff_t *offset)
{
    int i;

    for (i = 0; i < MESSAGE_LENGTH - 1 && i < length; i++)
        get_user(message[i], buf + i);

    message[i] = '\0';

    return i;
}

DECLARE_WAIT_QUEUE_HEAD(WaitQ);

static int module_open(struct inode *inode, struct file *file)
{
    int i;
    int is_sig = 0;

    if ((file->f_flags & O_NONBLOCK) && already_open )
        return -EAGAIN;

    try_module_get(THIS_MODULE);

    while(already_open){

        wait_event_interruptible(WaitQ, !already_open);

        for(i = 0; i < _NSIG_WORDS && !is_sig; i++)
            is_sig = current->pending.signal.sig[i] &
                 ~current->blocked.sig[i];

        if (is_sig){
            module_put(THIS_MODULE);
            return -EINTR;
        }   
    }

    already_open = 1;

    return 0;       
}

int module_close(struct inode *inode, struct file *file)
{
    already_open = 0;

    wake_up(&WaitQ);

    module_put(THIS_MODULE);

    return 0;
}

static int module_permission(struct inode *inode, int op)
{
    // Documentation/security/credentials.txt
    if (op==4 || (op == 2 && current_euid().val == 0))
        return 0;

    return -EACCES;
}

static struct file_operations fops = {
    .read = module_output,
    .write = module_input,
    .open = module_open,
    .release = module_close
};

static struct inode_operations iops = {
    .permission = module_permission
};

int init_module(void)
{
    struct proc_dir_entry *our_proc_file;

    our_proc_file = proc_create(PROC_ENTRY_FILENAME, 0, NULL, &fops);

    if( our_proc_file == NULL )
    {
        printk(KERN_ALERT "Error: Could not initialize /proc/sleep\n"); 
        return -ENOMEM;
    }

    // Line causing the error
    our_proc_file->proc_iops = &iops;

    printk(KERN_INFO "/proc/sleep file created.\n");

    return 0;
}

void cleanup_module(void)
{
    remove_proc_entry(PROC_ENTRY_FILENAME, NULL);
    printk(KERN_INFO "/proc/sleep file removed.");
}

【问题讨论】:

  • 哪一行给出了错误?
  • 在init_module中,我在上面放了一条注释
  • 我不太确定我是否正确理解了您的要求,但我已经添加了一个答案。检查一下,如果这符合您的要求,请告诉我。
  • 告诉我一件事,您是否安装了所需的开发模块?请参阅我的更新答案。
  • 我正在使用 make 编译,指定自定义路径是否有意义,因为我从 linux 安装了所有头文件。

标签: c linux pointers


【解决方案1】:

struct proc_dir_entry 的定义可在fs/proc/internal.h 文件中找到。您必须包含它才能将定义放入源文件中。

无法使用 fs/proc/internal.h,因为它不在包含目录下。

在编译时,您可以使用带有gcc-I 选项提供您将要使用的包含文件的(自定义)路径。

注意:我假设您已安装 kernel-headerfileskernel-devel

【讨论】:

  • 该文件不再在 Linux 的包含目录中
  • 那我们能做什么呢?
猜你喜欢
  • 2021-06-30
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多