summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.asciidoc1
-rw-r--r--doc/en/weechat_plugin_api.en.txt6
-rw-r--r--doc/fr/weechat_plugin_api.fr.txt6
-rw-r--r--doc/it/weechat_plugin_api.it.txt7
-rw-r--r--doc/ja/weechat_plugin_api.ja.txt7
-rw-r--r--src/core/wee-hook.c102
-rw-r--r--src/core/wee-hook.h1
7 files changed, 98 insertions, 32 deletions
diff --git a/ChangeLog.asciidoc b/ChangeLog.asciidoc
index b3f699407..a716e0091 100644
--- a/ChangeLog.asciidoc
+++ b/ChangeLog.asciidoc
@@ -49,6 +49,7 @@ http://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
weechat.look.save_{config|layout}_on_exit
* api: add support of case insensitive search and search by buffer full name
in function buffer_search (bug #34318)
+* api: add option "detached" in function hook_process_hashtable
* 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
diff --git a/doc/en/weechat_plugin_api.en.txt b/doc/en/weechat_plugin_api.en.txt
index 45e33ef03..91631663d 100644
--- a/doc/en/weechat_plugin_api.en.txt
+++ b/doc/en/weechat_plugin_api.en.txt
@@ -7196,6 +7196,12 @@ available:
(not used) |
Create a pipe for writing data on standard input (stdin) of child process
(see function <<_weechat_hook_set,weechat_hook_set>>)
+
+| detached +
+ _(WeeChat ≥ 0.4.4)_ |
+ (not used) |
+ Run the process in a detached mode: stdout and stderr are redirected to
+ '/dev/null'
|===
For command "url:...", following options are available (see
diff --git a/doc/fr/weechat_plugin_api.fr.txt b/doc/fr/weechat_plugin_api.fr.txt
index 4cb6eb10b..60cca1461 100644
--- a/doc/fr/weechat_plugin_api.fr.txt
+++ b/doc/fr/weechat_plugin_api.fr.txt
@@ -7320,6 +7320,12 @@ sont disponibles :
(non utilisée) |
Créer un tuyau pour écrire sur l'entrée standard (stdin) du processus fils
(voir la fonction <<_weechat_hook_set,weechat_hook_set>>)
+
+| detached +
+ _(WeeChat ≥ 0.4.4)_ |
+ (non utilisée) |
+ Lancer le process dans un mode détaché : stdout et stderr sont redirigés vers
+ '/dev/null'
|===
Pour la commande "url:...", les options suivantes sont disponibles (voir
diff --git a/doc/it/weechat_plugin_api.it.txt b/doc/it/weechat_plugin_api.it.txt
index fb42c79b3..62ae887e6 100644
--- a/doc/it/weechat_plugin_api.it.txt
+++ b/doc/it/weechat_plugin_api.it.txt
@@ -7313,6 +7313,13 @@ available:
(not used) |
Create a pipe for writing data on standard input (stdin) of child process
(see function <<_weechat_hook_set,weechat_hook_set>>)
+
+// TRANSLATION MISSING
+| detached +
+ _(WeeChat ≥ 0.4.4)_ |
+ (not used) |
+ Run the process in a detached mode: stdout and stderr are redirected to
+ '/dev/null'
|===
Per il comando "url:..." sono disponibili le seguenti opzioni (consultare
diff --git a/doc/ja/weechat_plugin_api.ja.txt b/doc/ja/weechat_plugin_api.ja.txt
index 7dc2513b5..42032beef 100644
--- a/doc/ja/weechat_plugin_api.ja.txt
+++ b/doc/ja/weechat_plugin_api.ja.txt
@@ -7200,6 +7200,13 @@ struct t_hook *weechat_hook_process_hashtable (const char *command,
(非使用) |
データを書き込むためのパイプを子プロセスの標準入力 (stdin)
に作成します (関数 <<_weechat_hook_set,weechat_hook_set>> を参照)
+
+// TRANSLATION MISSING
+| detached +
+ _(WeeChat バージョン 0.4.4 以上で利用可)_ |
+ (非使用) |
+ Run the process in a detached mode: stdout and stderr are redirected to
+ '/dev/null'
|===
"url:..." 型のコマンドでは、以下のコマンドを使うことができます
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index f4f1c130b..415879530 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -1384,6 +1384,8 @@ hook_process_hashtable (struct t_weechat_plugin *plugin,
new_hook_process->callback = callback;
new_hook_process->command = strdup (command);
new_hook_process->options = (options) ? hashtable_dup (options) : NULL;
+ new_hook_process->detached = (options && hashtable_has_key (options,
+ "detached"));
new_hook_process->timeout = timeout;
new_hook_process->child_read[HOOK_PROCESS_STDIN] = -1;
new_hook_process->child_read[HOOK_PROCESS_STDOUT] = -1;
@@ -1468,17 +1470,35 @@ hook_process_child (struct t_hook *hook_process)
close (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDIN]));
/* redirect stdout/stderr to pipe (so that parent process can read them) */
- close (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]));
- close (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]));
- if (dup2 (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDOUT]),
+ if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]) >= 0)
+ {
+ close (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]));
+ if (dup2 (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDOUT]),
STDOUT_FILENO) < 0)
+ {
+ _exit (EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ /* detached mode: write stdout in /dev/null */
+ f = freopen ("/dev/null", "w", stdout);
+ (void) f;
+ }
+ if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]) >= 0)
{
- _exit (EXIT_FAILURE);
+ close (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]));
+ if (dup2 (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDERR]),
+ STDERR_FILENO) < 0)
+ {
+ _exit (EXIT_FAILURE);
+ }
}
- if (dup2 (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDERR]),
- STDERR_FILENO) < 0)
+ else
{
- _exit (EXIT_FAILURE);
+ /* detached mode: write stderr in /dev/null */
+ f = freopen ("/dev/null", "w", stderr);
+ (void) f;
}
rc = EXIT_SUCCESS;
@@ -1769,11 +1789,14 @@ hook_process_run (struct t_hook *hook_process)
goto error;
}
- /* create pipes for stdout/err */
- if (pipe (pipes[HOOK_PROCESS_STDOUT]) < 0)
- goto error;
- if (pipe (pipes[HOOK_PROCESS_STDERR]) < 0)
- goto error;
+ /* create pipes for stdout/err (if not running in detached mode) */
+ if (!HOOK_PROCESS(hook_process, detached))
+ {
+ if (pipe (pipes[HOOK_PROCESS_STDOUT]) < 0)
+ goto error;
+ if (pipe (pipes[HOOK_PROCESS_STDERR]) < 0)
+ goto error;
+ }
/* assign pipes to variables in hook */
for (i = 0; i < 3; i++)
@@ -1811,24 +1834,36 @@ hook_process_run (struct t_hook *hook_process)
close (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDIN]));
HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDIN]) = -1;
}
- close (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDOUT]));
- HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDOUT]) = -1;
- close (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDERR]));
- HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDERR]) = -1;
-
- HOOK_PROCESS(hook_process, hook_fd[HOOK_PROCESS_STDOUT]) =
- hook_fd (hook_process->plugin,
- HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]),
- 1, 0, 0,
- &hook_process_child_read_stdout_cb,
- hook_process);
-
- HOOK_PROCESS(hook_process, hook_fd[HOOK_PROCESS_STDERR]) =
- hook_fd (hook_process->plugin,
- HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]),
- 1, 0, 0,
- &hook_process_child_read_stderr_cb,
- hook_process);
+ if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]) >= 0)
+ {
+ close (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDOUT]));
+ HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDOUT]) = -1;
+ }
+ if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]) >= 0)
+ {
+ close (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDERR]));
+ HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDERR]) = -1;
+ }
+
+ if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]) >= 0)
+ {
+ HOOK_PROCESS(hook_process, hook_fd[HOOK_PROCESS_STDOUT]) =
+ hook_fd (hook_process->plugin,
+ HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]),
+ 1, 0, 0,
+ &hook_process_child_read_stdout_cb,
+ hook_process);
+ }
+
+ if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]) >= 0)
+ {
+ HOOK_PROCESS(hook_process, hook_fd[HOOK_PROCESS_STDERR]) =
+ hook_fd (hook_process->plugin,
+ HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]),
+ 1, 0, 0,
+ &hook_process_child_read_stderr_cb,
+ hook_process);
+ }
timeout = HOOK_PROCESS(hook_process, timeout);
interval = 100;
@@ -3714,7 +3749,9 @@ hook_add_to_infolist_pointer (struct t_infolist *infolist, struct t_hook *hook)
return 0;
if (!infolist_new_var_string (ptr_item, "options", hashtable_get_string (HOOK_PROCESS(hook, options), "keys_values")))
return 0;
- if (!infolist_new_var_integer (ptr_item, "timeout", HOOK_PROCESS(hook, timeout)))
+ if (!infolist_new_var_integer (ptr_item, "detached", HOOK_PROCESS(hook, detached)))
+ return 0;
+ if (!infolist_new_var_integer (ptr_item, "timeout", (int)(HOOK_PROCESS(hook, timeout))))
return 0;
if (!infolist_new_var_integer (ptr_item, "child_read_stdin", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDIN])))
return 0;
@@ -4196,7 +4233,8 @@ hook_print_log ()
HOOK_PROCESS(ptr_hook, options),
hashtable_get_string (HOOK_PROCESS(ptr_hook, options),
"keys_values"));
- log_printf (" timeout . . . . . . . : %d", HOOK_PROCESS(ptr_hook, timeout));
+ log_printf (" detached. . . . . . . : %d", HOOK_PROCESS(ptr_hook, detached));
+ log_printf (" timeout . . . . . . . : %ld", HOOK_PROCESS(ptr_hook, timeout));
log_printf (" child_read[stdin] . . : %d", HOOK_PROCESS(ptr_hook, child_read[HOOK_PROCESS_STDIN]));
log_printf (" child_write[stdin]. . : %d", HOOK_PROCESS(ptr_hook, child_write[HOOK_PROCESS_STDIN]));
log_printf (" child_read[stdout]. . : %d", HOOK_PROCESS(ptr_hook, child_read[HOOK_PROCESS_STDOUT]));
diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h
index a3a2ce97f..6e3d1b69b 100644
--- a/src/core/wee-hook.h
+++ b/src/core/wee-hook.h
@@ -213,6 +213,7 @@ struct t_hook_process
t_hook_callback_process *callback; /* process callback (after child end)*/
char *command; /* command executed by child */
struct t_hashtable *options; /* options for process (see doc) */
+ int detached; /* detached mode (background) */
long timeout; /* timeout (ms) (0 = no timeout) */
int child_read[3]; /* read stdin/out/err data from child*/
int child_write[3]; /* write stdin/out/err data for child*/