diff --git a/ChangeLog.asciidoc b/ChangeLog.asciidoc index 8819c5b9a..b2c15fe6e 100644 --- a/ChangeLog.asciidoc +++ b/ChangeLog.asciidoc @@ -47,6 +47,8 @@ http://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes] * core: add signals "key_combo_{default|search|cursor}" * core: display a warning in case of inconsistency between the options weechat.look.save_{config|layout}_on_exit +* api: add option "signal" in function hook_set to send a signal to the child + process * api: add support of escaped strings with format `${esc:xxx}` or `${\xxx}` in function string_eval_expression and command /eval * api: add functions "hashtable_dup", "string_replace_regex", diff --git a/doc/en/weechat_plugin_api.en.txt b/doc/en/weechat_plugin_api.en.txt index 4fdaf749d..44edaa35e 100644 --- a/doc/en/weechat_plugin_api.en.txt +++ b/doc/en/weechat_plugin_api.en.txt @@ -9743,6 +9743,13 @@ Properties: _(WeeChat ≥ 0.4.3)_ | 'process', 'process_hashtable' | (not used) | Close pipe used to send data on standard input ('stdin') of child process + +| signal + + _(WeeChat ≥ 0.4.4)_ | + 'process', 'process_hashtable' | + signal number or one of these names: `hup`, `int`, `quit`, `kill`, `term`, + `usr1`, `usr2` | + Send a signal to the child process |=== C example: diff --git a/doc/fr/weechat_plugin_api.fr.txt b/doc/fr/weechat_plugin_api.fr.txt index 0c505952c..624b23cf3 100644 --- a/doc/fr/weechat_plugin_api.fr.txt +++ b/doc/fr/weechat_plugin_api.fr.txt @@ -9932,6 +9932,13 @@ Propriétés : 'process', 'process_hashtable' | (non utilisée) | Fermer le tuyau utilisé pour envoyer les données sur l'entrée standard ('stdin') du processus fils + +| signal + + _(WeeChat ≥ 0.4.4)_ | + 'process', 'process_hashtable' | + numéro de signal ou un de ces noms : `hup`, `int`, `quit`, `kill`, `term`, + `usr1`, `usr2` | + Envoyer un signal au processus fils |=== Exemple en C : diff --git a/doc/it/weechat_plugin_api.it.txt b/doc/it/weechat_plugin_api.it.txt index 71e7f1324..ff87f88ac 100644 --- a/doc/it/weechat_plugin_api.it.txt +++ b/doc/it/weechat_plugin_api.it.txt @@ -9986,6 +9986,15 @@ Properties: 'process', 'process_hashtable' | (not used) | // TRANSLATION MISSING Close pipe used to send data on standard input ('stdin') of child process + +| signal + + _(WeeChat ≥ 0.4.4)_ | + 'process', 'process_hashtable' | +// TRANSLATION MISSING + signal number or one of these names: `hup`, `int`, `quit`, `kill`, `term`, + `usr1`, `usr2` | +// TRANSLATION MISSING + Send a signal to the child process |=== Esempio in C: diff --git a/doc/ja/weechat_plugin_api.ja.txt b/doc/ja/weechat_plugin_api.ja.txt index 56e682fcc..bc95ca4f3 100644 --- a/doc/ja/weechat_plugin_api.ja.txt +++ b/doc/ja/weechat_plugin_api.ja.txt @@ -9759,6 +9759,15 @@ void weechat_hook_set (struct t_hook *hook, const char *property, _(WeeChat バージョン 0.4.3 以上で利用可)_ | 'process' 、'process_hashtable' | (非使用) | 子プロセスの標準入力 ('stdin') にデータを送信するパイプを閉じる + +| signal + + _(WeeChat ≥ 0.4.4)_ | + 'process', 'process_hashtable' | +// TRANSLATION MISSING + signal number or one of these names: `hup`, `int`, `quit`, `kill`, `term`, + `usr1`, `usr2` | +// TRANSLATION MISSING + Send a signal to the child process |=== C 言語での使用例: diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index bbc6b055b..f4f1c130b 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -3219,6 +3219,9 @@ void hook_set (struct t_hook *hook, const char *property, const char *value) { ssize_t num_written; + char *error; + long number; + int rc; /* invalid hook? */ if (!hook_valid (hook)) @@ -3253,6 +3256,34 @@ hook_set (struct t_hook *hook, const char *property, const char *value) HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]) = -1; } } + else if (string_strcasecmp (property, "signal") == 0) + { + if (!hook->deleted + && (hook->type == HOOK_TYPE_PROCESS) + && (HOOK_PROCESS(hook, child_pid) > 0)) + { + error = NULL; + number = strtol (value, &error, 10); + if (!error || error[0]) + { + /* not a number? look for signal by name */ + number = util_signal_search (value); + } + if (number >= 0) + { + rc = kill (HOOK_PROCESS(hook, child_pid), (int)number); + if (rc < 0) + { + gui_chat_printf (NULL, + _("%sError sending signal %d to pid %d: %s"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + (int)number, + HOOK_PROCESS(hook, child_pid), + strerror (errno)); + } + } + } + } } /* diff --git a/src/core/wee-util.c b/src/core/wee-util.c index 2630f36c2..9d93c396b 100644 --- a/src/core/wee-util.c +++ b/src/core/wee-util.c @@ -103,6 +103,16 @@ struct t_rlimit_resource rlimit_resource[] = }; #endif /* HAVE_SYS_RESOURCE_H */ +struct t_util_signal util_signals[] = +{ { "hup", SIGHUP }, + { "int", SIGINT }, + { "quit", SIGQUIT }, + { "kill", SIGKILL }, + { "term", SIGTERM }, + { "usr1", SIGUSR1 }, + { "usr2", SIGUSR2 }, + { NULL, 0 }, +}; /* * Sets resource limit. @@ -302,6 +312,28 @@ util_get_time_string (const time_t *date) return text_time; } +/* + * Gets a signal number with a name; only some commonly used signal names are + * supported here (see declaration of util_signals[]). + * + * Returns the signal number, -1 if not found. + */ + +int +util_signal_search (const char *name) +{ + int i; + + for (i = 0; util_signals[i].name; i++) + { + if (string_strcasecmp (util_signals[i].name, name) == 0) + return util_signals[i].signal; + } + + /* signal not found */ + return -1; +} + /* * Catches a system signal. */ diff --git a/src/core/wee-util.h b/src/core/wee-util.h index 342881bc9..e200f9061 100644 --- a/src/core/wee-util.h +++ b/src/core/wee-util.h @@ -28,11 +28,18 @@ struct t_rlimit_resource }; #endif /* HAVE_SYS_RESOURCE_H */ +struct t_util_signal +{ + char *name; /* name of signal */ + int signal; /* signal number */ +}; + extern void util_setrlimit (); extern int util_timeval_cmp (struct timeval *tv1, struct timeval *tv2); extern long util_timeval_diff (struct timeval *tv1, struct timeval *tv2); extern void util_timeval_add (struct timeval *tv, long interval); extern char *util_get_time_string (const time_t *date); +extern int util_signal_search (const char *name); extern void util_catch_signal (int signum, void (*handler)(int)); extern int util_mkdir_home (const char *directory, int mode); extern int util_mkdir (const char *directory, int mode);