Skip to content

Commit

Permalink
destroy the correct subprocess
Browse files Browse the repository at this point in the history
When a new subprocess is created during an EXIT event of
another subprocess new_process_in_pool will update the
process_pool pointer. Since we use a pointer to a pointer
for iterating all processes during vis_process_tick its
value will be different before executing the event and after
creating the new subprocess. This causes the updated pointer
to be erroneously destroyed and leaves the Process of the
reaped child behind which causes consecutive waitpid calls
to fail with ECHILD.

This is fixed by destroying the proper current subprocess
and updating the iteration pointer accordingly.

Fixes: 0b01532
  • Loading branch information
fischerling authored and rnpnr committed Nov 18, 2023
1 parent 1e64b1c commit d1eb36c
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions vis-subprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,10 @@ static Process *new_process_in_pool(void) {
/**
* Removes the subprocess information from the pool, sets invalidator to NULL
* and frees resources.
* @param a reference to a reference to the process to be removed
* @param a reference to the process to be removed
* @return the next process in the pool
*/
static void destroy_process(Process **pointer) {
Process *target = *pointer;
static Process *destroy_process(Process *target) {
if (target->outfd != -1) {
close(target->outfd);
}
Expand All @@ -47,9 +46,11 @@ static void destroy_process(Process **pointer) {
if (target->invalidator) {
*(target->invalidator) = NULL;
}
*pointer = target->next;
Process *next = target->next;
free(target->name);
free(target);

return next;
}

/**
Expand Down Expand Up @@ -104,7 +105,7 @@ Process *vis_process_communicate(Vis *vis, const char *name,
if (!new->name) {
vis_info_show(vis, "Cannot copy process name: %s", strerror(errno));
/* pop top element (which is `new`) from the pool */
destroy_process(&process_pool);
process_pool = destroy_process(process_pool);
goto closeall;
}
new->outfd = pout[0];
Expand Down Expand Up @@ -211,6 +212,7 @@ void vis_process_tick(Vis *vis, fd_set *readfds) {
} else {
vis_lua_process_response(vis, current->name, NULL, WEXITSTATUS(status), EXIT);
}
destroy_process(pointer);
/* update our iteration pointer */
*pointer = destroy_process(current);
}
}

0 comments on commit d1eb36c

Please sign in to comment.