Linux 内核里有一类常见的操作:遍历由 list_head 串起来的结构体链表。list_for_each_entry 就是干这个事儿的。它藏在 include/linux/list.h,是一个宏,展开后是一个 for 循环。
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
&pos->member != (head); \
pos = list_next_entry(pos, member))
参数很直观:pos 是循环游标,类型和你链表的节点类型一致;head 是链表头指针;member 是节点结构体里嵌的那个 list_head 字段的名字。用法上,只要你有一个以 LIST_HEAD(my_list) 定义的链表头,并且通过 list_add_tail 把节点加进去,就可以写:
struct my_struct {
int data;
struct list_head node;
};
struct my_struct *p;
list_for_each_entry(p, &my_list, node) {
// 在这里访问 p->data
}
实际内核代码里到处是这个模式。比如 input 子系统遍历 handler 链表:
struct input_handler {
void *private;
...
const char *name;
const struct input_device_id *id_table;
struct list_head h_list;
struct list_head node;
};
;
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);

