api: add support of functions in hook_process

This commit is contained in:
Sébastien Helleu 2016-04-23 13:59:20 +02:00
parent ae89d28462
commit 51c3e0b9ec
16 changed files with 566 additions and 43 deletions

View File

@ -32,6 +32,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
(issue #262) (issue #262)
* core: move irc bar item "away" to core, move options * core: move irc bar item "away" to core, move options
"irc.look.item_away_message" and "irc.color.item_away" to core (issue #692) "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) * 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 option irc.network.sasl_fail_unavailable (issue #600, issue #697)
* irc: add multiple targets and support of "-server" in command /ctcp * irc: add multiple targets and support of "-server" in command /ctcp

View File

@ -7517,8 +7517,8 @@ struct t_hook *weechat_hook_process (const char *command,
Arguments: Arguments:
* 'command': command to launch in child process or URL _(WeeChat ≥ 0.3.7)_ * 'command': command to launch in child process, URL _(WeeChat ≥ 0.3.7)_ or
(see below) function _(WeeChat ≥ 1.5)_ (see below)
* 'timeout': timeout for command (in milliseconds): after this timeout, child * 'timeout': timeout for command (in milliseconds): after this timeout, child
process is killed (0 means no timeout) process is killed (0 means no timeout)
* 'callback': function called when data from child is available, or when child * 'callback': function called when data from child is available, or when child
@ -7533,13 +7533,16 @@ Arguments:
**** '2': transfer error **** '2': transfer error
**** '3': not enough memory **** '3': not enough memory
**** '4': error with a file **** '4': error with a file
*** '< 0': 'WEECHAT_HOOK_PROCESS_RUNNING' (data available, but child still *** '< 0':
running) or 'WEECHAT_HOOK_PROCESS_ERROR' (error when launching command) **** '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) ** 'out': standard output of command (stdout)
** 'err': error output of command (stderr) ** 'err': error output of command (stderr)
** return value: ** return value:
*** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_OK'
*** 'WEECHAT_RC_ERROR' *** '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_pointer': pointer given to callback when it is called by WeeChat
* 'callback_data': 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) 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 When command has ended, or if timeout is reached, WeeChat will automatically
unhook (and kill process if it is still running). unhook (and kill process if it is still running).
The command can be an URL with format: "url:http://www.example.com", to download The command can be an URL with format: "url:http://www.example.com",
content of URL _(WeeChat ≥ 0.3.7)_. Options are possible for URL with to download content of URL _(WeeChat ≥ 0.3.7)_. Options are possible for URL
function <<_hook_process_hashtable,weechat_hook_process_hashtable>>. 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] [TIP]
If you want to retrieve infos about WeeChat (like current stable version, If you want to retrieve infos about WeeChat (like current stable version,
@ -7575,6 +7587,7 @@ C example:
[source,C] [source,C]
---- ----
/* example with an external command */
int int
my_process_cb (const void *pointer, void *data, const char *command, my_process_cb (const void *pointer, void *data, const char *command,
int return_code, const char *out, const char *err) 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, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000,
&my_process_cb, NULL, NULL); &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): Script (Python):
@ -7614,7 +7673,7 @@ Script (Python):
# prototype # prototype
hook = weechat.hook_process(command, timeout, callback, callback_data) 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): def my_process_cb(data, command, return_code, out, err):
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR:
weechat.prnt("", "Error with command '%s'" % command) 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 return weechat.WEECHAT_RC_OK
hook = weechat.hook_process("ls", 5000, "my_process_cb", "") 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 ==== hook_process_hashtable

View File

@ -7654,8 +7654,8 @@ struct t_hook *weechat_hook_process (const char *command,
Paramètres : Paramètres :
* 'command' : commande à lancer dans le processus fils ou URL * 'command' : commande à lancer dans le processus fils, URL _(WeeChat ≥ 0.3.7)_
_(WeeChat ≥ 0.3.7)_ (voir ci-dessous) ou fonction _(WeeChat ≥ 1.5)_ (voir ci-dessous)
* 'timeout' : timeout pour la commande (en millisecondes) : après ce délai, le * 'timeout' : timeout pour la commande (en millisecondes) : après ce délai, le
processus fils est tué (0 signifie pas de limite) processus fils est tué (0 signifie pas de limite)
* 'callback' : fonction appelée quand des données du fils sont disponibles, or * 'callback' : fonction appelée quand des données du fils sont disponibles, or
@ -7671,14 +7671,19 @@ Paramètres :
**** '2' : erreur de transfert **** '2' : erreur de transfert
**** '3' : pas assez de mémoire **** '3' : pas assez de mémoire
**** '4' : erreur avec un fichier **** '4' : erreur avec un fichier
*** '< 0' : 'WEECHAT_HOOK_PROCESS_RUNNING' (données disponibles, mais le *** '< 0' :
fils tourne toujours) ou 'WEECHAT_HOOK_PROCESS_ERROR' (erreur en lançant **** 'WEECHAT_HOOK_PROCESS_RUNNING' : données disponibles, mais le fils tourne
la commande) 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) ** 'out' : sortie standard de la commande (stdout)
** 'err' : erreurs de la commande (stderr) ** 'err' : erreurs de la commande (stderr)
** valeur de retour : ** valeur de retour :
*** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_OK'
*** 'WEECHAT_RC_ERROR' *** '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 * 'callback_pointer' : pointeur donné au "callback" lorsqu'il est appelé par
WeeChat WeeChat
* 'callback_data' : pointeur donné au "callback" lorsqu'il est appelé par * '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 Des options pour l'URL sont possibles avec la fonction
<<_hook_process_hashtable,weechat_hook_process_hashtable>>. <<_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] [TIP]
Si vous souhaitez récupérer des infos à propos de WeeChat (comme la version 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 stable actuelle, le dernier commit git, etc...), vous pouvez utiliser les URLs
@ -7720,6 +7736,7 @@ Exemple en C :
[source,C] [source,C]
---- ----
/* exemple avec une commande externe */
int int
my_process_cb (const void *pointer, void *data, const char *command, my_process_cb (const void *pointer, void *data, const char *command,
int return_code, const char *out, const char *err) 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, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000,
&my_process_cb, NULL, NULL); &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) : Script (Python) :
@ -7759,7 +7822,7 @@ Script (Python) :
# prototype # prototype
hook = weechat.hook_process(command, timeout, callback, callback_data) 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): def my_process_cb(data, command, return_code, out, err):
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR:
weechat.prnt("", "Erreur avec la commande '%s'" % command) 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 return weechat.WEECHAT_RC_OK
hook = weechat.hook_process("ls", 5000, "my_process_cb", "") 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 ==== hook_process_hashtable

