aboutsummaryrefslogtreecommitdiff
path: root/vis-subprocess.c
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2023-11-18 11:26:24 +0100
committerRandy Palamar <randy@rnpnr.xyz>2023-11-18 16:36:56 -0700
commitd1eb36c96a5d98b0ea9a4422fbd247261e169fa5 (patch)
treebff77ad7813c2263bd151025ef813c7b77ad5e04 /vis-subprocess.c
parent1e64b1c13aa0f4b41f564223b6c0529a56959f85 (diff)
downloadvis-d1eb36c96a5d98b0ea9a4422fbd247261e169fa5.tar.gz
vis-d1eb36c96a5d98b0ea9a4422fbd247261e169fa5.tar.xz
destroy the correct subprocess
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: 0b015320382e74fcb385a46a81304f588ed27f77
Diffstat (limited to 'vis-subprocess.c')
-rw-r--r--vis-subprocess.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/vis-subprocess.c b/vis-subprocess.c
index f06688c..39282e4 100644
--- a/vis-subprocess.c
+++ b/vis-subprocess.c
@@ -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);
}
@@ -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;
}
/**
@@ -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];
@@ -211,6 +212,7 @@ just_destroy:
} else {
vis_lua_process_response(vis, current->name, NULL, WEXITSTATUS(status), EXIT);
}
- destroy_process(pointer);
+ /* update our iteration pointer */
+ *pointer = destroy_process(current);
}
}