Reputation: 111
I encountered a compilation error "dereferencing pointer to incomplete type" while compiling a module in Linux. I have created an inode_operations table which I want to assign to proc_iops pointer in proc_dir_entry. I searched for the answers telling me to use procfs APIs. Using fs/proc/internal.h is not possible as it is not under include directory. I know about incomplete types but I am still not able to perform that assignment in init_module. Help needed.
Using Debian 8 with Linux Kernel 3.16 GCC Version 4.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.");
}
Upvotes: 0
Views: 2741
Reputation: 134286
The definition of struct proc_dir_entry
is available in fs/proc/internal.h
file. You have to include it to get the definition into your source file.
Using fs/proc/internal.h is not possible as it is not under include directory.
In compilation time, you can provide the (custom) path to the include files you'll be using using -I
option with gcc
.
NOTE: I assume you have kernel-headerfiles
and kernel-devel
installed.
Upvotes: 0