]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/list.h
Merge pull request #3059 from brauner/2019-06-21/seccomp_notify
[mirror_lxc.git] / src / lxc / list.h
CommitLineData
250b1eec
SG
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
f1a4a029
ÇO
24#ifndef __LXC_LIST_H
25#define __LXC_LIST_H
0ad19a3f 26
1a0e70ac
CB
27#include <stdio.h>
28
951cc719 29struct lxc_list {
0ad19a3f 30 void *elem;
951cc719
DL
31 struct lxc_list *next;
32 struct lxc_list *prev;
0ad19a3f 33};
34
1a0e70ac
CB
35#define lxc_init_list(l) \
36 { \
37 .next = l, .prev = l \
38 }
0ad19a3f 39
c2613927
CB
40/*
41 * Iterate through an lxc list. An example for an idiom would be:
42 *
43 * struct lxc_list *iterator;
c2613927 44 * lxc_list_for_each(iterator, list) {
1a0e70ac 45 * type *tmp;
c2613927 46 * tmp = iterator->elem;
c2613927 47 * }
c2613927 48 */
1a0e70ac
CB
49#define lxc_list_for_each(__iterator, __list) \
50 for (__iterator = (__list)->next; __iterator != __list; \
0ad19a3f 51 __iterator = __iterator->next)
52
1a0e70ac 53/* Iterate safely through an lxc list. An example for an appropriate use case
c2613927
CB
54 * would be:
55 *
1a0e70ac
CB
56 * struct lxc_list *cur, *next;
57 * lxc_list_for_each_safe(cur, list, next) {
58 * type *tmp;
59 * tmp = cur->elem;
c2613927 60 * }
c2613927 61 */
1a0e70ac
CB
62#define lxc_list_for_each_safe(__iterator, __list, __next) \
63 for (__iterator = (__list)->next, __next = __iterator->next; \
64 __iterator != __list; __iterator = __next, __next = __next->next)
9ebb03ad 65
95db7d8c 66/* Initialize list. */
951cc719 67static inline void lxc_list_init(struct lxc_list *list)
0ad19a3f 68{
69 list->elem = NULL;
70 list->next = list->prev = list;
71}
72
c2613927 73/* Add an element to a list. See lxc_list_add() and lxc_list_add_tail() for an
1a0e70ac
CB
74 * idiom.
75 */
951cc719 76static inline void lxc_list_add_elem(struct lxc_list *list, void *elem)
0ad19a3f 77{
78 list->elem = elem;
79}
80
c2613927 81/* Retrieve first element of list. */
951cc719 82static inline void *lxc_list_first_elem(struct lxc_list *list)
0ad19a3f 83{
84 return list->next->elem;
85}
86
c2613927 87/* Retrieve last element of list. */
bac89583
DL
88static inline void *lxc_list_last_elem(struct lxc_list *list)
89{
90 return list->prev->elem;
91}
92
c2613927 93/* Determine if list is empty. */
951cc719 94static inline int lxc_list_empty(struct lxc_list *list)
0ad19a3f 95{
96 return list == list->next;
97}
98
c2613927 99/* Workhorse to be called from lxc_list_add() and lxc_list_add_tail(). */
1a0e70ac 100static inline void __lxc_list_add(struct lxc_list *new, struct lxc_list *prev,
951cc719 101 struct lxc_list *next)
0ad19a3f 102{
d028235d
SG
103 next->prev = new;
104 new->next = next;
105 new->prev = prev;
106 prev->next = new;
0ad19a3f 107}
108
1a0e70ac 109/* Idiom to add an element to the beginning of an lxc list:
c2613927
CB
110 *
111 * struct lxc_list *tmp = malloc(sizeof(*tmp));
112 * if (tmp == NULL)
113 * return 1;
114 * lxc_list_add_elem(tmp, elem);
115 * lxc_list_add(list, tmp);
116 */
951cc719 117static inline void lxc_list_add(struct lxc_list *head, struct lxc_list *list)
0ad19a3f 118{
951cc719
DL
119 __lxc_list_add(list, head, head->next);
120}
121
1a0e70ac 122/* Idiom to add an element to the end of an lxc list:
c2613927
CB
123 *
124 * struct lxc_list *tmp = malloc(sizeof(*tmp));
125 * if (tmp == NULL)
126 * return 1;
127 * lxc_list_add_elem(tmp, elem);
128 * lxc_list_add_tail(list, tmp);
129 */
951cc719
DL
130static inline void lxc_list_add_tail(struct lxc_list *head,
131 struct lxc_list *list)
132{
133 __lxc_list_add(list, head->prev, head);
134}
135
1a0e70ac
CB
136/* Idiom to remove an element from a list:
137 * struct lxc_list *cur, *next;
138 * lxc_list_for_each_safe(cur, list, next) {
139 * lxc_list_del(cur);
140 * free(cur->elem);
141 * free(cur);
c2613927 142 * }
c2613927 143 */
951cc719
DL
144static inline void lxc_list_del(struct lxc_list *list)
145{
146 struct lxc_list *next, *prev;
0ad19a3f 147
148 next = list->next;
149 prev = list->prev;
150 next->prev = prev;
151 prev->next = next;
152}
153
c2613927
CB
154/* Return length of the list. */
155static inline size_t lxc_list_len(struct lxc_list *list)
9fc7f8c0 156{
ca9a2504 157 size_t i = 0;
158 struct lxc_list *iter;
1a0e70ac 159
ca9a2504 160 lxc_list_for_each(iter, list) {
9fc7f8c0 161 i++;
ca9a2504 162 }
9fc7f8c0 163
ca9a2504 164 return i;
9fc7f8c0
TA
165}
166
1a0e70ac 167#endif /* __LXC_LIST_H */