View File

@ -7718,8 +7718,9 @@ struct t_hook *weechat_hook_process (const char *command,
Argomenti: Argomenti:
* 'command': comando da avviare nel processo figlio o URL // TRANSLATION MISSING
_(WeeChat ≥ 0.3.7)_, segue: * '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, * 'timeout': timeout per il comando (in millisecondi): dopo questo timeout,
il processo figlio viene terminato (0 indica nessun timeout) il processo figlio viene terminato (0 indica nessun timeout)
* 'callback': funzione chiamata quando i dati dal processo figlio sono disponibili, * 'callback': funzione chiamata quando i dati dal processo figlio sono disponibili,
@ -7735,14 +7736,19 @@ Argomenti:
**** '2': errore di trasferimento **** '2': errore di trasferimento
**** '3': memoria non sufficiente **** '3': memoria non sufficiente
**** '4': errore con un file **** '4': errore con un file
*** '< 0': 'WEECHAT_HOOK_PROCESS_RUNNING' (dati disponibili, ma figlio *** '< 0':
ancora in esecuzione) o 'WEECHAT_HOOK_PROCESS_ERROR' (errore nella **** 'WEECHAT_HOOK_PROCESS_RUNNING': dati disponibili, ma figlio ancora in
esecuzione del comando) 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) ** 'out': output standard del comando (stdout)
** 'err': output di errore del comando (stderr) ** 'err': output di errore del comando (stderr)
** valore restituito: ** valore restituito:
*** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_OK'
*** 'WEECHAT_RC_ERROR' *** '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 * 'callback_pointer': puntatore fornito alla callback quando chiamata da WeeChat
// TRANSLATION MISSING // TRANSLATION MISSING
* 'callback_data': puntatore fornito alla callback quando chiamata da WeeChat; * 'callback_data': puntatore fornito alla callback quando chiamata da WeeChat;
@ -7761,6 +7767,16 @@ scaricare il contenuto dell'URL _(WeeChat ≥ 0.3.7)_. Le opzioni per
un URL sono disponibili con la funzione un URL sono disponibili con la funzione
<<_hook_process_hashtable,weechat_hook_process_hashtable>>. <<_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 // TRANSLATION MISSING
[TIP] [TIP]
If you want to retrieve infos about WeeChat (like current stable version, If you want to retrieve infos about WeeChat (like current stable version,
@ -7782,6 +7798,7 @@ Esempio in C:
[source,C] [source,C]
---- ----
/* example with an external command */
int int
my_process_cb (const void *pointer, void *data, const char *command, my_process_cb (const void *pointer, void *data, const char *command,
int return_code, const char *out, const char *err) 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, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000,
&my_process_cb, NULL, NULL); &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): Script (Python):
@ -7821,7 +7884,7 @@ Script (Python):
# prototipo # prototipo
hook = weechat.hook_process(command, timeout, callback, callback_data) 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): def my_process_cb(data, command, return_code, out, err):
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR:
weechat.prnt("", "Error with command '%s'" % command) 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 return weechat.WEECHAT_RC_OK
hook = weechat.hook_process("ls", 5000, "my_process_cb", "") 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 ==== hook_process_hashtable

