i was trying to understand how created is socket but i have ran into the problem which i really dont understand. This problem is the code below:
static inline struct socket *SOCKET_I(struct inode *inode)
{
return &container_of(inode, struct socket_alloc, vfs_inode)->socket; //why here is -> socket
}
I see it's the container_of
macro and it returns a pointer. It takes inode
pointer as a parameter and subtracts amount of vfs_inode
bytes.
my question is : Why there is something like ->socket
at the end of the macro and what does it do?
inode
is the vfs_inode
member of a socket_alloc
structure. container_of
expands to the structure that contains that member.
The structure also contains a socket
member, and this function returns the value of that member.
In other words, there's a structure like
struct socket_alloc {
// ... some members
struct inode vfs_inode;
// ... other members
struct socket socket
// ... more members
} some_variable;
If you do:
struct inode *i = &(some_variable.vfs_inode);
then you can later do
struct socket *this_sock = SOCKET_I(i);
to get a pointer to the corresponding socket
.
Code which helps me to understand it more in kernel linux there is function like sock_alloc_inode which return &ei->vfs_inode nad i think linux kernel scenario with container of macro in socket.c may looks like that. Im not sure if its right but looks well.
#include <stdio.h>
#include <stdlib.h>
#define offsetof(type, member) ((size_t) &((type *)0)->member)
#define container_of(ptr, type, member) ({ \
const typeof ( ((type *)0)->member ) *__mptr = (ptr); \
(type *) ( (char *)__mptr - offsetof(type, member) ); })
struct inode{
int a;
int b;
};
struct socket{
int some_other_data;
int this_data;
};
struct socket_alloc{
struct socket socket ;
struct inode vfs_inode;
};
static inline struct socket *SOCKET_I(struct inode *inode)
{
return &container_of(inode, struct socket_alloc, vfs_inode)->socket;
}
static inline struct inode *SOCK_INODE(struct socket *socket)
{
return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
}
int main()
{
struct inode *inode;
struct socket* socket;
struct socket_alloc *ei;
ei = (struct socket_alloc*)malloc(sizeof(*ei));
inode = (struct inode*)malloc(sizeof(*inode));
socket = (struct socket*)malloc(sizeof(*socket));
printf("INODE POINTER NO MACRO AND WITHOUT REFER TO THE SOCKET_ALLOC STRUCT %d\n", *inode);
inode= &ei->vfs_inode;
printf("INODE POINTER NO MACRO %d\n", *inode);
printf("SOCKET POINTER NO MACRO%d\n", *socket);
socket = SOCKET_I(inode);
inode = SOCK_INODE(socket);
printf("INODE POINTER USING MACRO %d\n", *inode);
printf("SOCKET POINTER USING MACRO %d\n", *socket);
free(ei);
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.