Skip to content

Commit

Permalink
sighook: Fix sigreset() error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
tavianator committed Jan 20, 2025
1 parent be8aa86 commit 34e6eca
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions src/sighook.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,18 +295,22 @@ static void rcu_list_remove(struct rcu_list *list, struct rcu_node *node) {
rcu_destroy(&node->next);
}

/** Iterate over an rcu_list. */
/**
* Iterate over an rcu_list.
*
* It is save to `break` out of this loop, but `return` or `goto` will lead to
* a missed arc_put().
*/
#define for_rcu(type, node, list) \
for_rcu_(type, node, (list), node##_slot_, node##_prev_, node##_done_)

#define for_rcu_(type, node, list, slot, prev, done) \
/* This outer loop is just for declaring variables; it iterates once. */ \
for (struct arc *slot, *prev, **done = NULL; !done && (done = &slot); ) \
for (struct arc *slot, *prev, **done = NULL; !done; arc_put(slot), done = &slot) \
for (type *node = rcu_read(&list->head, &slot); \
node || (arc_put(slot), false); \
(prev = slot, \
node = rcu_read(&((struct rcu_node *)node)->next, &slot), \
arc_put(prev)))
node; \
prev = slot, \
node = rcu_read(&((struct rcu_node *)node)->next, &slot), \
arc_put(prev))

struct sighook {
/** The RCU list node (must be the first field). */
Expand Down Expand Up @@ -675,11 +679,14 @@ int sigreset(void) {
return 0;
}

int ret = 0;

for_rcu (struct sigsave, save, &saved) {
if (sigaction(save->sig, &save->action, NULL) != 0) {
return -1;
ret = -1;
break;
}
}

return 0;
return ret;
}

0 comments on commit 34e6eca

Please sign in to comment.