View File

@ -7515,8 +7515,9 @@ struct t_hook *weechat_hook_process (const char *command,
引数: 引数:
* 'command': 子プロセスで実行するコマンドまたは // TRANSLATION MISSING
URL _(WeeChat バージョン 0.3.7 以上で利用可)_ (以下を参照) * 'command': command to launch in child process, URL _(WeeChat ≥ 0.3.7)_ or
function _(WeeChat ≥ 1.5)_ (see below)
* 'timeout': コマンドのタイムアウト (ミリ秒): * 'timeout': コマンドのタイムアウト (ミリ秒):
このタイムアウトを過ぎたら、子プロセスを kill します (タイムアウトさせない場合は 0) このタイムアウトを過ぎたら、子プロセスを kill します (タイムアウトさせない場合は 0)
* 'callback': * 'callback':
@ -7531,13 +7532,20 @@ struct t_hook *weechat_hook_process (const char *command,
**** '2': 転送エラー **** '2': 転送エラー
**** '3': メモリ不足 **** '3': メモリ不足
**** '4': ファイルに関するエラー **** '4': ファイルに関するエラー
*** '< 0': 'WEECHAT_HOOK_PROCESS_RUNNING' (データは利用可能だが子プロセスは終了していない) *** '< 0':
または 'WEECHAT_HOOK_PROCESS_ERROR' (コマンドの実行中にエラー) // 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) ** 'out': コマンドの標準出力 (stdout)
** 'err': コマンドの標準エラー出力 (stderr) ** 'err': コマンドの標準エラー出力 (stderr)
** 戻り値: ** 戻り値:
*** 'WEECHAT_RC_OK' *** 'WEECHAT_RC_OK'
*** 'WEECHAT_RC_ERROR' *** 'WEECHAT_RC_ERROR'
// TRANSLATION MISSING
*** child process return code (in case of function with "func:" in command)
* 'callback_pointer': WeeChat が 'callback' コールバックを呼び出す際にコールバックに渡すポインタ * 'callback_pointer': WeeChat が 'callback' コールバックを呼び出す際にコールバックに渡すポインタ
* 'callback_data': WeeChat が 'callback' コールバックを呼び出す際にコールバックに渡すポインタ; * 'callback_data': WeeChat が 'callback' コールバックを呼び出す際にコールバックに渡すポインタ;
このポインタが NULL でない場合、このポインタは malloc (または類似の関数) このポインタが 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>> の内容がダウンロードされます _(WeeChat バージョン 0.3.7 以上で利用可)_ 。<<_hook_process_hashtable,weechat_hook_process_hashtable>>
関数を使えば URL に対してオプションを与えることもできます。 関数を使えば 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] [TIP]
WeeChat に関する情報 (例えば現在の安定版、最新の git コミット、...) WeeChat に関する情報 (例えば現在の安定版、最新の git コミット、...)
が欲しい場合、https://weechat.org/dev/info に書かれている URL を使ってください が欲しい場合、https://weechat.org/dev/info に書かれている URL を使ってください
@ -7573,6 +7591,7 @@ C 言語での使用例:
[source,C] [source,C]
---- ----
/* example with an external command */
int int
my_process_cb (const void *pointer, void *data, const char *command, my_process_cb (const void *pointer, void *data, const char *command,
int return_code, const char *out, const char *err) 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, struct t_hook *my_process_hook = weechat_hook_process ("ls", 5000,
&my_process_cb, NULL, NULL); &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) での使用例: スクリプト (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) hook = weechat.hook_process(command, timeout, callback, callback_data)
# # example with an external command
def my_process_cb(data, command, return_code, out, err): def my_process_cb(data, command, return_code, out, err):
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR:
weechat.prnt("", "Error with command '%s'" % command) 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 return weechat.WEECHAT_RC_OK
hook = weechat.hook_process("ls", 5000, "my_process_cb", "") 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 ==== hook_process_hashtable

View File

@ -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() */ struct pollfd *hook_fd_pollfd = NULL; /* file descriptors for poll() */
int hook_fd_pollfd_count = 0; /* number of file descriptors */ 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); void hook_process_run (struct t_hook *hook_process);
@ -1405,6 +1407,8 @@ hook_fd_exec ()
/* perform the poll() */ /* perform the poll() */
timeout = hook_timer_get_time_to_next (); timeout = hook_timer_get_time_to_next ();
if (hook_process_pending)
timeout = 0;
ready = poll (hook_fd_pollfd, num_fd, timeout); ready = poll (hook_fd_pollfd, num_fd, timeout);
if (ready <= 0) if (ready <= 0)
return; return;
@ -1547,7 +1551,10 @@ hook_process_hashtable (struct t_weechat_plugin *plugin,
new_hook_process->timeout); 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; 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)); 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 else
{ {
/* launch command */ /* launch command */
@ -2142,6 +2159,39 @@ error:
unhook (hook_process); unhook (hook_process);
} }
/*
* 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). * Hooks a connection to a peer (using fork).
* *

View File

@ -505,6 +505,7 @@ extern struct t_hook *hook_process_hashtable (struct t_weechat_plugin *plugin,
t_hook_callback_process *callback, t_hook_callback_process *callback,
const void *callback_pointer, const void *callback_pointer,
void *callback_data); void *callback_data);
extern void hook_process_exec ();
extern struct t_hook *hook_connect (struct t_weechat_plugin *plugin, extern struct t_hook *hook_connect (struct t_weechat_plugin *plugin,
const char *proxy, const char *address, const char *proxy, const char *address,
int port, int ipv6, int retry, int port, int ipv6, int retry,

View File

@ -422,6 +422,9 @@ gui_main_loop ()
/* execute fd hooks */ /* execute fd hooks */
hook_fd_exec (); hook_fd_exec ();
/* run process (with fork) */
hook_process_exec ();
} }
/* remove keyboard hook */ /* remove keyboard hook */

