ifupdown: code to deconstruct the state_list gracefully
(patch by Gabriel L. Somlo <somlo@cmu.edu>)
This commit is contained in:
parent
9431e564aa
commit
c115fdbc80
@ -475,6 +475,7 @@ typedef struct llist_s {
|
|||||||
extern void llist_add_to(llist_t **old_head, void *data);
|
extern void llist_add_to(llist_t **old_head, void *data);
|
||||||
extern void llist_add_to_end(llist_t **list_head, void *data);
|
extern void llist_add_to_end(llist_t **list_head, void *data);
|
||||||
extern void *llist_pop(llist_t **elm);
|
extern void *llist_pop(llist_t **elm);
|
||||||
|
extern void llist_unlink(llist_t **head, llist_t *elm);
|
||||||
extern void llist_free(llist_t *elm, void (*freeit)(void *data));
|
extern void llist_free(llist_t *elm, void (*freeit)(void *data));
|
||||||
extern llist_t* llist_rev(llist_t *list);
|
extern llist_t* llist_rev(llist_t *list);
|
||||||
|
|
||||||
|
@ -45,21 +45,40 @@ void llist_add_to_end(llist_t ** list_head, void *data)
|
|||||||
/* Remove first element from the list and return it */
|
/* Remove first element from the list and return it */
|
||||||
void *llist_pop(llist_t ** head)
|
void *llist_pop(llist_t ** head)
|
||||||
{
|
{
|
||||||
void *data;
|
void *data, *next;
|
||||||
|
|
||||||
if (!*head)
|
if (!*head)
|
||||||
data = *head;
|
return NULL;
|
||||||
else {
|
|
||||||
void *next = (*head)->link;
|
|
||||||
|
|
||||||
data = (*head)->data;
|
data = (*head)->data;
|
||||||
free(*head);
|
next = (*head)->link;
|
||||||
*head = next;
|
free(*head);
|
||||||
}
|
*head = next;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unlink arbitrary given element from the list */
|
||||||
|
void llist_unlink(llist_t **head, llist_t *elm)
|
||||||
|
{
|
||||||
|
llist_t *crt;
|
||||||
|
|
||||||
|
if (!(elm && *head))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (elm == *head) {
|
||||||
|
*head = (*head)->link;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (crt = *head; crt; crt = crt->link) {
|
||||||
|
if (crt->link == elm) {
|
||||||
|
crt->link = elm->link;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Recursively free all elements in the linked list. If freeit != NULL
|
/* Recursively free all elements in the linked list. If freeit != NULL
|
||||||
* call it on each datum in the list */
|
* call it on each datum in the list */
|
||||||
void llist_free(llist_t * elm, void (*freeit) (void *data))
|
void llist_free(llist_t * elm, void (*freeit) (void *data))
|
||||||
|
@ -1091,6 +1091,7 @@ int ifupdown_main(int argc, char **argv)
|
|||||||
llist_t *state_list = NULL;
|
llist_t *state_list = NULL;
|
||||||
llist_t *target_list = NULL;
|
llist_t *target_list = NULL;
|
||||||
const char *interfaces = "/etc/network/interfaces";
|
const char *interfaces = "/etc/network/interfaces";
|
||||||
|
FILE *state_fp;
|
||||||
int any_failures = 0;
|
int any_failures = 0;
|
||||||
|
|
||||||
cmds = iface_down;
|
cmds = iface_down;
|
||||||
@ -1117,6 +1118,19 @@ int ifupdown_main(int argc, char **argv)
|
|||||||
startup_PATH = getenv("PATH");
|
startup_PATH = getenv("PATH");
|
||||||
if (!startup_PATH) startup_PATH = "";
|
if (!startup_PATH) startup_PATH = "";
|
||||||
|
|
||||||
|
/* Read the previous state from the state file */
|
||||||
|
state_fp = fopen_or_warn("/var/run/ifstate", "r");
|
||||||
|
if (state_fp) {
|
||||||
|
char *start, *end_ptr;
|
||||||
|
while ((start = xmalloc_fgets(state_fp)) != NULL) {
|
||||||
|
/* We should only need to check for a single character */
|
||||||
|
end_ptr = start + strcspn(start, " \t\n");
|
||||||
|
*end_ptr = '\0';
|
||||||
|
llist_add_to(&state_list, start);
|
||||||
|
}
|
||||||
|
fclose(state_fp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a list of interfaces to work on */
|
/* Create a list of interfaces to work on */
|
||||||
if (DO_ALL) {
|
if (DO_ALL) {
|
||||||
if (cmds == iface_up) {
|
if (cmds == iface_up) {
|
||||||
@ -1166,7 +1180,7 @@ int ifupdown_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* ifdown */
|
/* ifdown */
|
||||||
if (iface_state) {
|
if (!iface_state) {
|
||||||
bb_error_msg("interface %s not configured", iface);
|
bb_error_msg("interface %s not configured", iface);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1236,7 +1250,8 @@ int ifupdown_main(int argc, char **argv)
|
|||||||
iface_state->data = newiface;
|
iface_state->data = newiface;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Remove an interface from the linked list */
|
/* Remove an interface from state_list */
|
||||||
|
llist_unlink(&state_list, iface_state);
|
||||||
free(llist_pop(&iface_state));
|
free(llist_pop(&iface_state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1244,8 +1259,6 @@ int ifupdown_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Actually write the new state */
|
/* Actually write the new state */
|
||||||
if (!NO_ACT) {
|
if (!NO_ACT) {
|
||||||
FILE *state_fp;
|
|
||||||
|
|
||||||
state_fp = xfopen("/var/run/ifstate", "w");
|
state_fp = xfopen("/var/run/ifstate", "w");
|
||||||
while (state_list) {
|
while (state_list) {
|
||||||
if (state_list->data) {
|
if (state_list->data) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user