当前位置: 首页 > news >正文

400套商业网站的静态模板网站安全风险评估报告

400套商业网站的静态模板,网站安全风险评估报告,找网站公司做网站用了织梦可以吗,网站动态添加广告怎么做的一、前言 linux内核链表在include/linux/list.h文件中#xff0c;内核中实现的链表比较简洁#xff0c;实用性很强#xff0c;因此想把它单独移植出来使用。 内核中的代码只能使用gnuc编译器编译#xff0c;stdc编译器编译是会报错的#xff0c;主要是因为typeof这个宏是…一、前言 linux内核链表在include/linux/list.h文件中内核中实现的链表比较简洁实用性很强因此想把它单独移植出来使用。 内核中的代码只能使用gnuc编译器编译stdc编译器编译是会报错的主要是因为typeof这个宏是gnuc特有的扩展stdc中没有此扩展。 本篇文章就是来解决这个问题的移植得到一个在stdc下运行的list方便其他平台使用。 二、移植过程 1、将include/linux/list.h单独扣出来保存为list.h文件。 2、修改头文件并添加list_head的定义还有部分宏定义以下为添加部分 #include stdbool.h #include stddef.hstruct list_head {struct list_head *next, *prev; };struct hlist_head {struct hlist_node *first; };struct hlist_node {struct hlist_node *next, **pprev; };#define WRITE_ONCE(var, val) ((var) (val)) #define READ_ONCE(var) (var)/* container_of */ #ifndef offsetof #define offsetof(type, member) (size_t)(((type*)0)-member) #endif #define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))修改并添加了以下宏改完后可以在stdc下编译 1、WRITE_ONCE和READ_ONCE。2、container_of去除了typeof的使用。 3、删除所有使用typeof的定义将以下所有使用到typeof的代码删除 /*** list_next_entry - get the next element in list* pos: the type * to cursor* member: the name of the list_head within the struct.*/ #define list_next_entry(pos, member) \list_entry((pos)-member.next, typeof(*(pos)), member)/*** list_prev_entry - get the prev element in list* pos: the type * to cursor* member: the name of the list_head within the struct.*/ #define list_prev_entry(pos, member) \list_entry((pos)-member.prev, typeof(*(pos)), member)/*** 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_head 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))/*** list_for_each_entry_reverse - iterate backwards 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_head within the struct.*/ #define list_for_each_entry_reverse(pos, head, member) \for (pos list_last_entry(head, typeof(*pos), member); \pos-member ! (head); \pos list_prev_entry(pos, member))/*** list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()* pos: the type * to use as a start point* head: the head of the list* member: the name of the list_head within the struct.** Prepares a pos entry for use as a start point in list_for_each_entry_continue().*/ #define list_prepare_entry(pos, head, member) \((pos) ? : list_entry(head, typeof(*pos), member))/*** list_for_each_entry_safe - iterate over list of given type safe against removal of list entry* pos: the type * to use as a loop cursor.* n: another type * to use as temporary storage* head: the head for your list.* member: the name of the list_head within the struct.*/ #define list_for_each_entry_safe(pos, n, head, member) \for (pos list_first_entry(head, typeof(*pos), member), \n list_next_entry(pos, member); \pos-member ! (head); \pos n, n list_next_entry(n, member))/*** list_for_each_entry_safe_reverse - iterate backwards over list safe against removal* pos: the type * to use as a loop cursor.* n: another type * to use as temporary storage* head: the head for your list.* member: the name of the list_head within the struct.** Iterate backwards over list of given type, safe against removal* of list entry.*/ #define list_for_each_entry_safe_reverse(pos, n, head, member) \for (pos list_last_entry(head, typeof(*pos), member), \n list_prev_entry(pos, member); \pos-member ! (head); \pos n, n list_prev_entry(n, member))#define hlist_entry_safe(ptr, type, member) \({ typeof(ptr) ____ptr (ptr); \____ptr ? hlist_entry(____ptr, type, member) : NULL; \})/*** hlist_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 hlist_node within the struct.*/ #define hlist_for_each_entry(pos, head, member) \for (pos hlist_entry_safe((head)-first, typeof(*(pos)), member);\pos; \pos hlist_entry_safe((pos)-member.next, typeof(*(pos)), member))/*** hlist_for_each_entry_continue - iterate over a hlist continuing after current point* pos: the type * to use as a loop cursor.* member: the name of the hlist_node within the struct.*/ #define hlist_for_each_entry_continue(pos, member) \for (pos hlist_entry_safe((pos)-member.next, typeof(*(pos)), member);\pos; \pos hlist_entry_safe((pos)-member.next, typeof(*(pos)), member))/*** hlist_for_each_entry_from - iterate over a hlist continuing from current point* pos: the type * to use as a loop cursor.* member: the name of the hlist_node within the struct.*/ #define hlist_for_each_entry_from(pos, member) \for (; pos; \pos hlist_entry_safe((pos)-member.next, typeof(*(pos)), member))/*** hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry* pos: the type * to use as a loop cursor.* n: another struct hlist_node to use as temporary storage* head: the head for your list.* member: the name of the hlist_node within the struct.*/ #define hlist_for_each_entry_safe(pos, n, head, member) \for (pos hlist_entry_safe((head)-first, typeof(*pos), member);\pos ({ n pos-member.next; 1; }); \pos hlist_entry_safe(n, typeof(*pos), member))至此移植完成。 三、移植好的list.h文件 /* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_LIST_H #define _LINUX_LIST_H#include stdbool.h #include stddef.hstruct list_head {struct list_head *next, *prev; };struct hlist_head {struct hlist_node *first; };struct hlist_node {struct hlist_node *next, **pprev; };#define WRITE_ONCE(var, val) ((var) (val)) #define READ_ONCE(var) (var)/* container_of */ #ifndef offsetof #define offsetof(type, member) (size_t)(((type*)0)-member) #endif #define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))/** Circular doubly linked list implementation.** Some of the internal functions (__xxx) are useful when* manipulating whole lists rather than single entries, as* sometimes we already know the next/prev entries and we can* generate better code by using them directly rather than* using the generic single-entry routines.*/#define LIST_HEAD_INIT(name) { (name), (name) }#define LIST_HEAD(name) \struct list_head name LIST_HEAD_INIT(name)/*** INIT_LIST_HEAD - Initialize a list_head structure* list: list_head structure to be initialized.** Initializes the list_head to point to itself. If it is a list header,* the result is an empty list.*/ static inline void INIT_LIST_HEAD(struct list_head *list) {WRITE_ONCE(list-next, list);list-prev list; }static inline bool __list_add_valid(struct list_head *new,struct list_head *prev,struct list_head *next) {return true; } static inline bool __list_del_entry_valid(struct list_head *entry) {return true; }/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/ static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next) {if (!__list_add_valid(new, prev, next))return;next-prev new;new-next next;new-prev prev;WRITE_ONCE(prev-next, new); }/*** list_add - add a new entry* new: new entry to be added* head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/ static inline void list_add(struct list_head *new, struct list_head *head) {__list_add(new, head, head-next); }/*** list_add_tail - add a new entry* new: new entry to be added* head: list head to add it before** Insert a new entry before the specified head.* This is useful for implementing queues.*/ static inline void list_add_tail(struct list_head *new, struct list_head *head) {__list_add(new, head-prev, head); }/** Delete a list entry by making the prev/next entries* point to each other.** This is only for internal list manipulation where we know* the prev/next entries already!*/ static inline void __list_del(struct list_head * prev, struct list_head * next) {next-prev prev;WRITE_ONCE(prev-next, next); }/** Delete a list entry and clear the prev pointer.** This is a special-purpose list clearing method used in the networking code* for lists allocated as per-cpu, where we dont want to incur the extra* WRITE_ONCE() overhead of a regular list_del_init(). The code that uses this* needs to check the node prev pointer instead of calling list_empty().*/ static inline void __list_del_clearprev(struct list_head *entry) {__list_del(entry-prev, entry-next);entry-prev NULL; }static inline void __list_del_entry(struct list_head *entry) {if (!__list_del_entry_valid(entry))return;__list_del(entry-prev, entry-next); }/*** list_del - deletes entry from list.* entry: the element to delete from the list.* Note: list_empty() on entry does not return true after this, the entry is* in an undefined state.*/ static inline void list_del(struct list_head *entry) {__list_del_entry(entry);entry-next NULL;entry-prev NULL; }/*** list_replace - replace old entry by new one* old : the element to be replaced* new : the new element to insert** If old was empty, it will be overwritten.*/ static inline void list_replace(struct list_head *old,struct list_head *new) {new-next old-next;new-next-prev new;new-prev old-prev;new-prev-next new; }/*** list_replace_init - replace old entry by new one and initialize the old one* old : the element to be replaced* new : the new element to insert** If old was empty, it will be overwritten.*/ static inline void list_replace_init(struct list_head *old,struct list_head *new) {list_replace(old, new);INIT_LIST_HEAD(old); }/*** list_swap - replace entry1 with entry2 and re-add entry1 at entry2s position* entry1: the location to place entry2* entry2: the location to place entry1*/ static inline void list_swap(struct list_head *entry1,struct list_head *entry2) {struct list_head *pos entry2-prev;list_del(entry2);list_replace(entry1, entry2);if (pos entry1)pos entry2;list_add(entry1, pos); }/*** list_del_init - deletes entry from list and reinitialize it.* entry: the element to delete from the list.*/ static inline void list_del_init(struct list_head *entry) {__list_del_entry(entry);INIT_LIST_HEAD(entry); }/*** list_move - delete from one list and add as anothers head* list: the entry to move* head: the head that will precede our entry*/ static inline void list_move(struct list_head *list, struct list_head *head) {__list_del_entry(list);list_add(list, head); }/*** list_move_tail - delete from one list and add as anothers tail* list: the entry to move* head: the head that will follow our entry*/ static inline void list_move_tail(struct list_head *list,struct list_head *head) {__list_del_entry(list);list_add_tail(list, head); }/*** list_bulk_move_tail - move a subsection of a list to its tail* head: the head that will follow our entry* first: first entry to move* last: last entry to move, can be the same as first** Move all entries between first and including last before head.* All three entries must belong to the same linked list.*/ static inline void list_bulk_move_tail(struct list_head *head,struct list_head *first,struct list_head *last) {first-prev-next last-next;last-next-prev first-prev;head-prev-next first;first-prev head-prev;last-next head;head-prev last; }/*** list_is_first -- tests whether list is the first entry in list head* list: the entry to test* head: the head of the list*/ static inline int list_is_first(const struct list_head *list, const struct list_head *head) {return list-prev head; }/*** list_is_last - tests whether list is the last entry in list head* list: the entry to test* head: the head of the list*/ static inline int list_is_last(const struct list_head *list, const struct list_head *head) {return list-next head; }/*** list_is_head - tests whether list is the list head* list: the entry to test* head: the head of the list*/ static inline int list_is_head(const struct list_head *list, const struct list_head *head) {return list head; }/*** list_empty - tests whether a list is empty* head: the list to test.*/ static inline int list_empty(const struct list_head *head) {return READ_ONCE(head-next) head; }/*** list_del_init_careful - deletes entry from list and reinitialize it.* entry: the element to delete from the list.** This is the same as list_del_init(), except designed to be used* together with list_empty_careful() in a way to guarantee ordering* of other memory operations.** Any memory operations done before a list_del_init_careful() are* guaranteed to be visible after a list_empty_careful() test.*/ static inline void list_del_init_careful(struct list_head *entry) {__list_del_entry(entry);entry-prev entry;WRITE_ONCE(entry-next, entry); }/*** list_empty_careful - tests whether a list is empty and not being modified* head: the list to test** Description:* tests whether a list is empty _and_ checks that no other CPU might be* in the process of modifying either member (next or prev)** NOTE: using list_empty_careful() without synchronization* can only be safe if the only activity that can happen* to the list entry is list_del_init(). Eg. it cannot be used* if another CPU could re-list_add() it.*/ static inline int list_empty_careful(const struct list_head *head) {struct list_head *next READ_ONCE(head-next);return list_is_head(next, head) (next head-prev); }/*** list_rotate_left - rotate the list to the left* head: the head of the list*/ static inline void list_rotate_left(struct list_head *head) {struct list_head *first;if (!list_empty(head)) {first head-next;list_move_tail(first, head);} }/*** list_rotate_to_front() - Rotate list to specific item.* list: The desired new front of the list.* head: The head of the list.** Rotates list so that list becomes the new front of the list.*/ static inline void list_rotate_to_front(struct list_head *list,struct list_head *head) {/** Deletes the list head from the list denoted by head and* places it as the tail of list, this effectively rotates the* list so that list is at the front.*/list_move_tail(head, list); }/*** list_is_singular - tests whether a list has just one entry.* head: the list to test.*/ static inline int list_is_singular(const struct list_head *head) {return !list_empty(head) (head-next head-prev); }static inline void __list_cut_position(struct list_head *list,struct list_head *head, struct list_head *entry) {struct list_head *new_first entry-next;list-next head-next;list-next-prev list;list-prev entry;entry-next list;head-next new_first;new_first-prev head; }/*** list_cut_position - cut a list into two* list: a new list to add all removed entries* head: a list with entries* entry: an entry within head, could be the head itself* and if so we wont cut the list** This helper moves the initial part of head, up to and* including entry, from head to list. You should* pass on entry an element you know is on head. list* should be an empty list or a list you do not care about* losing its data.**/ static inline void list_cut_position(struct list_head *list,struct list_head *head, struct list_head *entry) {if (list_empty(head))return;if (list_is_singular(head) !list_is_head(entry, head) (entry ! head-next))return;if (list_is_head(entry, head))INIT_LIST_HEAD(list);else__list_cut_position(list, head, entry); }/*** list_cut_before - cut a list into two, before given entry* list: a new list to add all removed entries* head: a list with entries* entry: an entry within head, could be the head itself** This helper moves the initial part of head, up to but* excluding entry, from head to list. You should pass* in entry an element you know is on head. list should* be an empty list or a list you do not care about losing* its data.* If entry head, all entries on head are moved to* list.*/ static inline void list_cut_before(struct list_head *list,struct list_head *head,struct list_head *entry) {if (head-next entry) {INIT_LIST_HEAD(list);return;}list-next head-next;list-next-prev list;list-prev entry-prev;list-prev-next list;head-next entry;entry-prev head; }static inline void __list_splice(const struct list_head *list,struct list_head *prev,struct list_head *next) {struct list_head *first list-next;struct list_head *last list-prev;first-prev prev;prev-next first;last-next next;next-prev last; }/*** list_splice - join two lists, this is designed for stacks* list: the new list to add.* head: the place to add it in the first list.*/ static inline void list_splice(const struct list_head *list,struct list_head *head) {if (!list_empty(list))__list_splice(list, head, head-next); }/*** list_splice_tail - join two lists, each list being a queue* list: the new list to add.* head: the place to add it in the first list.*/ static inline void list_splice_tail(struct list_head *list,struct list_head *head) {if (!list_empty(list))__list_splice(list, head-prev, head); }/*** list_splice_init - join two lists and reinitialise the emptied list.* list: the new list to add.* head: the place to add it in the first list.** The list at list is reinitialised*/ static inline void list_splice_init(struct list_head *list,struct list_head *head) {if (!list_empty(list)) {__list_splice(list, head, head-next);INIT_LIST_HEAD(list);} }/*** list_splice_tail_init - join two lists and reinitialise the emptied list* list: the new list to add.* head: the place to add it in the first list.** Each of the lists is a queue.* The list at list is reinitialised*/ static inline void list_splice_tail_init(struct list_head *list,struct list_head *head) {if (!list_empty(list)) {__list_splice(list, head-prev, head);INIT_LIST_HEAD(list);} }/*** list_entry - get the struct for this entry* ptr: the struct list_head pointer.* type: the type of the struct this is embedded in.* member: the name of the list_head within the struct.*/ #define list_entry(ptr, type, member) \container_of(ptr, type, member)/*** list_first_entry - get the first element from a list* ptr: the list head to take the element from.* type: the type of the struct this is embedded in.* member: the name of the list_head within the struct.** Note, that list is expected to be not empty.*/ #define list_first_entry(ptr, type, member) \list_entry((ptr)-next, type, member)/*** list_last_entry - get the last element from a list* ptr: the list head to take the element from.* type: the type of the struct this is embedded in.* member: the name of the list_head within the struct.** Note, that list is expected to be not empty.*/ #define list_last_entry(ptr, type, member) \list_entry((ptr)-prev, type, member)/*** list_first_entry_or_null - get the first element from a list* ptr: the list head to take the element from.* type: the type of the struct this is embedded in.* member: the name of the list_head within the struct.** Note that if the list is empty, it returns NULL.*/ #define list_first_entry_or_null(ptr, type, member) ({ \struct list_head *head__ (ptr); \struct list_head *pos__ READ_ONCE(head__-next); \pos__ ! head__ ? list_entry(pos__, type, member) : NULL; \ })/*** list_for_each - iterate over a list* pos: the struct list_head to use as a loop cursor.* head: the head for your list.*/ #define list_for_each(pos, head) \for (pos (head)-next; !list_is_head(pos, (head)); pos pos-next)/*** list_for_each_continue - continue iteration over a list* pos: the struct list_head to use as a loop cursor.* head: the head for your list.** Continue to iterate over a list, continuing after the current position.*/ #define list_for_each_continue(pos, head) \for (pos pos-next; !list_is_head(pos, (head)); pos pos-next)/*** list_for_each_prev - iterate over a list backwards* pos: the struct list_head to use as a loop cursor.* head: the head for your list.*/ #define list_for_each_prev(pos, head) \for (pos (head)-prev; !list_is_head(pos, (head)); pos pos-prev)/*** list_for_each_safe - iterate over a list safe against removal of list entry* pos: the struct list_head to use as a loop cursor.* n: another struct list_head to use as temporary storage* head: the head for your list.*/ #define list_for_each_safe(pos, n, head) \for (pos (head)-next, n pos-next; \!list_is_head(pos, (head)); \pos n, n pos-next)/*** list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry* pos: the struct list_head to use as a loop cursor.* n: another struct list_head to use as temporary storage* head: the head for your list.*/ #define list_for_each_prev_safe(pos, n, head) \for (pos (head)-prev, n pos-prev; \!list_is_head(pos, (head)); \pos n, n pos-prev)/*** list_entry_is_head - test if the entry points to the head of the list* pos: the type * to cursor* head: the head for your list.* member: the name of the list_head within the struct.*/ #define list_entry_is_head(pos, head, member) \(pos-member (head))/*** list_for_each_entry_continue - continue iteration 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_head within the struct.** Continue to iterate over list of given type, continuing after* the current position.*/ #define list_for_each_entry_continue(pos, head, member) \for (pos list_next_entry(pos, member); \!list_entry_is_head(pos, head, member); \pos list_next_entry(pos, member))/*** list_for_each_entry_continue_reverse - iterate backwards from the given point* pos: the type * to use as a loop cursor.* head: the head for your list.* member: the name of the list_head within the struct.** Start to iterate over list of given type backwards, continuing after* the current position.*/ #define list_for_each_entry_continue_reverse(pos, head, member) \for (pos list_prev_entry(pos, member); \!list_entry_is_head(pos, head, member); \pos list_prev_entry(pos, member))/*** list_for_each_entry_from - iterate over list of given type from the current point* pos: the type * to use as a loop cursor.* head: the head for your list.* member: the name of the list_head within the struct.** Iterate over list of given type, continuing from current position.*/ #define list_for_each_entry_from(pos, head, member) \for (; !list_entry_is_head(pos, head, member); \pos list_next_entry(pos, member))/*** list_for_each_entry_from_reverse - iterate backwards over list of given type* from the current point* pos: the type * to use as a loop cursor.* head: the head for your list.* member: the name of the list_head within the struct.** Iterate backwards over list of given type, continuing from current position.*/ #define list_for_each_entry_from_reverse(pos, head, member) \for (; !list_entry_is_head(pos, head, member); \pos list_prev_entry(pos, member))/*** list_for_each_entry_safe_continue - continue list iteration safe against removal* pos: the type * to use as a loop cursor.* n: another type * to use as temporary storage* head: the head for your list.* member: the name of the list_head within the struct.** Iterate over list of given type, continuing after current point,* safe against removal of list entry.*/ #define list_for_each_entry_safe_continue(pos, n, head, member) \for (pos list_next_entry(pos, member), \n list_next_entry(pos, member); \!list_entry_is_head(pos, head, member); \pos n, n list_next_entry(n, member))/*** list_for_each_entry_safe_from - iterate over list from current point safe against removal* pos: the type * to use as a loop cursor.* n: another type * to use as temporary storage* head: the head for your list.* member: the name of the list_head within the struct.** Iterate over list of given type from current point, safe against* removal of list entry.*/ #define list_for_each_entry_safe_from(pos, n, head, member) \for (n list_next_entry(pos, member); \!list_entry_is_head(pos, head, member); \pos n, n list_next_entry(n, member))/*** list_safe_reset_next - reset a stale list_for_each_entry_safe loop* pos: the loop cursor used in the list_for_each_entry_safe loop* n: temporary storage used in list_for_each_entry_safe* member: the name of the list_head within the struct.** list_safe_reset_next is not safe to use in general if the list may be* modified concurrently (eg. the lock is dropped in the loop body). An* exception to this is if the cursor element (pos) is pinned in the list,* and list_safe_reset_next is called after re-taking the lock and before* completing the current iteration of the loop body.*/ #define list_safe_reset_next(pos, n, member) \n list_next_entry(pos, member)/** Double linked lists with a single pointer list head.* Mostly useful for hash tables where the two pointer list head is* too wasteful.* You lose the ability to access the tail in O(1).*/#define HLIST_HEAD_INIT { .first NULL } #define HLIST_HEAD(name) struct hlist_head name { .first NULL } #define INIT_HLIST_HEAD(ptr) ((ptr)-first NULL) static inline void INIT_HLIST_NODE(struct hlist_node *h) {h-next NULL;h-pprev NULL; }/*** hlist_unhashed - Has node been removed from list and reinitialized?* h: Node to be checked** Not that not all removal functions will leave a node in unhashed* state. For example, hlist_nulls_del_init_rcu() does leave the* node in unhashed state, but hlist_nulls_del() does not.*/ static inline int hlist_unhashed(const struct hlist_node *h) {return !h-pprev; }/*** hlist_unhashed_lockless - Version of hlist_unhashed for lockless use* h: Node to be checked** This variant of hlist_unhashed() must be used in lockless contexts* to avoid potential load-tearing. The READ_ONCE() is paired with the* various WRITE_ONCE() in hlist helpers that are defined below.*/ static inline int hlist_unhashed_lockless(const struct hlist_node *h) {return !READ_ONCE(h-pprev); }/*** hlist_empty - Is the specified hlist_head structure an empty hlist?* h: Structure to check.*/ static inline int hlist_empty(const struct hlist_head *h) {return !READ_ONCE(h-first); }static inline void __hlist_del(struct hlist_node *n) {struct hlist_node *next n-next;struct hlist_node **pprev n-pprev;WRITE_ONCE(*pprev, next);if (next)WRITE_ONCE(next-pprev, pprev); }/*** hlist_del - Delete the specified hlist_node from its list* n: Node to delete.** Note that this function leaves the node in hashed state. Use* hlist_del_init() or similar instead to unhash n.*/ static inline void hlist_del(struct hlist_node *n) {__hlist_del(n);n-next NULL;n-pprev NULL; }/*** hlist_del_init - Delete the specified hlist_node from its list and initialize* n: Node to delete.** Note that this function leaves the node in unhashed state.*/ static inline void hlist_del_init(struct hlist_node *n) {if (!hlist_unhashed(n)) {__hlist_del(n);INIT_HLIST_NODE(n);} }/*** hlist_add_head - add a new entry at the beginning of the hlist* n: new entry to be added* h: hlist head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) {struct hlist_node *first h-first;WRITE_ONCE(n-next, first);if (first)WRITE_ONCE(first-pprev, n-next);WRITE_ONCE(h-first, n);WRITE_ONCE(n-pprev, h-first); }/*** hlist_add_before - add a new entry before the one specified* n: new entry to be added* next: hlist node to add it before, which must be non-NULL*/ static inline void hlist_add_before(struct hlist_node *n,struct hlist_node *next) {WRITE_ONCE(n-pprev, next-pprev);WRITE_ONCE(n-next, next);WRITE_ONCE(next-pprev, n-next);WRITE_ONCE(*(n-pprev), n); }/*** hlist_add_behind - add a new entry after the one specified* n: new entry to be added* prev: hlist node to add it after, which must be non-NULL*/ static inline void hlist_add_behind(struct hlist_node *n,struct hlist_node *prev) {WRITE_ONCE(n-next, prev-next);WRITE_ONCE(prev-next, n);WRITE_ONCE(n-pprev, prev-next);if (n-next)WRITE_ONCE(n-next-pprev, n-next); }/*** hlist_add_fake - create a fake hlist consisting of a single headless node* n: Node to make a fake list out of** This makes n appear to be its own predecessor on a headless hlist.* The point of this is to allow things like hlist_del() to work correctly* in cases where there is no list.*/ static inline void hlist_add_fake(struct hlist_node *n) {n-pprev n-next; }/*** hlist_fake: Is this node a fake hlist?* h: Node to check for being a self-referential fake hlist.*/ static inline bool hlist_fake(struct hlist_node *h) {return h-pprev h-next; }/*** hlist_is_singular_node - is node the only element of the specified hlist?* n: Node to check for singularity.* h: Header for potentially singular list.** Check whether the node is the only node of the head without* accessing head, thus avoiding unnecessary cache misses.*/ static inline bool hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) {return !n-next n-pprev h-first; }/*** hlist_move_list - Move an hlist* old: hlist_head for old list.* new: hlist_head for new list.** Move a list from one list head to another. Fixup the pprev* reference of the first entry if it exists.*/ static inline void hlist_move_list(struct hlist_head *old,struct hlist_head *new) {new-first old-first;if (new-first)new-first-pprev new-first;old-first NULL; }#define hlist_entry(ptr, type, member) container_of(ptr,type,member)#define hlist_for_each(pos, head) \for (pos (head)-first; pos ; pos pos-next)#define hlist_for_each_safe(pos, n, head) \for (pos (head)-first; pos ({ n pos-next; 1; }); \pos n)#endif四、使用方法 4.1、初始化链表 struct mailbox_data {u8 chan;u32 cmd;u32 data;int (*func)(struct mailbox_data *mailbox);struct list_head head; };LIST_HEAD(mailbox_list_head);或 struct mailbox_data {u8 chan;u32 cmd;u32 data;int (*func)(struct mailbox_data *mailbox);struct list_head head; };struct mailbox_head mailbox_list_head; INIT_LIST_HEAD(mailbox_list_head);4.2、添加链表 struct mailbox_data* mailbox calloc(1, sizeof(*mailbox)); list_add_tail(mailbox-head, mailbox_list_head);4.3、遍历链表 struct list_head* pos NULL; struct list_head* pt NULL; struct mailbox_data* mailbox NULL;list_for_each_safe(pos, pt, mailbox_list_head) {mailbox list_entry(pos, struct mailbox_data, head);if (mailbox-func) {mailbox-func(mailbox);}list_del(mailbox -head);free(mailbox); }4.4、删除链表 list_del(mailbox -head);
http://www.w-s-a.com/news/166661/

