diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2023-10-10 19:23:43 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2023-10-10 19:23:43 +0200 |
commit | 02a05f63d5d84e1adedf2352721c418ef3ba8c76 (patch) | |
tree | 337a793b34e30fa958e10482ec4f6f0680e5f025 /src/core | |
parent | 408901d772a92fbf62b2e6c8ad3345e36d316d9a (diff) | |
download | weechat-02a05f63d5d84e1adedf2352721c418ef3ba8c76.zip |
core: fix zombie processes remaining after the end of forked processes (closes #1994)
The clean of processes with waitpid() is now delayed after the kill(), so that
there are no more zombies.
In addition, this can be done manually if needed with `/sys waitpid`.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/hook/wee-hook-connect.c | 2 | ||||
-rw-r--r-- | src/core/hook/wee-hook-process.c | 3 | ||||
-rw-r--r-- | src/core/wee-command.c | 16 | ||||
-rw-r--r-- | src/core/wee-hook.c | 30 | ||||
-rw-r--r-- | src/core/wee-hook.h | 1 | ||||
-rw-r--r-- | src/core/wee-sys.c | 19 | ||||
-rw-r--r-- | src/core/wee-sys.h | 1 |
7 files changed, 66 insertions, 6 deletions
diff --git a/src/core/hook/wee-hook-connect.c b/src/core/hook/wee-hook-connect.c index 81e402eca..d03fe4bec 100644 --- a/src/core/hook/wee-hook-connect.c +++ b/src/core/hook/wee-hook-connect.c @@ -270,7 +270,7 @@ hook_connect_free_data (struct t_hook *hook) if (HOOK_CONNECT(hook, child_pid) > 0) { kill (HOOK_CONNECT(hook, child_pid), SIGKILL); - waitpid (HOOK_CONNECT(hook, child_pid), NULL, 0); + hook_schedule_clean_children (); HOOK_CONNECT(hook, child_pid) = 0; } if (HOOK_CONNECT(hook, child_read) != -1) diff --git a/src/core/hook/wee-hook-process.c b/src/core/hook/wee-hook-process.c index ff676dffc..42f0d2a72 100644 --- a/src/core/hook/wee-hook-process.c +++ b/src/core/hook/wee-hook-process.c @@ -603,7 +603,6 @@ hook_process_timer_cb (const void *pointer, void *data, int remaining_calls) ((float)HOOK_PROCESS(hook_process, timeout)) / 1000); } kill (HOOK_PROCESS(hook_process, child_pid), SIGKILL); - usleep (1000); unhook (hook_process); } else @@ -863,7 +862,7 @@ hook_process_free_data (struct t_hook *hook) if (HOOK_PROCESS(hook, child_pid) > 0) { kill (HOOK_PROCESS(hook, child_pid), SIGKILL); - waitpid (HOOK_PROCESS(hook, child_pid), NULL, 0); + hook_schedule_clean_children (); HOOK_PROCESS(hook, child_pid) = 0; } if (HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDIN]) != -1) diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 64fb1ea08..7520570a7 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -6795,6 +6795,12 @@ COMMAND_CALLBACK(sys) return WEECHAT_RC_OK; } + if (string_strcmp (argv[1], "waitpid") == 0) + { + sys_waitpid (); + return WEECHAT_RC_OK; + } + COMMAND_ERROR; } @@ -9273,15 +9279,19 @@ command_init () NULL, "sys", N_("system actions"), "get rlimit|rusage" - " || suspend", + " || suspend" + " || waitpid", N_(" get: display system info\n" " rlimit: display resource limits " "(see /help weechat.startup.sys_rlimit and \"man getrlimit\")\n" " rusage: display resource usage (see \"man getrusage\")\n" "suspend: suspend WeeChat and go back to the shell, by sending " - "signal SIGTSTP to the WeeChat process"), + "signal SIGTSTP to the WeeChat process\n" + "waitpid: acknowledge the end of children processes (to prevent " + "\"zombie\" processes)"), "get rlimit|rusage" - " || suspend", + " || suspend" + " || waitpid", &command_sys, NULL, NULL); hook_command ( NULL, "toggle", diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index 758052a72..d0c120640 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -38,6 +38,7 @@ #include "wee-log.h" #include "wee-signal.h" #include "wee-string.h" +#include "wee-sys.h" #include "wee-util.h" #include "../gui/gui-chat.h" #include "../plugins/plugin.h" @@ -628,6 +629,35 @@ hook_set (struct t_hook *hook, const char *property, const char *value) } /* + * Callback used to clean all children (forked processes) by acknowledging + * their end. + */ + +int +hook_timer_clean_children_cb (const void *pointer, void *data, + int remaining_calls) +{ + /* make C compiler happy */ + (void) pointer; + (void) data; + (void) remaining_calls; + + sys_waitpid (); + + return WEECHAT_RC_OK; +} + +/* + * Schedule a cleanup timer to clean children (forked processes). + */ + +void +hook_schedule_clean_children () +{ + hook_timer (NULL, 100, 0, 1, &hook_timer_clean_children_cb, NULL, NULL); +} + +/* * Unhooks something. */ diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h index bebb0419e..8ae79a3c6 100644 --- a/src/core/wee-hook.h +++ b/src/core/wee-hook.h @@ -146,6 +146,7 @@ extern void hook_callback_end (struct t_hook *hook, extern char *hook_get_description (struct t_hook *hook); extern void hook_set (struct t_hook *hook, const char *property, const char *value); +extern void hook_schedule_clean_children (); extern void unhook (struct t_hook *hook); extern void unhook_all_plugin (struct t_weechat_plugin *plugin, const char *subplugin); diff --git a/src/core/wee-sys.c b/src/core/wee-sys.c index 8bcb3226a..7560b80aa 100644 --- a/src/core/wee-sys.c +++ b/src/core/wee-sys.c @@ -32,6 +32,7 @@ #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif +#include <sys/wait.h> #include "weechat.h" #include "wee-config.h" @@ -341,3 +342,21 @@ sys_display_rusage () "getrusage"); #endif /* HAVE_SYS_RESOURCE_H */ } + +/* + * Calls waitpid() to acknowledge the end of forked processes, thus preventing + * them to become zombies. + */ + +void +sys_waitpid () +{ + int i; + + /* acknowledge the end of up to 42 forked processes */ + i = 0; + while ((i < 42) && (waitpid (-1, NULL, WNOHANG) > 0)) + { + i++; + } +} diff --git a/src/core/wee-sys.h b/src/core/wee-sys.h index d78f6fdb9..eb4e7bcb9 100644 --- a/src/core/wee-sys.h +++ b/src/core/wee-sys.h @@ -31,5 +31,6 @@ struct t_rlimit_resource extern void sys_setrlimit (); extern void sys_display_rlimit (); extern void sys_display_rusage (); +extern void sys_waitpid (); #endif /* WEECHAT_SYS_H */ |