about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDaniel Santos <dacs.git@brilhante.top>2023-03-24 14:56:35 +0000
committerDaniel Santos <dan.git@brilhante.top>2023-07-01 10:08:20 +0100
commit35351387a197e55f5389545efe3941b58ca94ffd (patch)
tree87bba0f195ad83c9f895f91f1119cd099b954c71
parentc402f8d9d2b3f94bbc20ba9c0c43f6df3b7ca885 (diff)
downloadprofani-tty-35351387a197e55f5389545efe3941b58ca94ffd.tar.gz
/executable async on|off
 * rename call_external() to call_external_async().
 * add call_external_fork(). This function makes all executable calls
to be forked and synchronous. So that running profanity inside a TTY,
we can set all executables to be TTY programs (fbi, mpv, w3m, emacs
eww, etc.), making possible to open urls or see images inside the TTY.
 * add '/executable async' command.
 * make call_external() use either call_external_async() or
call_external_fork(), according to the '/executable async'
configuration.

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
-rw-r--r--src/command/cmd_ac.c6
-rw-r--r--src/command/cmd_defs.c12
-rw-r--r--src/command/cmd_funcs.c13
-rw-r--r--src/command/cmd_funcs.h1
-rw-r--r--src/common.c41
-rw-r--r--src/config/preferences.c4
-rw-r--r--src/config/preferences.h1
-rw-r--r--src/ui/console.c2
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