相关文章:

  • 建设网站 请示 报告wordpress会员制
  • 青岛建网站人做网站怎么赚钱广告
  • 网站建设哪家好公司跨境电商展会2023
  • 设计大神云集的网站是南通市 网站设计
  • 心理咨询网站模板企业画册封面设计
  • 做网站 南京网站建设的重难点分析
  • 深圳做网站980移动网站开发语言
  • 网站评论怎么做seo关键词优化方法
  • 市级部门网站建设自评报告网站优化文章怎么做
  • 可不可以异地建设网站学做网站培训班要多少钱
  • 茌平网站建设公司免费的云服务器有哪些
  • 手机网站单页面铜陵网站制作公司
  • 网站logo怎么做才清晰千库网官网首页登录
  • 山西省建设银行网站首页长沙网站建设制作
  • 襄阳市做网站 优帮云百度搜索次数统计
  • 自己做视频直播网站盐城做网站多少钱
  • 买个网站服务器多少钱重庆做的好的房产网站
  • 深圳定制建站网站建设推广关键词怎么设置
  • 宝山网站建设 网站外包修改wordpress版权
  • 建立网站的基本步骤新网站多久会被百度收录
  • 软件设计开发流程图廊坊关键词seo排名方案
  • 南山住房和建设局网站网站被k 多久恢复
  • 阿里买域名 电脑做网站做简历哪个网站好
  • 个人网站免费服务器单页网站的域名
  • 网站设计简单讲解小店怎么做网站
  • 校园网站的意义wordpress去除更新
  • 网站开发用python吗常用的网页开发工具有哪些
  • 北京市住房建设投资建设网站做商城网站要哪些流程
  • seo网站改版杭州建设局官网
  • 物流网站建设策划书泰然建设网站