diff options
-rw-r--r-- | ChangeLog.asciidoc | 1 | ||||
-rw-r--r-- | doc/en/weechat_plugin_api.en.asciidoc | 95 | ||||
-rw-r--r-- | doc/fr/weechat_plugin_api.fr.asciidoc | 95 | ||||
-rw-r--r-- | doc/it/weechat_plugin_api.it.asciidoc | 95 | ||||
-rw-r--r-- | doc/ja/weechat_plugin_api.ja.asciidoc | 95 | ||||
-rw-r--r-- | src/core/wee-hook.c | 52 | ||||
-rw-r--r-- | src/core/wee-hook.h | 1 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-main.c | 3 | ||||
-rw-r--r-- | src/plugins/guile/weechat-guile-api.c | 23 | ||||
-rw-r--r-- | src/plugins/javascript/weechat-js-api.cpp | 23 | ||||
-rw-r--r-- | src/plugins/lua/weechat-lua-api.c | 23 | ||||
-rw-r--r-- | src/plugins/perl/weechat-perl-api.c | 23 | ||||
-rw-r--r-- | src/plugins/python/weechat-python-api.c | 23 | ||||
-rw-r--r-- | src/plugins/ruby/weechat-ruby-api.c | 23 | ||||
-rw-r--r-- | src/plugins/tcl/weechat-tcl-api.c | 23 | ||||
-rw-r--r-- | src/plugins/weechat-plugin.h | 11 |
16 files changed, 566 insertions, 43 deletions
diff --git a/ChangeLog.asciidoc b/ChangeLog.asciidoc index 89bf07f72..a352e807a 100644 --- a/ChangeLog.asciidoc +++ b/ChangeLog.asciidoc @@ -32,6 +32,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes] (issue #262) * core: move irc bar item "away" to core, move options "irc.look.item_away_message" and "irc.color.item_away" to core (issue #692) +* api: add support of functions in hook_process * api: add pointer in callbacks used in scripting API (issue #406) * irc: add option irc.network.sasl_fail_unavailable (issue #600, issue #697) * irc: add multiple targets and support of "-server" in command /ctcp diff --git a/doc/en/weechat_plugin_api.en.asciidoc b/doc/en/weechat_plugin_api.en.asciidoc index 7212082ec..a9789cb1f 100644 --- a/doc/en/weechat_plugin_api.en.asciidoc +++ b/doc/en/weechat_plugin_api.en.asciidoc @@ -7517,8 +7517,8 @@ struct t_hook *weechat_hook_process (const char *command, Arguments: -* 'command': command to launch in child process or URL _(WeeChat ≥ 0.3.7)_ - (see below) +* 'command': command to launch in child process, URL _(WeeChat ≥ 0.3.7)_ or + function _(WeeChat ≥ 1.5)_ (see below) * 'timeout': timeout for command (in milliseconds): after this timeout, child process is killed (0 means no timeout) * 'callback': function called when data from child is available, or when child @@ -7533,13 +7533,16 @@ Arguments: **** '2': transfer error **** '3': not enough memory **** '4': error with a file -*** '< 0': 'WEECHAT_HOOK_PROCESS_RUNNING' (data available, but child still - running) or 'WEECHAT_HOOK_PROCESS_ERROR' (error when launching command) +*** '< 0': +**** 'WEECHAT_HOOK_PROCESS_RUNNING': data available, but child still running) +**** 'WEECHAT_HOOK_PROCESS_ERROR': error when launching command +**** 'WEECHAT_HOOK_PROCESS_CHILD': callback is called in the child process ** 'out': standard output of command (stdout) ** 'err': error output of command (stderr) ** return value: *** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_ERROR' +*** child process return code (in case of function with "func:" in command) * 'callback_pointer': pointer given to callback when it is called by WeeChat * 'callback_data': pointer given to callback when it is called by WeeChat; if not NULL, it must have been allocated with malloc (or similar function) @@ -7552,9 +7555,18 @@ Return value: When command has ended, or if timeout is reached, WeeChat will automatically unhook (and kill process if it is still running). -The command can be an URL with format: "url:http://www.example.com", to download -content of URL _(WeeChat ≥ 0.3.7)_. Options are possible for URL with -function <<_hook_process_hashtable,weechat_hook_process_hashtable>>. +The command can be an URL with format: "url:http://www.example.com", +to download content of URL _(WeeChat ≥ 0.3.7)_. Options are possible for URL +with function <<_hook_process_hashtable,weechat_hook_process_hashtable>>. + +The command can also be a function name with format: "func:name", to execute +the function "name" _(WeeChat ≥ 1.5)_. This function receives a single argument +('data') and must return a string, which is sent to the callback. + +In C API, the callback is called with the return code set to +'WEECHAT_HOOK_PROCESS_CHILD', which means the callback is running in the child +process (after fork). + +In scripting API, the function 'name' is called directly and its result +(string) is sent to the callback (like the output of an external command). [TIP] If you want to retrieve infos about WeeChat (like current stable version, @@ -7575,6 +7587,7 @@ C example: [source,C] ---- +/* example with an external command */ int my_process_cb (const void *pointer, void *data, const char *command, int return_code, const char *out, const char *err) @@ -7605,6 +7618,52 @@ my_process_cb (const void *pointer, void *data, const char *command, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000, &my_process_cb, NULL, NULL); + +/* example with the callback called in the child process */ +int +my_process_cb (const void *pointer, void *data, const char *command, + int return_code, const char *out, const char *err) +{ + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + /* do something blocking... */ + /* ... */ + + /* the stdout will be sent as "out" in the parent callback */ + printf ("this is the result"); + + /* return code of the process */ + return 0; + } + else + { + if (return_code == WEECHAT_HOOK_PROCESS_ERROR) + { + weechat_printf (NULL, "Error with command '%s'", command); + return WEECHAT_RC_OK; + } + + if (return_code >= 0) + { + weechat_printf (NULL, "return_code = %d", return_code); + } + + if (out) + { + weechat_printf (NULL, "stdout: %s", out); + } + + if (err) + { + weechat_printf (NULL, "stderr: %s", err); + } + + return WEECHAT_RC_OK; + } +} + +struct t_hook *my_process_hook = weechat_hook_process ("func:get_status", 5000, + &my_process_cb, NULL, NULL); ---- Script (Python): @@ -7614,7 +7673,7 @@ Script (Python): # prototype hook = weechat.hook_process(command, timeout, callback, callback_data) -# example +# example with an external command def my_process_cb(data, command, return_code, out, err): if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: weechat.prnt("", "Error with command '%s'" % command) @@ -7628,6 +7687,26 @@ def my_process_cb(data, command, return_code, out, err): return weechat.WEECHAT_RC_OK hook = weechat.hook_process("ls", 5000, "my_process_cb", "") + +# example with a script function +def get_status(data): + # do something blocking... + # ... + return "this is the result" + +def my_process_cb(data, command, return_code, out, err): + if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: + weechat.prnt("", "Error with command '%s'" % command) + return weechat.WEECHAT_RC_OK + if return_code >= 0: + weechat.prnt("", "return_code = %d" % return_code) + if out != "": + weechat.prnt("", "stdout: %s" % out) + if err != "": + weechat.prnt("", "stderr: %s" % err) + return weechat.WEECHAT_RC_OK + +hook = weechat.hook_process("func:get_status", 5000, "my_process_cb", "") ---- ==== hook_process_hashtable diff --git a/doc/fr/weechat_plugin_api.fr.asciidoc b/doc/fr/weechat_plugin_api.fr.asciidoc index 030f733f9..4f7cd595d 100644 --- a/doc/fr/weechat_plugin_api.fr.asciidoc +++ b/doc/fr/weechat_plugin_api.fr.asciidoc @@ -7654,8 +7654,8 @@ struct t_hook *weechat_hook_process (const char *command, Paramètres : -* 'command' : commande à lancer dans le processus fils ou URL - _(WeeChat ≥ 0.3.7)_ (voir ci-dessous) +* 'command' : commande à lancer dans le processus fils, URL _(WeeChat ≥ 0.3.7)_ + ou fonction _(WeeChat ≥ 1.5)_ (voir ci-dessous) * 'timeout' : timeout pour la commande (en millisecondes) : après ce délai, le processus fils est tué (0 signifie pas de limite) * 'callback' : fonction appelée quand des données du fils sont disponibles, or @@ -7671,14 +7671,19 @@ Paramètres : **** '2' : erreur de transfert **** '3' : pas assez de mémoire **** '4' : erreur avec un fichier -*** '< 0' : 'WEECHAT_HOOK_PROCESS_RUNNING' (données disponibles, mais le - fils tourne toujours) ou 'WEECHAT_HOOK_PROCESS_ERROR' (erreur en lançant - la commande) +*** '< 0' : +**** 'WEECHAT_HOOK_PROCESS_RUNNING' : données disponibles, mais le fils tourne + toujours +**** 'WEECHAT_HOOK_PROCESS_ERROR' : erreur en lançant la commande +**** 'WEECHAT_HOOK_PROCESS_CHILD': le "callback" est appelé dans le processus + fils ** 'out' : sortie standard de la commande (stdout) ** 'err' : erreurs de la commande (stderr) ** valeur de retour : *** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_ERROR' +*** code retour du processus fils (dans le cas d'une fonction avec "func:" dans + la commande) * 'callback_pointer' : pointeur donné au "callback" lorsqu'il est appelé par WeeChat * 'callback_data' : pointeur donné au "callback" lorsqu'il est appelé par @@ -7699,6 +7704,17 @@ pour télécharger le contenu de l'URL _(WeeChat ≥ 0.3.7)_. Des options pour l'URL sont possibles avec la fonction <<_hook_process_hashtable,weechat_hook_process_hashtable>>. +La commande peut aussi être le nom d'une fonction avec le format : "func:nom", +pour exécuter la fonction "nom" _(WeeChat ≥ 1.5)_. Cette fonction reçoit un +paramètre ('data') et doit retourner une chaîne de caractères, qui sera envoyée +au "callback". + +Dans l'API C, le "callback" est appelé avec le code retour qui vaut +'WEECHAT_HOOK_PROCESS_CHILD', cela signifie que le "callback" tourne dans le +processus fils (après le fork). + +Dans l'API script, la fonction 'nom' est appelée directement et le résultat +(chaîne de caractères) est envoyé au "callback" (comme la sortie d'une commande +externe). + [TIP] Si vous souhaitez récupérer des infos à propos de WeeChat (comme la version stable actuelle, le dernier commit git, etc...), vous pouvez utiliser les URLs @@ -7720,6 +7736,7 @@ Exemple en C : [source,C] ---- +/* exemple avec une commande externe */ int my_process_cb (const void *pointer, void *data, const char *command, int return_code, const char *out, const char *err) @@ -7750,6 +7767,52 @@ my_process_cb (const void *pointer, void *data, const char *command, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000, &my_process_cb, NULL, NULL); + +/* exemple avec le "callback" appelé dans le processus fils */ +int +my_process_cb (const void *pointer, void *data, const char *command, + int return_code, const char *out, const char *err) +{ + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + /* faire quelque chose de bloquant... */ + /* ... */ + + /* la sortie "stdout" sera envoyée comme "out" au "callback" parent */ + printf ("ceci est le résultat"); + + /* code retour du processus */ + return 0; + } + else + { + if (return_code == WEECHAT_HOOK_PROCESS_ERROR) + { + weechat_printf (NULL, "Erreur avec la commande '%s'", command); + return WEECHAT_RC_OK; + } + + if (return_code >= 0) + { + weechat_printf (NULL, "return_code = %d", return_code); + } + + if (out) + { + weechat_printf (NULL, "stdout : %s", out); + } + + if (err) + { + weechat_printf (NULL, "stderr : %s", err); + } + + return WEECHAT_RC_OK; + } +} + +struct t_hook *my_process_hook = weechat_hook_process ("func:get_status", 5000, + &my_process_cb, NULL, NULL); ---- Script (Python) : @@ -7759,7 +7822,7 @@ Script (Python) : # prototype hook = weechat.hook_process(command, timeout, callback, callback_data) -# exemple +# exemple avec une commande externe def my_process_cb(data, command, return_code, out, err): if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: weechat.prnt("", "Erreur avec la commande '%s'" % command) @@ -7773,6 +7836,26 @@ def my_process_cb(data, command, return_code, out, err): return weechat.WEECHAT_RC_OK hook = weechat.hook_process("ls", 5000, "my_process_cb", "") + +# exemple avec une fonction du script +def get_status(data): + # faire quelque chose de bloquant... + # ... + return "ceci est le résultat" + +def my_process_cb(data, command, return_code, out, err): + if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: + weechat.prnt("", "Erreur avec la commande '%s'" % command) + return weechat.WEECHAT_RC_OK + if return_code >= 0: + weechat.prnt("", "return_code = %d" % return_code) + if out != "": + weechat.prnt("", "stdout : %s" % out) + if err != "": + weechat.prnt("", "stderr : %s" % err) + return weechat.WEECHAT_RC_OK + +hook = weechat.hook_process("func:get_status", 5000, "my_process_cb", "") ---- ==== hook_process_hashtable diff --git a/doc/it/weechat_plugin_api.it.asciidoc b/doc/it/weechat_plugin_api.it.asciidoc index 641303e62..3b006c07d 100644 --- a/doc/it/weechat_plugin_api.it.asciidoc +++ b/doc/it/weechat_plugin_api.it.asciidoc @@ -7718,8 +7718,9 @@ struct t_hook *weechat_hook_process (const char *command, Argomenti: -* 'command': comando da avviare nel processo figlio o URL - _(WeeChat ≥ 0.3.7)_, segue: +// TRANSLATION MISSING +* 'command': command to launch in child process, URL _(WeeChat ≥ 0.3.7)_ or + function _(WeeChat ≥ 1.5)_ (see below) * 'timeout': timeout per il comando (in millisecondi): dopo questo timeout, il processo figlio viene terminato (0 indica nessun timeout) * 'callback': funzione chiamata quando i dati dal processo figlio sono disponibili, @@ -7735,14 +7736,19 @@ Argomenti: **** '2': errore di trasferimento **** '3': memoria non sufficiente **** '4': errore con un file -*** '< 0': 'WEECHAT_HOOK_PROCESS_RUNNING' (dati disponibili, ma figlio - ancora in esecuzione) o 'WEECHAT_HOOK_PROCESS_ERROR' (errore nella - esecuzione del comando) +*** '< 0': +**** 'WEECHAT_HOOK_PROCESS_RUNNING': dati disponibili, ma figlio ancora in + esecuzione) +**** 'WEECHAT_HOOK_PROCESS_ERROR': errore nella esecuzione del comando +// TRANSLATION MISSING +**** 'WEECHAT_HOOK_PROCESS_CHILD': callback is called in the child process ** 'out': output standard del comando (stdout) ** 'err': output di errore del comando (stderr) ** valore restituito: *** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_ERROR' +// TRANSLATION MISSING +*** child process return code (in case of function with "func:" in command) * 'callback_pointer': puntatore fornito alla callback quando chiamata da WeeChat // TRANSLATION MISSING * 'callback_data': puntatore fornito alla callback quando chiamata da WeeChat; @@ -7762,6 +7768,16 @@ un URL sono disponibili con la funzione <<_hook_process_hashtable,weechat_hook_process_hashtable>>. // TRANSLATION MISSING +The command can also be a function name with format: "func:name", to execute +the function "name" _(WeeChat ≥ 1.5)_. This function receives a single argument +('data') and must return a string, which is sent to the callback. + +In C API, the callback is called with the return code set to +'WEECHAT_HOOK_PROCESS_CHILD', which means the callback is running in the child +process (after fork). + +In scripting API, the function 'name' is called directly and its result +(string) is sent to the callback (like the output of an external command). + +// TRANSLATION MISSING [TIP] If you want to retrieve infos about WeeChat (like current stable version, latest git commit, ...), you can use URLs on page https://weechat.org/dev/info @@ -7782,6 +7798,7 @@ Esempio in C: [source,C] ---- +/* example with an external command */ int my_process_cb (const void *pointer, void *data, const char *command, int return_code, const char *out, const char *err) @@ -7812,6 +7829,52 @@ my_process_cb (const void *pointer, void *data, const char *command, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000, &my_process_cb, NULL, NULL); + +/* example with the callback called in the child process */ +int +my_process_cb (const void *pointer, void *data, const char *command, + int return_code, const char *out, const char *err) +{ + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + /* do something blocking... */ + /* ... */ + + /* the stdout will be sent as "out" in the parent callback */ + printf ("this is the result"); + + /* return code of the process */ + return 0; + } + else + { + if (return_code == WEECHAT_HOOK_PROCESS_ERROR) + { + weechat_printf (NULL, "Error with command '%s'", command); + return WEECHAT_RC_OK; + } + + if (return_code >= 0) + { + weechat_printf (NULL, "return_code = %d", return_code); + } + + if (out) + { + weechat_printf (NULL, "stdout: %s", out); + } + + if (err) + { + weechat_printf (NULL, "stderr: %s", err); + } + + return WEECHAT_RC_OK; + } +} + +struct t_hook *my_process_hook = weechat_hook_process ("func:get_status", 5000, + &my_process_cb, NULL, NULL); ---- Script (Python): @@ -7821,7 +7884,7 @@ Script (Python): # prototipo hook = weechat.hook_process(command, timeout, callback, callback_data) -# esempio +# example with an external command def my_process_cb(data, command, return_code, out, err): if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: weechat.prnt("", "Error with command '%s'" % command) @@ -7835,6 +7898,26 @@ def my_process_cb(data, command, return_code, out, err): return weechat.WEECHAT_RC_OK hook = weechat.hook_process("ls", 5000, "my_process_cb", "") + +# example with a script function +def get_status(data): + # do something blocking... + # ... + return "this is the result" + +def my_process_cb(data, command, return_code, out, err): + if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: + weechat.prnt("", "Error with command '%s'" % command) + return weechat.WEECHAT_RC_OK + if return_code >= 0: + weechat.prnt("", "return_code = %d" % return_code) + if out != "": + weechat.prnt("", "stdout: %s" % out) + if err != "": + weechat.prnt("", "stderr: %s" % err) + return weechat.WEECHAT_RC_OK + +hook = weechat.hook_process("func:get_status", 5000, "my_process_cb", "") ---- ==== hook_process_hashtable diff --git a/doc/ja/weechat_plugin_api.ja.asciidoc b/doc/ja/weechat_plugin_api.ja.asciidoc index d544da27c..693ef2ccf 100644 --- a/doc/ja/weechat_plugin_api.ja.asciidoc +++ b/doc/ja/weechat_plugin_api.ja.asciidoc @@ -7515,8 +7515,9 @@ struct t_hook *weechat_hook_process (const char *command, 引数: -* 'command': 子プロセスで実行するコマンドまたは - URL _(WeeChat バージョン 0.3.7 以上で利用可)_ (以下を参照) +// TRANSLATION MISSING +* 'command': command to launch in child process, URL _(WeeChat ≥ 0.3.7)_ or + function _(WeeChat ≥ 1.5)_ (see below) * 'timeout': コマンドのタイムアウト (ミリ秒): このタイムアウトを過ぎたら、子プロセスを kill します (タイムアウトさせない場合は 0) * 'callback': @@ -7531,13 +7532,20 @@ struct t_hook *weechat_hook_process (const char *command, **** '2': 転送エラー **** '3': メモリ不足 **** '4': ファイルに関するエラー -*** '< 0': 'WEECHAT_HOOK_PROCESS_RUNNING' (データは利用可能だが子プロセスは終了していない) - または 'WEECHAT_HOOK_PROCESS_ERROR' (コマンドの実行中にエラー) +*** '< 0': +// TRANSLATION MISSING +**** 'WEECHAT_HOOK_PROCESS_RUNNING': data available, but child still running) +// TRANSLATION MISSING +**** 'WEECHAT_HOOK_PROCESS_ERROR': error when launching command +// TRANSLATION MISSING +**** 'WEECHAT_HOOK_PROCESS_CHILD': callback is called in the child process ** 'out': コマンドの標準出力 (stdout) ** 'err': コマンドの標準エラー出力 (stderr) ** 戻り値: *** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_ERROR' +// TRANSLATION MISSING +*** child process return code (in case of function with "func:" in command) * 'callback_pointer': WeeChat が 'callback' コールバックを呼び出す際にコールバックに渡すポインタ * 'callback_data': WeeChat が 'callback' コールバックを呼び出す際にコールバックに渡すポインタ; このポインタが NULL でない場合、このポインタは malloc (または類似の関数) @@ -7554,6 +7562,16 @@ struct t_hook *weechat_hook_process (const char *command, の内容がダウンロードされます _(WeeChat バージョン 0.3.7 以上で利用可)_ 。<<_hook_process_hashtable,weechat_hook_process_hashtable>> 関数を使えば URL に対してオプションを与えることもできます。 +// TRANSLATION MISSING +The command can also be a function name with format: "func:name", to execute +the function "name" _(WeeChat ≥ 1.5)_. This function receives a single argument +('data') and must return a string, which is sent to the callback. + +In C API, the callback is called with the return code set to +'WEECHAT_HOOK_PROCESS_CHILD', which means the callback is running in the child +process (after fork). + +In scripting API, the function 'name' is called directly and its result +(string) is sent to the callback (like the output of an external command). + [TIP] WeeChat に関する情報 (例えば現在の安定版、最新の git コミット、...) が欲しい場合、https://weechat.org/dev/info に書かれている URL を使ってください @@ -7573,6 +7591,7 @@ C 言語での使用例: [source,C] ---- +/* example with an external command */ int my_process_cb (const void *pointer, void *data, const char *command, int return_code, const char *out, const char *err) @@ -7603,6 +7622,52 @@ my_process_cb (const void *pointer, void *data, const char *command, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000, &my_process_cb, NULL, NULL); + +/* example with the callback called in the child process */ +int +my_process_cb (const void *pointer, void *data, const char *command, + int return_code, const char *out, const char *err) +{ + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + /* do something blocking... */ + /* ... */ + + /* the stdout will be sent as "out" in the parent callback */ + printf ("this is the result"); + + /* return code of the process */ + return 0; + } + else + { + if (return_code == WEECHAT_HOOK_PROCESS_ERROR) + { + weechat_printf (NULL, "Error with command '%s'", command); + return WEECHAT_RC_OK; + } + + if (return_code >= 0) + { + weechat_printf (NULL, "return_code = %d", return_code); + } + + if (out) + { + weechat_printf (NULL, "stdout: %s", out); + } + + if (err) + { + weechat_printf (NULL, "stderr: %s", err); + } + + return WEECHAT_RC_OK; + } +} + +struct t_hook *my_process_hook = weechat_hook_process ("func:get_status", 5000, + &my_process_cb, NULL, NULL); ---- スクリプト (Python) での使用例: @@ -7612,7 +7677,7 @@ struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000, # プロトタイプ hook = weechat.hook_process(command, timeout, callback, callback_data) -# 例 +# example with an external command def my_process_cb(data, command, return_code, out, err): if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: weechat.prnt("", "Error with command '%s'" % command) @@ -7626,6 +7691,26 @@ def my_process_cb(data, command, return_code, out, err): return weechat.WEECHAT_RC_OK hook = weechat.hook_process("ls", 5000, "my_process_cb", "") + +# example with a script function +def get_status(data): + # do something blocking... + # ... + return "this is the result" + +def my_process_cb(data, command, return_code, out, err): + if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: + weechat.prnt("", "Error with command '%s'" % command) + return weechat.WEECHAT_RC_OK + if return_code >= 0: + weechat.prnt("", "return_code = %d" % return_code) + if out != "": + weechat.prnt("", "stdout: %s" % out) + if err != "": + weechat.prnt("", "stderr: %s" % err) + return weechat.WEECHAT_RC_OK + +hook = weechat.hook_process("func:get_status", 5000, "my_process_cb", "") ---- ==== hook_process_hashtable diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index dd33e4bbb..40396facc 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -76,6 +76,8 @@ int real_delete_pending = 0; /* 1 if some hooks must be deleted */ struct pollfd *hook_fd_pollfd = NULL; /* file descriptors for poll() */ int hook_fd_pollfd_count = 0; /* number of file descriptors */ +int hook_process_pending = 0; /* 1 if there are some process to */ + /* run (via fork) */ void hook_process_run (struct t_hook *hook_process); @@ -1405,6 +1407,8 @@ hook_fd_exec () /* perform the poll() */ timeout = hook_timer_get_time_to_next (); + if (hook_process_pending) + timeout = 0; ready = poll (hook_fd_pollfd, num_fd, timeout); if (ready <= 0) return; @@ -1547,7 +1551,10 @@ hook_process_hashtable (struct t_weechat_plugin *plugin, new_hook_process->timeout); } - hook_process_run (new_hook); + if (strncmp (new_hook_process->command, "func:", 5) == 0) + hook_process_pending = 1; + else + hook_process_run (new_hook); return new_hook; @@ -1656,6 +1663,16 @@ hook_process_child (struct t_hook *hook_process) } rc = weeurl_download (ptr_url, HOOK_PROCESS(hook_process, options)); } + else if (strncmp (HOOK_PROCESS(hook_process, command), "func:", 5) == 0) + { + /* run a function (via the hook callback) */ + rc = (int) (HOOK_PROCESS(hook_process, callback)) + (hook_process->callback_pointer, + hook_process->callback_data, + HOOK_PROCESS(hook_process, command), + WEECHAT_HOOK_PROCESS_CHILD, + NULL, NULL); + } else { /* launch command */ @@ -2143,6 +2160,39 @@ error: } /* + * Executes all process commands pending. + */ + +void +hook_process_exec () +{ + struct t_hook *ptr_hook, *next_hook; + + hook_exec_start (); + + ptr_hook = weechat_hooks[HOOK_TYPE_PROCESS]; + while (ptr_hook) + { + next_hook = ptr_hook->next_hook; + + if (!ptr_hook->deleted + && !ptr_hook->running + && (HOOK_PROCESS(ptr_hook, child_pid) == 0)) + { + ptr_hook->running = 1; + hook_process_run (ptr_hook); + ptr_hook->running = 0; + } + + ptr_hook = next_hook; + } + + hook_exec_end (); + + hook_process_pending = 0; +} + +/* * Hooks a connection to a peer (using fork). * * Returns pointer to new hook, NULL if error. diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h index 32e8e2947..cdbba4027 100644 --- a/src/core/wee-hook.h +++ b/src/core/wee-hook.h @@ -505,6 +505,7 @@ extern struct t_hook *hook_process_hashtable (struct t_weechat_plugin *plugin, t_hook_callback_process *callback, const void *callback_pointer, void *callback_data); +extern void hook_process_exec (); extern struct t_hook *hook_connect (struct t_weechat_plugin *plugin, const char *proxy, const char *address, int port, int ipv6, int retry, diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c index cc865666b..8407f8c63 100644 --- a/src/gui/curses/gui-curses-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -422,6 +422,9 @@ gui_main_loop () /* execute fd hooks */ hook_fd_exec (); + + /* run process (with fork) */ + hook_process_exec (); } /* remove keyboard hook */ diff --git a/src/plugins/guile/weechat-guile-api.c b/src/plugins/guile/weechat-guile-api.c index 32676fbd5..acf0f8080 100644 --- a/src/plugins/guile/weechat-guile-api.c +++ b/src/plugins/guile/weechat-guile-api.c @@ -2171,14 +2171,33 @@ weechat_guile_api_hook_process_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[5]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; int *rc, ret; script = (struct t_plugin_script *)pointer; plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); - if (ptr_function && ptr_function[0]) + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + if (strncmp (command, "func:", 5) == 0) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + + result = (char *) weechat_guile_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + command + 5, + "s", func_argv); + if (result) + { + printf ("%s", result); + free (result); + return 0; + } + } + return 1; + } + else if (ptr_function && ptr_function[0]) { func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg; diff --git a/src/plugins/javascript/weechat-js-api.cpp b/src/plugins/javascript/weechat-js-api.cpp index e2cad59f4..4a09b130b 100644 --- a/src/plugins/javascript/weechat-js-api.cpp +++ b/src/plugins/javascript/weechat-js-api.cpp @@ -2085,14 +2085,33 @@ weechat_js_api_hook_process_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[5]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; int *rc, ret; script = (struct t_plugin_script *)pointer; plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); - if (ptr_function && ptr_function[0]) + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + if (strncmp (command, "func:", 5) == 0) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + + result = (char *) weechat_js_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + command + 5, + "s", func_argv); + if (result) + { + printf ("%s", result); + free (result); + return 0; + } + } + return 1; + } + else if (ptr_function && ptr_function[0]) { func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg; diff --git a/src/plugins/lua/weechat-lua-api.c b/src/plugins/lua/weechat-lua-api.c index 893424034..ba75aad74 100644 --- a/src/plugins/lua/weechat-lua-api.c +++ b/src/plugins/lua/weechat-lua-api.c @@ -2268,14 +2268,33 @@ weechat_lua_api_hook_process_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[5]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; int *rc, ret; script = (struct t_plugin_script *)pointer; plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); - if (ptr_function && ptr_function[0]) + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + if (strncmp (command, "func:", 5) == 0) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + + result = (char *) weechat_lua_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + command + 5, + "s", func_argv); + if (result) + { + printf ("%s", result); + free (result); + return 0; + } + } + return 1; + } + else if (ptr_function && ptr_function[0]) { func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg; diff --git a/src/plugins/perl/weechat-perl-api.c b/src/plugins/perl/weechat-perl-api.c index 267d1982d..4233f70c6 100644 --- a/src/plugins/perl/weechat-perl-api.c +++ b/src/plugins/perl/weechat-perl-api.c @@ -2198,14 +2198,33 @@ weechat_perl_api_hook_process_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[5]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; int *rc, ret; script = (struct t_plugin_script *)pointer; plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); - if (ptr_function && ptr_function[0]) + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + if (strncmp (command, "func:", 5) == 0) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + + result = (char *) weechat_perl_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + command + 5, + "s", func_argv); + if (result) + { + printf ("%s", result); + free (result); + return 0; + } + } + return 1; + } + else if (ptr_function && ptr_function[0]) { func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg; diff --git a/src/plugins/python/weechat-python-api.c b/src/plugins/python/weechat-python-api.c index fc9d05409..23acaba0b 100644 --- a/src/plugins/python/weechat-python-api.c +++ b/src/plugins/python/weechat-python-api.c @@ -2208,14 +2208,33 @@ weechat_python_api_hook_process_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[5]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; int *rc, ret; script = (struct t_plugin_script *)pointer; plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); - if (ptr_function && ptr_function[0]) + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + if (strncmp (command, "func:", 5) == 0) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + + result = (char *) weechat_python_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + command + 5, + "s", func_argv); + if (result) + { + printf ("%s", result); + free (result); + return 0; + } + } + return 1; + } + else if (ptr_function && ptr_function[0]) { func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg; diff --git a/src/plugins/ruby/weechat-ruby-api.c b/src/plugins/ruby/weechat-ruby-api.c index e3c57e385..9b705afba 100644 --- a/src/plugins/ruby/weechat-ruby-api.c +++ b/src/plugins/ruby/weechat-ruby-api.c @@ -2682,14 +2682,33 @@ weechat_ruby_api_hook_process_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[5]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; int *rc, ret; script = (struct t_plugin_script *)pointer; plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); - if (ptr_function && ptr_function[0]) + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + if (strncmp (command, "func:", 5) == 0) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + + result = (char *) weechat_ruby_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + command + 5, + "s", func_argv); + if (result) + { + printf ("%s", result); + free (result); + return 0; + } + } + return 1; + } + else if (ptr_function && ptr_function[0]) { func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg; diff --git a/src/plugins/tcl/weechat-tcl-api.c b/src/plugins/tcl/weechat-tcl-api.c index 078afd169..75db35ab3 100644 --- a/src/plugins/tcl/weechat-tcl-api.c +++ b/src/plugins/tcl/weechat-tcl-api.c @@ -2450,14 +2450,33 @@ weechat_tcl_api_hook_process_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[5]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; int *rc, ret; script = (struct t_plugin_script *)pointer; plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); - if (ptr_function && ptr_function[0]) + if (return_code == WEECHAT_HOOK_PROCESS_CHILD) + { + if (strncmp (command, "func:", 5) == 0) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + + result = (char *) weechat_tcl_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + command + 5, + "s", func_argv); + if (result) + { + printf ("%s", result); + free (result); + return 0; + } + } + return 1; + } + else if (ptr_function && ptr_function[0]) { func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg; diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index 53171b920..ece4de71d 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -57,7 +57,7 @@ struct timeval; * please change the date with current one; for a second change at same * date, increment the 01, otherwise please keep 01. */ -#define WEECHAT_PLUGIN_API_VERSION "20160324-01" +#define WEECHAT_PLUGIN_API_VERSION "20160423-01" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -138,11 +138,16 @@ struct timeval; /* * process return code (for callback): - * if >= 0, then process ended and it's return code of command - * if < 0, then it's running or error + * if >= 0, the process ended and it's return code of command + * if -1, the process is still running + * if -2, the process ended with an error + * if -3, the callback is called in the child process (exec of function) + * (note: the return code -3 is NEVER sent to script plugins, + * it can be used only in C API) */ #define WEECHAT_HOOK_PROCESS_RUNNING -1 #define WEECHAT_HOOK_PROCESS_ERROR -2 +#define WEECHAT_HOOK_PROCESS_CHILD -3 /* connect status for connection hooked */ #define WEECHAT_HOOK_CONNECT_OK 0 |