M.S Chaudhari M.S Chaudhari - 2 months ago 20
Linux Question

Building the Linux /proc file driver with seq_file

Why do I get the following error messages when building the Linux

/proc
file driver with
seq_file
?

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

#define PROC_NAME "iter"

MODULE_AUTHOR("MS Chaudhari");
MODULE_LICENSE("GPL");

/*
This function is called at the beginning of a sequence.
ie, when:
- the /proc file is read (first time)
- after the function stop (end of sequence)
*/
static void *my_seq_start(struct seq_file *s, loff_t *pos)
{
static unsigned long counter = 0;

// beginning a new sequence
if (*pos == 0)
{
return &counter;
}
else
{
*pos = 0;
return NULL;
}
}

/*
This function is called after the beginning of a sequence.
It's called untill the return is NULL (this ends the sequence).
*/
static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
unsigned long *tmp_v = (unsigned long *)v;
(*tmp_v)++;
(*pos)++;
return NULL;
}

/*
This function is called for each "step" of a sequence
*/

static int my_seq_show(struct seq_file *s, void *v)
{
loff_t *spos = (loff_t *)v;

seq_printf(s, "%Ld\n", *spos);
return 0;
}

/*
This structure gather "function" to manage the sequnce
*/

static struct seq_operation my_seq_ops =
{
.start = my_seq_start,
.next = my_seq_next,
.stop = my_seq_stop,
.show = my_seq_show
};

/*
This function is called when the /proc file is open.
*/
static int my_open(struct inode *inode, struct file *file)
{
return seq_open(file, &my_seq_ops);
}

/*
This structure gather "function" that manage the /proc file
*/
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = my_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
};


/*
This function is called when the module is loaded
*/
int init_module(void)
{
struct proc_dir_entry *entry;

entry = proc_create(PROC_NAME, 0, NULL, &fops);

// entry = create_entry(PROC_NAME, 0, NULL);
if (entry)
{
entry->proc_fops = &my_file_ops;
}

return 0;
}

/*
This function is called when the module is unloaded.
*/
void cleanup_module(void)
{
remove_proc_entry(PROC_NAME, NULL);
}


And when i compile using
make
command, I got following errors.

/home/radix/programing/DD/procSeq.c:61:15: error: variable ‘my_seq_ops’ has initializer but incomplete type
static struct seq_operation my_seq_ops =
^
/home/radix/programing/DD/procSeq.c:63:2: error: unknown field ‘start’ specified in initializer
.start = my_seq_start,
^
/home/radix/programing/DD/procSeq.c:63:2: warning: excess elements in struct initializer [enabled by default]
/home/radix/programing/DD/procSeq.c:63:2: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c:64:2: error: unknown field ‘next’ specified in initializer
.next = my_seq_next,
^
/home/radix/programing/DD/procSeq.c:64:2: warning: excess elements in struct initializer [enabled by default]
/home/radix/programing/DD/procSeq.c:64:2: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c:65:2: error: unknown field ‘stop’ specified in initializer
.stop = my_seq_stop,
^
/home/radix/programing/DD/procSeq.c:65:10: error: ‘my_seq_stop’ undeclared here (not in a function)
.stop = my_seq_stop,
^
/home/radix/programing/DD/procSeq.c:65:2: warning: excess elements in struct initializer [enabled by default]
.stop = my_seq_stop,
^
/home/radix/programing/DD/procSeq.c:65:2: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c:66:2: error: unknown field ‘show’ specified in initializer
.show = my_seq_show
^
/home/radix/programing/DD/procSeq.c:67:1: warning: excess elements in struct initializer [enabled by default]
};
^
/home/radix/programing/DD/procSeq.c:67:1: warning: (near initialization for ‘my_seq_ops’) [enabled by default]
/home/radix/programing/DD/procSeq.c: In function ‘my_open’:
/home/radix/programing/DD/procSeq.c:74:2: warning: passing argument 2 of ‘seq_open’ from incompatible pointer type [enabled by default]
return seq_open(file, &my_seq_ops);
^
In file included from /home/radix/programing/DD/procSeq.c:4:0:
include/linux/seq_file.h:98:5: note: expected ‘const struct seq_operations *’ but argument is of type ‘struct seq_operation *’
int seq_open(struct file *, const struct seq_operations *);
^
/home/radix/programing/DD/procSeq.c: In function ‘init_module’:
/home/radix/programing/DD/procSeq.c:102:8: error: dereferencing pointer to incomplete type
entry->proc_fops = &my_file_ops;
^
/home/radix/programing/DD/procSeq.c:102:23: error: ‘my_file_ops’ undeclared (first use in this function)
entry->proc_fops = &my_file_ops;
^
/home/radix/programing/DD/procSeq.c:102:23: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [/home/radix/programing/DD/procSeq.o] Error 1
make[1]: *** [_module_/home/radix/programing/DD] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.13.0-24-generic'
make: *** [all] Error 2


Sorry for my code is long.

Answer

It's because there is no struct seq_operation but struct seq_operations

Comments