diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/wee-hook.c | 178 | ||||
-rw-r--r-- | src/core/wee-hook.h | 15 | ||||
-rw-r--r-- | src/plugins/guile/weechat-guile-api.c | 16 | ||||
-rw-r--r-- | src/plugins/lua/weechat-lua-api.c | 19 | ||||
-rw-r--r-- | src/plugins/perl/weechat-perl-api.c | 19 | ||||
-rw-r--r-- | src/plugins/python/weechat-python-api.c | 20 | ||||
-rw-r--r-- | src/plugins/ruby/weechat-ruby-api.c | 26 | ||||
-rw-r--r-- | src/plugins/tcl/weechat-tcl-api.c | 22 |
8 files changed, 263 insertions, 52 deletions
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index 150bbc168..bb8895592 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -1353,35 +1353,29 @@ hook_process_hashtable (struct t_weechat_plugin *plugin, struct t_hook_process *new_hook_process; char *stdout_buffer, *stderr_buffer; + stdout_buffer = NULL; + stderr_buffer = NULL; + new_hook = NULL; + new_hook_process = NULL; + if (!command || !command[0] || !callback) - return NULL; + goto error; stdout_buffer = malloc (HOOK_PROCESS_BUFFER_SIZE + 1); if (!stdout_buffer) - return NULL; + goto error; stderr_buffer = malloc (HOOK_PROCESS_BUFFER_SIZE + 1); if (!stderr_buffer) - { - free (stdout_buffer); - return NULL; - } + goto error; new_hook = malloc (sizeof (*new_hook)); if (!new_hook) - { - free (stdout_buffer); - free (stderr_buffer); - return NULL; - } + goto error; + new_hook_process = malloc (sizeof (*new_hook_process)); if (!new_hook_process) - { - free (stdout_buffer); - free (stderr_buffer); - free (new_hook); - return NULL; - } + goto error; hook_init_data (new_hook, plugin, HOOK_TYPE_PROCESS, HOOK_PRIORITY_DEFAULT, callback_data); @@ -1391,16 +1385,21 @@ hook_process_hashtable (struct t_weechat_plugin *plugin, new_hook_process->command = strdup (command); new_hook_process->options = (options) ? hashtable_dup (options) : NULL; new_hook_process->timeout = timeout; + new_hook_process->child_read[HOOK_PROCESS_STDIN] = -1; new_hook_process->child_read[HOOK_PROCESS_STDOUT] = -1; new_hook_process->child_read[HOOK_PROCESS_STDERR] = -1; + new_hook_process->child_write[HOOK_PROCESS_STDIN] = -1; new_hook_process->child_write[HOOK_PROCESS_STDOUT] = -1; new_hook_process->child_write[HOOK_PROCESS_STDERR] = -1; new_hook_process->child_pid = 0; + new_hook_process->hook_fd[HOOK_PROCESS_STDIN] = NULL; new_hook_process->hook_fd[HOOK_PROCESS_STDOUT] = NULL; new_hook_process->hook_fd[HOOK_PROCESS_STDERR] = NULL; new_hook_process->hook_timer = NULL; + new_hook_process->buffer[HOOK_PROCESS_STDIN] = NULL; new_hook_process->buffer[HOOK_PROCESS_STDOUT] = stdout_buffer; new_hook_process->buffer[HOOK_PROCESS_STDERR] = stderr_buffer; + new_hook_process->buffer_size[HOOK_PROCESS_STDIN] = 0; new_hook_process->buffer_size[HOOK_PROCESS_STDOUT] = 0; new_hook_process->buffer_size[HOOK_PROCESS_STDERR] = 0; @@ -1409,6 +1408,17 @@ hook_process_hashtable (struct t_weechat_plugin *plugin, hook_process_run (new_hook); return new_hook; + +error: + if (stdout_buffer) + free (stdout_buffer); + if (stderr_buffer) + free (stderr_buffer); + if (new_hook) + free (new_hook); + if (new_hook_process) + free (new_hook_process); + return NULL; } /* @@ -1439,11 +1449,25 @@ hook_process_child (struct t_hook *hook_process) int rc, i, num_args; FILE *f; - /* use "/dev/null" for stdin stream */ - f = freopen ("/dev/null", "r", stdin); - (void) f; + /* read stdin from parent, if a pipe was defined */ + if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDIN]) >= 0) + { + if (dup2 (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDIN]), + STDIN_FILENO) < 0) + { + _exit (EXIT_FAILURE); + } + } + else + { + /* no stdin pipe from parent, use "/dev/null" for stdin stream */ + f = freopen ("/dev/null", "r", stdin); + (void) f; + } + if (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDIN]) >= 0) + close (HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDIN])); - /* redirect stdout/stderr to pipe (so that father process can read them) */ + /* 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]), @@ -1718,40 +1742,38 @@ hook_process_timer_cb (void *arg_hook_process, int remaining_calls) void hook_process_run (struct t_hook *hook_process) { - int pipe_stdout[2], pipe_stderr[2], timeout, max_calls, rc; + int pipes[3][2], timeout, max_calls, rc, i; long interval; pid_t pid; - /* create pipe for child process (stdout) */ - if (pipe (pipe_stdout) < 0) + for (i = 0; i < 3; i++) { - (void) (HOOK_PROCESS(hook_process, callback)) - (hook_process->callback_data, - HOOK_PROCESS(hook_process, command), - WEECHAT_HOOK_PROCESS_ERROR, - NULL, NULL); - unhook (hook_process); - return; + pipes[i][0] = -1; + pipes[i][1] = -1; } - if (pipe (pipe_stderr) < 0) + + /* create pipe for stdin (only if stdin was given in options) */ + if (HOOK_PROCESS(hook_process, options) + && hashtable_has_key (HOOK_PROCESS(hook_process, options), "stdin")) { - close (pipe_stdout[0]); - close (pipe_stdout[1]); - (void) (HOOK_PROCESS(hook_process, callback)) - (hook_process->callback_data, - HOOK_PROCESS(hook_process, command), - WEECHAT_HOOK_PROCESS_ERROR, - NULL, NULL); - unhook (hook_process); - return; + if (pipe (pipes[HOOK_PROCESS_STDIN]) < 0) + goto error; } - HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]) = pipe_stdout[0]; - HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDOUT]) = pipe_stdout[1]; + /* create pipes for stdout/err */ + if (pipe (pipes[HOOK_PROCESS_STDOUT]) < 0) + goto error; + if (pipe (pipes[HOOK_PROCESS_STDERR]) < 0) + goto error; - HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]) = pipe_stderr[0]; - HOOK_PROCESS(hook_process, child_write[HOOK_PROCESS_STDERR]) = pipe_stderr[1]; + /* assign pipes to variables in hook */ + for (i = 0; i < 3; i++) + { + HOOK_PROCESS(hook_process, child_read[i]) = pipes[i][0]; + HOOK_PROCESS(hook_process, child_write[i]) = pipes[i][1]; + } + /* fork */ switch (pid = fork ()) { /* fork failed */ @@ -1772,8 +1794,14 @@ hook_process_run (struct t_hook *hook_process) _exit (EXIT_SUCCESS); break; } + /* parent process */ HOOK_PROCESS(hook_process, child_pid) = pid; + if (HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDIN]) >= 0) + { + 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])); @@ -1815,6 +1843,22 @@ hook_process_run (struct t_hook *hook_process) interval, 0, max_calls, &hook_process_timer_cb, hook_process); + return; + +error: + for (i = 0; i < 3; i++) + { + if (pipes[i][0] >= 0) + close (pipes[i][0]); + if (pipes[i][1] >= 0) + close (pipes[i][1]); + } + (void) (HOOK_PROCESS(hook_process, callback)) + (hook_process->callback_data, + HOOK_PROCESS(hook_process, command), + WEECHAT_HOOK_PROCESS_ERROR, + NULL, NULL); + unhook (hook_process); } /* @@ -3157,12 +3201,39 @@ hook_focus_get_data (struct t_hashtable *hashtable_focus1, void hook_set (struct t_hook *hook, const char *property, const char *value) { + /* invalid hook? */ + if (!hook_valid (hook)) + return; + if (string_strcasecmp (property, "subplugin") == 0) { if (hook->subplugin) free(hook->subplugin); hook->subplugin = strdup (value); } + else if (string_strcasecmp (property, "stdin") == 0) + { + if (!hook->deleted + && (hook->type == HOOK_TYPE_PROCESS) + && (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]) >= 0)) + { + /* send data on child's stdin */ + write (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]), + value, + strlen (value)); + } + } + else if (string_strcasecmp (property, "stdin_close") == 0) + { + if (!hook->deleted + && (hook->type == HOOK_TYPE_PROCESS) + && (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]) >= 0)) + { + /* close stdin pipe */ + close (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN])); + HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]) = -1; + } + } } /* @@ -3250,6 +3321,8 @@ unhook (struct t_hook *hook) free (HOOK_PROCESS(hook, command)); if (HOOK_PROCESS(hook, options)) hashtable_free (HOOK_PROCESS(hook, options)); + if (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDIN])) + unhook (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDIN])); if (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDOUT])) unhook (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDOUT])); if (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDERR])) @@ -3261,6 +3334,10 @@ unhook (struct t_hook *hook) kill (HOOK_PROCESS(hook, child_pid), SIGKILL); waitpid (HOOK_PROCESS(hook, child_pid), NULL, 0); } + if (HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDIN]) != -1) + close (HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDIN])); + if (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]) != -1) + close (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN])); if (HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDOUT]) != -1) close (HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDOUT])); if (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDOUT]) != -1) @@ -3269,6 +3346,8 @@ unhook (struct t_hook *hook) close (HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDERR])); if (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDERR]) != -1) close (HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDERR])); + if (HOOK_PROCESS(hook, buffer[HOOK_PROCESS_STDIN])) + free (HOOK_PROCESS(hook, buffer[HOOK_PROCESS_STDIN])); if (HOOK_PROCESS(hook, buffer[HOOK_PROCESS_STDOUT])) free (HOOK_PROCESS(hook, buffer[HOOK_PROCESS_STDOUT])); if (HOOK_PROCESS(hook, buffer[HOOK_PROCESS_STDERR])) @@ -3587,6 +3666,10 @@ hook_add_to_infolist_pointer (struct t_infolist *infolist, struct t_hook *hook) return 0; if (!infolist_new_var_integer (ptr_item, "timeout", 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; + if (!infolist_new_var_integer (ptr_item, "child_write_stdin", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]))) + return 0; if (!infolist_new_var_integer (ptr_item, "child_read_stdout", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDOUT]))) return 0; if (!infolist_new_var_integer (ptr_item, "child_write_stdout", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDOUT]))) @@ -3597,6 +3680,8 @@ hook_add_to_infolist_pointer (struct t_infolist *infolist, struct t_hook *hook) return 0; if (!infolist_new_var_integer (ptr_item, "child_pid", HOOK_PROCESS(hook, child_pid))) return 0; + if (!infolist_new_var_pointer (ptr_item, "hook_fd_stdin", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDIN]))) + return 0; if (!infolist_new_var_pointer (ptr_item, "hook_fd_stdout", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDOUT]))) return 0; if (!infolist_new_var_pointer (ptr_item, "hook_fd_stderr", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDERR]))) @@ -4062,11 +4147,14 @@ hook_print_log () hashtable_get_string (HOOK_PROCESS(ptr_hook, options), "keys_values")); log_printf (" timeout . . . . . . . : %d", 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])); log_printf (" child_write[stdout] . : %d", HOOK_PROCESS(ptr_hook, child_write[HOOK_PROCESS_STDOUT])); log_printf (" child_read[stderr]. . : %d", HOOK_PROCESS(ptr_hook, child_read[HOOK_PROCESS_STDERR])); log_printf (" child_write[stderr] . : %d", HOOK_PROCESS(ptr_hook, child_write[HOOK_PROCESS_STDERR])); log_printf (" child_pid . . . . . . : %d", HOOK_PROCESS(ptr_hook, child_pid)); + log_printf (" hook_fd[stdin]. . . . : 0x%lx", HOOK_PROCESS(ptr_hook, hook_fd[HOOK_PROCESS_STDIN])); log_printf (" hook_fd[stdout] . . . : 0x%lx", HOOK_PROCESS(ptr_hook, hook_fd[HOOK_PROCESS_STDOUT])); log_printf (" hook_fd[stderr] . . . : 0x%lx", HOOK_PROCESS(ptr_hook, hook_fd[HOOK_PROCESS_STDERR])); log_printf (" hook_timer. . . . . . : 0x%lx", HOOK_PROCESS(ptr_hook, hook_timer)); diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h index ca3f7b641..3f4a04ffa 100644 --- a/src/core/wee-hook.h +++ b/src/core/wee-hook.h @@ -88,8 +88,9 @@ enum t_hook_type #define HOOK_FD_FLAG_EXCEPTION 4 /* constants for hook process */ -#define HOOK_PROCESS_STDOUT 0 -#define HOOK_PROCESS_STDERR 1 +#define HOOK_PROCESS_STDIN 0 +#define HOOK_PROCESS_STDOUT 1 +#define HOOK_PROCESS_STDERR 2 #define HOOK_PROCESS_BUFFER_SIZE 65536 /* macros to access hook specific data */ @@ -213,13 +214,13 @@ struct t_hook_process char *command; /* command executed by child */ struct t_hashtable *options; /* options for process (see doc) */ long timeout; /* timeout (ms) (0 = no timeout) */ - int child_read[2]; /* to read data in pipe from child */ - int child_write[2]; /* to write data in pipe for child */ + int child_read[3]; /* read stdin/out/err data from child*/ + int child_write[3]; /* write stdin/out/err data for child*/ pid_t child_pid; /* pid of child process */ - struct t_hook *hook_fd[2]; /* hook fd for stdout/stderr */ + struct t_hook *hook_fd[3]; /* hook fd for stdin/out/err */ struct t_hook *hook_timer; /* timer to check if child has died */ - char *buffer[2]; /* buffers for child stdout/stderr */ - int buffer_size[2]; /* size of child stdout/stderr */ + char *buffer[3]; /* buffers for child stdin/out/err */ + int buffer_size[3]; /* size of child stdin/out/err */ }; /* hook connect */ diff --git a/src/plugins/guile/weechat-guile-api.c b/src/plugins/guile/weechat-guile-api.c index b79e53967..bdd47e92f 100644 --- a/src/plugins/guile/weechat-guile-api.c +++ b/src/plugins/guile/weechat-guile-api.c @@ -2965,6 +2965,21 @@ weechat_guile_api_hook_focus (SCM area, SCM function, SCM data) } SCM +weechat_guile_api_hook_set (SCM hook, SCM property, SCM value) +{ + API_FUNC(1, "hook_set", API_RETURN_ERROR); + if (!scm_is_string (hook) || !scm_is_string (property) + || !scm_is_string (value)) + API_WRONG_ARGS(API_RETURN_ERROR); + + weechat_hook_set (API_STR2PTR(API_SCM_TO_STRING(hook)), + API_SCM_TO_STRING(property), + API_SCM_TO_STRING(value)); + + API_RETURN_OK; +} + +SCM weechat_guile_api_unhook (SCM hook) { API_FUNC(1, "unhook", API_RETURN_ERROR); @@ -4726,6 +4741,7 @@ weechat_guile_api_module_init (void *data) API_DEF_FUNC(hook_info_hashtable, 6); API_DEF_FUNC(hook_infolist, 6); API_DEF_FUNC(hook_focus, 3); + API_DEF_FUNC(hook_set, 3); API_DEF_FUNC(unhook, 1); API_DEF_FUNC(unhook_all, 0); API_DEF_FUNC(buffer_new, 5); diff --git a/src/plugins/lua/weechat-lua-api.c b/src/plugins/lua/weechat-lua-api.c index 4c0009f44..d3e333de0 100644 --- a/src/plugins/lua/weechat-lua-api.c +++ b/src/plugins/lua/weechat-lua-api.c @@ -3202,6 +3202,24 @@ weechat_lua_api_hook_focus (lua_State *L) } static int +weechat_lua_api_hook_set (lua_State *L) +{ + const char *hook, *property, *value; + + API_FUNC(1, "hook_set", API_RETURN_ERROR); + if (lua_gettop (L) < 3) + API_WRONG_ARGS(API_RETURN_ERROR); + + hook = lua_tostring (L, -3); + property = lua_tostring (L, -2); + value = lua_tostring (L, -1); + + weechat_hook_set (API_STR2PTR(hook), property, value); + + API_RETURN_OK; +} + +static int weechat_lua_api_unhook (lua_State *L) { const char *hook; @@ -5210,6 +5228,7 @@ const struct luaL_Reg weechat_lua_api_funcs[] = { API_DEF_FUNC(hook_info_hashtable), API_DEF_FUNC(hook_infolist), API_DEF_FUNC(hook_focus), + API_DEF_FUNC(hook_set), API_DEF_FUNC(unhook), API_DEF_FUNC(unhook_all), API_DEF_FUNC(buffer_new), diff --git a/src/plugins/perl/weechat-perl-api.c b/src/plugins/perl/weechat-perl-api.c index 7d6c9d668..632e17872 100644 --- a/src/plugins/perl/weechat-perl-api.c +++ b/src/plugins/perl/weechat-perl-api.c @@ -3019,6 +3019,24 @@ XS (XS_weechat_api_hook_focus) API_RETURN_STRING_FREE(result); } +XS (XS_weechat_api_hook_set) +{ + char *hook, *property, *value; + dXSARGS; + + API_FUNC(1, "hook_set", API_RETURN_ERROR); + if (items < 3) + API_WRONG_ARGS(API_RETURN_ERROR); + + hook = SvPV_nolen (ST (0)); + property = SvPV_nolen (ST (1)); + value = SvPV_nolen (ST (2)); + + weechat_hook_set (API_STR2PTR(hook), property, value); + + API_RETURN_OK; +} + XS (XS_weechat_api_unhook) { dXSARGS; @@ -4963,6 +4981,7 @@ weechat_perl_api_init (pTHX) API_DEF_FUNC(hook_info_hashtable); API_DEF_FUNC(hook_infolist); API_DEF_FUNC(hook_focus); + API_DEF_FUNC(hook_set); API_DEF_FUNC(unhook); API_DEF_FUNC(unhook_all); API_DEF_FUNC(buffer_new); diff --git a/src/plugins/python/weechat-python-api.c b/src/plugins/python/weechat-python-api.c index 4b6128edd..3a3cc7b68 100644 --- a/src/plugins/python/weechat-python-api.c +++ b/src/plugins/python/weechat-python-api.c @@ -3159,6 +3159,25 @@ weechat_python_api_hook_focus (PyObject *self, PyObject *args) } static PyObject * +weechat_python_api_hook_set (PyObject *self, PyObject *args) +{ + char *hook, *property, *value; + + API_FUNC(1, "hook_set", API_RETURN_ERROR); + hook = NULL; + property = NULL; + value = NULL; + if (!PyArg_ParseTuple (args, "sss", &hook, &property, &value)) + API_WRONG_ARGS(API_RETURN_ERROR); + + weechat_hook_set (API_STR2PTR(hook), + property, + value); + + API_RETURN_OK; +} + +static PyObject * weechat_python_api_unhook (PyObject *self, PyObject *args) { char *hook; @@ -5122,6 +5141,7 @@ PyMethodDef weechat_python_funcs[] = API_DEF_FUNC(hook_info_hashtable), API_DEF_FUNC(hook_infolist), API_DEF_FUNC(hook_focus), + API_DEF_FUNC(hook_set), API_DEF_FUNC(unhook), API_DEF_FUNC(unhook_all), API_DEF_FUNC(buffer_new), diff --git a/src/plugins/ruby/weechat-ruby-api.c b/src/plugins/ruby/weechat-ruby-api.c index 6ceadef11..471f038a6 100644 --- a/src/plugins/ruby/weechat-ruby-api.c +++ b/src/plugins/ruby/weechat-ruby-api.c @@ -3649,6 +3649,31 @@ weechat_ruby_api_hook_focus (VALUE class, VALUE area, VALUE function, } static VALUE +weechat_ruby_api_hook_set (VALUE class, VALUE hook, VALUE property, + VALUE value) +{ + char *c_hook, *c_property, *c_value; + + API_FUNC(1, "hook_set", API_RETURN_ERROR); + if (NIL_P (hook) || NIL_P (property) || NIL_P (value)) + API_WRONG_ARGS(API_RETURN_ERROR); + + Check_Type (hook, T_STRING); + Check_Type (property, T_STRING); + Check_Type (value, T_STRING); + + c_hook = StringValuePtr (hook); + c_property = StringValuePtr (property); + c_value = StringValuePtr (value); + + weechat_hook_set (API_STR2PTR(c_hook), + c_property, + c_value); + + API_RETURN_OK; +} + +static VALUE weechat_ruby_api_unhook (VALUE class, VALUE hook) { char *c_hook; @@ -6066,6 +6091,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat) API_DEF_FUNC(hook_info_hashtable, 6); API_DEF_FUNC(hook_infolist, 6); API_DEF_FUNC(hook_focus, 3); + API_DEF_FUNC(hook_set, 3); API_DEF_FUNC(unhook, 1); API_DEF_FUNC(unhook_all, 0); API_DEF_FUNC(buffer_new, 5); diff --git a/src/plugins/tcl/weechat-tcl-api.c b/src/plugins/tcl/weechat-tcl-api.c index 0730cac48..bcaecb999 100644 --- a/src/plugins/tcl/weechat-tcl-api.c +++ b/src/plugins/tcl/weechat-tcl-api.c @@ -3505,6 +3505,27 @@ weechat_tcl_api_hook_focus (ClientData clientData, Tcl_Interp *interp, } static int +weechat_tcl_api_hook_set (ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + Tcl_Obj *objp; + char *hook, *property, *value; + int i; + + API_FUNC(1, "hook_set", API_RETURN_ERROR); + if (objc < 4) + API_WRONG_ARGS(API_RETURN_ERROR); + + hook = Tcl_GetStringFromObj (objv[1], &i); + property = Tcl_GetStringFromObj (objv[2], &i); + value = Tcl_GetStringFromObj (objv[3], &i); + + weechat_hook_set (API_STR2PTR(hook), property, value); + + API_RETURN_OK; +} + +static int weechat_tcl_api_unhook (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { @@ -5809,6 +5830,7 @@ void weechat_tcl_api_init (Tcl_Interp *interp) API_DEF_FUNC(hook_info_hashtable); API_DEF_FUNC(hook_infolist); API_DEF_FUNC(hook_focus); + API_DEF_FUNC(hook_set); API_DEF_FUNC(unhook); API_DEF_FUNC(unhook_all); API_DEF_FUNC(buffer_new); |