diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command/cmd_ac.c | 6 | ||||
-rw-r--r-- | src/command/cmd_defs.c | 12 | ||||
-rw-r--r-- | src/command/cmd_funcs.c | 13 | ||||
-rw-r--r-- | src/command/cmd_funcs.h | 1 | ||||
-rw-r--r-- | src/common.c | 41 | ||||
-rw-r--r-- | src/config/preferences.c | 4 | ||||
-rw-r--r-- | src/config/preferences.h | 1 | ||||
-rw-r--r-- | src/ui/console.c | 2 |
8 files changed, 70 insertions, 10 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index d182e4db..527281a7 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -1116,11 +1116,7 @@ cmd_ac_init(void) autocomplete_add(executable_ac, "urlopen"); autocomplete_add(executable_ac, "urlsave"); autocomplete_add(executable_ac, "editor"); - autocomplete_add(executable_ac, "vcard_photo"); - - executable_param_ac = autocomplete_new(); - autocomplete_add(executable_param_ac, "set"); - autocomplete_add(executable_param_ac, "default"); + autocomplete_add(executable_ac, "async"); intype_ac = autocomplete_new(); autocomplete_add(intype_ac, "console"); diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 9bc8b6f2..1aee5fb8 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2531,7 +2531,8 @@ static const struct cmd_t command_defs[] = { { "urlopen", cmd_executable_urlopen }, { "urlsave", cmd_executable_urlsave }, { "editor", cmd_executable_editor }, - { "vcard_photo", cmd_executable_vcard_photo }) + { "vcard_photo", cmd_executable_vcard_photo }, + { "async", cmd_executable_async }) CMD_TAGS( CMD_TAG_DISCOVERY) CMD_SYN( @@ -2544,7 +2545,8 @@ static const struct cmd_t command_defs[] = { "/executable editor set <cmdtemplate>", "/executable editor default", "/executable vcard_photo set <cmdtemplate>", - "/executable vcard_photo default") + "/executable vcard_photo default", + "/executable async on|off") CMD_DESC( "Configure executable that should be called upon a certain command.") CMD_ARGS( @@ -2557,7 +2559,8 @@ static const struct cmd_t command_defs[] = { { "editor set", "Set editor to be used with /editor. Needs a terminal editor or a script to run a graphical editor." }, { "editor default", "Restore to default settings." }, { "vcard_photo set", "Set executable that is run by /vcard photo open. Takes a command template that replaces %p with the path" }, - { "vcard_photo default", "Restore to default settings." }) + { "vcard_photo default", "Restore to default settings." }, + { "async on|off", "Enable or disable async call of executables. Disable async if all executables run inside the TTY." }) CMD_EXAMPLES( "/executable avatar xdg-open", "/executable urlopen set \"xdg-open %u\"", @@ -2566,8 +2569,9 @@ static const struct cmd_t command_defs[] = { "/executable urlsave set \"wget %u -O %p\"", "/executable urlsave set \"curl %u -o %p\"", "/executable urlsave default", + "/executable editor set \"emacsclient -t\"", "/executable vcard_photo set \"feh %p\"", - "/executable editor set \"emacsclient -t\"") + "/executable async off") }, { CMD_PREAMBLE("/url", diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index ffa8a3d2..f5535ad9 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -10864,3 +10864,16 @@ cmd_vcard_save(ProfWin* window, const char* const command, gchar** args) cons_show("User vCard uploaded"); return TRUE; } + +gboolean +cmd_executable_async(ProfWin* window, const char* const command, gchar** args) +{ + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + return TRUE; + } + + _cmd_set_boolean_preference(args[1], command, "Run executables asynchronously", PREF_EXECUTABLE_ASYNC); + + return TRUE; +} diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h index 400261d3..53fa7f31 100644 --- a/src/command/cmd_funcs.h +++ b/src/command/cmd_funcs.h @@ -267,5 +267,6 @@ gboolean cmd_vcard_photo(ProfWin* window, const char* const command, gchar** arg gboolean cmd_vcard_refresh(ProfWin* window, const char* const command, gchar** args); gboolean cmd_vcard_set(ProfWin* window, const char* const command, gchar** args); gboolean cmd_vcard_save(ProfWin* window, const char* const command, gchar** args); +gboolean cmd_executable_async(ProfWin* window, const char* const command, gchar** args); #endif diff --git a/src/common.c b/src/common.c index ab5c6c8b..d2bbc1c6 100644 --- a/src/common.c +++ b/src/common.c @@ -46,6 +46,13 @@ #include <sys/types.h> #include <sys/stat.h> +// fork / exec +#include <sys/wait.h> +#include <readline/readline.h> +#include "ui/ui.h" + +#include "config/preferences.h" + #include <curl/curl.h> #include <curl/easy.h> #include <glib.h> @@ -466,7 +473,7 @@ get_mentions(gboolean whole_word, gboolean case_sensitive, const char* const mes } gboolean -call_external(gchar** argv) +call_external_async(gchar** argv) { GError* spawn_error; gboolean is_successful; @@ -489,6 +496,38 @@ call_external(gchar** argv) return is_successful; } +gboolean +call_external_fork(gchar** argv) +{ + // Fork / exec external executable + pid_t pid = fork(); + if (pid == 0) { + int x = execvp(argv[0], argv); + if (x == -1) { + auto_gchar gchar* cmd = g_strjoinv(" ", argv); + log_error("Unable to call external executable '%s'", cmd); + } + _exit(EXIT_FAILURE); + } else { + if (pid == -1) { + return TRUE; + } + waitpid(pid, NULL, 0); + + // refresh display + ui_resize(); + rl_forced_update_display(); + } + + return TRUE; +} + +gboolean +call_external(gchar** argv) +{ + return prefs_get_boolean(PREF_EXECUTABLE_ASYNC) ? call_external_async(argv) : call_external_fork(argv); +} + gchar** format_call_external_argv(const char* template, const char* url, const char* filename) { diff --git a/src/config/preferences.c b/src/config/preferences.c index 3293d025..385cf592 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -1836,6 +1836,7 @@ _get_group(preference_t pref) case PREF_URL_OPEN_CMD: case PREF_URL_SAVE_CMD: case PREF_VCARD_PHOTO_CMD: + case PREF_EXECUTABLE_ASYNC: return PREF_GROUP_EXECUTABLES; case PREF_AUTOAWAY_CHECK: case PREF_AUTOAWAY_MODE: @@ -2140,6 +2141,8 @@ _get_key(preference_t pref) return "url.open.cmd"; case PREF_URL_SAVE_CMD: return "url.save.cmd"; + case PREF_EXECUTABLE_ASYNC: + return "run.async"; case PREF_COMPOSE_EDITOR: return "compose.editor"; case PREF_SILENCE_NON_ROSTER: @@ -2214,6 +2217,7 @@ _get_default_boolean(preference_t pref) case PREF_MOOD: case PREF_STROPHE_SM_ENABLED: case PREF_STROPHE_SM_RESEND: + case PREF_EXECUTABLE_ASYNC: return TRUE; default: return FALSE; diff --git a/src/config/preferences.h b/src/config/preferences.h index 531b8f94..3e386960 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -186,6 +186,7 @@ typedef enum { PREF_STROPHE_SM_ENABLED, PREF_STROPHE_SM_RESEND, PREF_VCARD_PHOTO_CMD, + PREF_EXECUTABLE_ASYNC, PREF_STATUSBAR_TABMODE, } preference_t; diff --git a/src/ui/console.c b/src/ui/console.c index d7ef1bc1..8c6a01a3 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -2279,6 +2279,8 @@ cons_executable_setting(void) gchar* vcard_cmd = prefs_get_string(PREF_VCARD_PHOTO_CMD); cons_show("Default '/vcard photo open' command (/executable vcard_photo) : %s", vcard_cmd); g_free(vcard_cmd); + + cons_show("Run executables asynchronously (/executable async) : %s", prefs_get_boolean(PREF_EXECUTABLE_ASYNC) ? "ON" : "OFF"); } void |