Issue
Many Kernel modules seem to opt for the following struct initialization style;
struct file_operations sample_fops = {
.owner = THIS_MODULE,
.read = sample_read,
.write = sample_write,
.ioctl = sample_ioctl,
.open = sample_open,
.release = sample_release,
};
I can wrap my head around when this style is used for primitives and pointer data types but I can't figure out how they work so seamlessly for functions.
When and where are the parameters for this type of initialization created? Is it in the scope of the file or in the scope where the struct is utilized. Can you access the parameters (for instance a pointer to buffer passed as an argument to the write function) or do you have to initialize the struct in a different style in order to be able to do that?
Furthermore, if sample_fops
is called multiple times, is it the same struct throughout the file? And where is it kept in the memory during its lifetime? Are the parameters kept in the same place too?
Solution
I have not exactly understood your question but this is
struct file_operations sample_fops = {
.owner = THIS_MODULE,
.read = sample_read,
.write = sample_write,
.ioctl = sample_ioctl,
.open = sample_open,
.release = sample_release,
};
a declaration of the object sample_fops
that has the type struct file_operations
.
It seems that the data members of the structure are declared as pointers to functions and in this declaration function designators as for example sample_open
are used to initializa corresponding data members of the structure.
Here is a demonstrative program.
#include <stdio.h>
void f( void )
{
puts( "Hello Yusuf Gürkan Bor" );
}
struct A
{
void ( *hello )( void );
};
int main( void )
{
struct A a = { .hello = f };
a.hello();
}
The program output is
Hello Yusuf Gürkan Bor
This record in the initializarion .fp = f
is called a designation initialization.
It uses the name of a data member of a structure that is initialized.
In fact you can equivalently to write
struct A a = { f };
But for a such an initialization you have to keep the order of initializers relative to the order of data members.
Here is another example when a function accepts an argument.
#include <stdio.h>
void f( const char *name )
{
printf( "Hello %s\n", name );
}
struct A
{
void ( *hello )( const char * );
};
int main( void )
{
struct A a = { .hello = f };
a.hello( "Yusuf Gürkan Bor" );
}
Its output is the same as shown above.
Answered By - Vlad from Moscow Answer Checked By - Cary Denson (WPSolving Admin)