View File

@ -2171,14 +2171,33 @@ weechat_guile_api_hook_process_cb (const void *pointer, void *data,
{ {
struct t_plugin_script *script; struct t_plugin_script *script;
void *func_argv[5]; void *func_argv[5];
char empty_arg[1] = { '\0' }; char empty_arg[1] = { '\0' }, *result;
const char *ptr_function, *ptr_data; const char *ptr_function, *ptr_data;
int *rc, ret; int *rc, ret;
script = (struct t_plugin_script *)pointer; script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); 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[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (command) ? (char *)command : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg;

View File

@ -2085,14 +2085,33 @@ weechat_js_api_hook_process_cb (const void *pointer, void *data,
{ {
struct t_plugin_script *script; struct t_plugin_script *script;
void *func_argv[5]; void *func_argv[5];
char empty_arg[1] = { '\0' }; char empty_arg[1] = { '\0' }, *result;
const char *ptr_function, *ptr_data; const char *ptr_function, *ptr_data;
int *rc, ret; int *rc, ret;
script = (struct t_plugin_script *)pointer; script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); 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[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (command) ? (char *)command : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg;

View File

@ -2268,14 +2268,33 @@ weechat_lua_api_hook_process_cb (const void *pointer, void *data,
{ {
struct t_plugin_script *script; struct t_plugin_script *script;
void *func_argv[5]; void *func_argv[5];
char empty_arg[1] = { '\0' }; char empty_arg[1] = { '\0' }, *result;
const char *ptr_function, *ptr_data; const char *ptr_function, *ptr_data;
int *rc, ret; int *rc, ret;
script = (struct t_plugin_script *)pointer; script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); 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[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (command) ? (char *)command : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg;

View File

@ -2198,14 +2198,33 @@ weechat_perl_api_hook_process_cb (const void *pointer, void *data,
{ {
struct t_plugin_script *script; struct t_plugin_script *script;
void *func_argv[5]; void *func_argv[5];
char empty_arg[1] = { '\0' }; char empty_arg[1] = { '\0' }, *result;
const char *ptr_function, *ptr_data; const char *ptr_function, *ptr_data;
int *rc, ret; int *rc, ret;
script = (struct t_plugin_script *)pointer; script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); 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[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (command) ? (char *)command : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg;

View File

@ -2208,14 +2208,33 @@ weechat_python_api_hook_process_cb (const void *pointer, void *data,
{ {
struct t_plugin_script *script; struct t_plugin_script *script;
void *func_argv[5]; void *func_argv[5];
char empty_arg[1] = { '\0' }; char empty_arg[1] = { '\0' }, *result;
const char *ptr_function, *ptr_data; const char *ptr_function, *ptr_data;
int *rc, ret; int *rc, ret;
script = (struct t_plugin_script *)pointer; script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); 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[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (command) ? (char *)command : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg;

View File

@ -2682,14 +2682,33 @@ weechat_ruby_api_hook_process_cb (const void *pointer, void *data,
{ {
struct t_plugin_script *script; struct t_plugin_script *script;
void *func_argv[5]; void *func_argv[5];
char empty_arg[1] = { '\0' }; char empty_arg[1] = { '\0' }, *result;
const char *ptr_function, *ptr_data; const char *ptr_function, *ptr_data;
int *rc, ret; int *rc, ret;
script = (struct t_plugin_script *)pointer; script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); 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[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (command) ? (char *)command : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg;

View File

@ -2450,14 +2450,33 @@ weechat_tcl_api_hook_process_cb (const void *pointer, void *data,
{ {
struct t_plugin_script *script; struct t_plugin_script *script;
void *func_argv[5]; void *func_argv[5];
char empty_arg[1] = { '\0' }; char empty_arg[1] = { '\0' }, *result;
const char *ptr_function, *ptr_data; const char *ptr_function, *ptr_data;
int *rc, ret; int *rc, ret;
script = (struct t_plugin_script *)pointer; script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); 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[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (command) ? (char *)command : empty_arg; func_argv[1] = (command) ? (char *)command : empty_arg;

View File

@ -57,7 +57,7 @@ struct timeval;
* please change the date with current one; for a second change at same * please change the date with current one; for a second change at same
* date, increment the 01, otherwise please keep 01. * 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 */ /* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \ #define WEECHAT_PLUGIN_NAME(__name) \
@ -138,11 +138,16 @@ struct timeval;
/* /*
* process return code (for callback): * process return code (for callback):
* if >= 0, then process ended and it's return code of command * if >= 0, the process ended and it's return code of command
* if < 0, then it's running or error * 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_RUNNING -1
#define WEECHAT_HOOK_PROCESS_ERROR -2 #define WEECHAT_HOOK_PROCESS_ERROR -2
#define WEECHAT_HOOK_PROCESS_CHILD -3
/* connect status for connection hooked */ /* connect status for connection hooked */
#define WEECHAT_HOOK_CONNECT_OK 0 #define WEECHAT_HOOK_CONNECT_OK 0