diff options
| author | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2025-08-16 20:28:00 +0300 |
|---|---|---|
| committer | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2025-08-17 12:02:29 +0300 |
| commit | e56c8489522e1aebb1309a03d460314138cb35dc (patch) | |
| tree | 816933ac027e7895ea3515136ce7359bad66f392 | |
| parent | 8c706a77db5a2aee6bcc6af53788e35e9805f945 (diff) | |
scm: support --listen flag for uds
Support the --listen flag to mu scm, to start listening on a Unix domain socket.
| -rw-r--r-- | mu/mu-options.cc | 5 | ||||
| -rw-r--r-- | mu/mu-options.hh | 1 | ||||
| -rw-r--r-- | scm/meson.build | 7 | ||||
| -rw-r--r-- | scm/mu-scm-repl.scm (renamed from scm/mu-scm-shell.scm) | 12 | ||||
| -rw-r--r-- | scm/mu-scm-store.cc | 1 | ||||
| -rw-r--r-- | scm/mu-scm.cc | 41 |
6 files changed, 52 insertions, 15 deletions
diff --git a/mu/mu-options.cc b/mu/mu-options.cc index 1a11bdb..b91138e 100644 --- a/mu/mu-options.cc +++ b/mu/mu-options.cc @@ -632,8 +632,11 @@ sub_server(CLI::App& sub, Options& opts) static void sub_scm(CLI::App& sub, Options& opts) { + sub.add_flag("--listen", opts.scm.listen, + "Start listening on a domain socket"); sub.add_option("script-path", opts.scm.script_path, "Path to script") - ->type_name("<path>"); + ->type_name("<path>") + ->excludes("--listen"); sub.add_option("script-args", opts.scm.params, "Parameters for script") ->type_name("<parameters>"); } diff --git a/mu/mu-options.hh b/mu/mu-options.hh index ead9ab9..245678d 100644 --- a/mu/mu-options.hh +++ b/mu/mu-options.hh @@ -259,6 +259,7 @@ struct Options { struct Scm { OptString script_path; /**< Path to script (optional) */ StringVec params; /**< Parameters for script (after "--") */ + bool listen; /**< Whether to start listening on a socket */ } scm; diff --git a/scm/meson.build b/scm/meson.build index f7ef0f7..d0ce391 100644 --- a/scm/meson.build +++ b/scm/meson.build @@ -17,8 +17,7 @@ mu_scm_dir=join_paths(datadir, 'mu', 'scm') mu_scm_dir_arg='-DMU_SCM_DIR="' + mu_scm_dir + '"' lib_mu_scm=static_library( - 'mu-scm', - [ + 'mu-scm', [ 'mu-scm.cc', 'mu-scm-message.cc', 'mu-scm-mime.cc', @@ -33,7 +32,9 @@ lib_mu_scm=static_library( install: false, cpp_args: [mu_scm_dir_arg]) -install_data(['mu-scm.scm', 'mu-scm-shell.scm'], install_dir : mu_scm_dir) +install_data(['mu-scm.scm', + 'mu-scm-repl.scm'], + install_dir : mu_scm_dir) # note: top-level meson.build defines a dummy replacement for this. mu_scm_dep = declare_dependency( diff --git a/scm/mu-scm-shell.scm b/scm/mu-scm-repl.scm index 0efe7f8..9664071 100644 --- a/scm/mu-scm-shell.scm +++ b/scm/mu-scm-repl.scm @@ -13,6 +13,16 @@ ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, write to the Free Software Foundation, ;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +(use-modules (system repl server) + (ice-9 threads)) +(use-modules (mu)) + +;; when a socket path is defined, listen on it (blocking) +;; after printing UNIX-CONNECT:<socket-file>\n on stdout +(let ((socket-path (getenv "MU_SCM_SOCKET_PATH"))) + (when socket-path + (format #t "UNIX-CONNECT:~a\n" socket-path) + (run-server + (make-unix-domain-server-socket #:path socket-path)))) (display "Welcome to the mu shell!\n\n") -(use-modules (mu)) diff --git a/scm/mu-scm-store.cc b/scm/mu-scm-store.cc index 44cbcf1..4bf22e2 100644 --- a/scm/mu-scm-store.cc +++ b/scm/mu-scm-store.cc @@ -216,7 +216,6 @@ init_subrs() #pragma GCC diagnostic pop } - void Mu::Scm::init_store(const Store& store) { diff --git a/scm/mu-scm.cc b/scm/mu-scm.cc index 0a0f4e6..9d460de 100644 --- a/scm/mu-scm.cc +++ b/scm/mu-scm.cc @@ -85,7 +85,9 @@ make_mu_scm_path(const std::string& fname) { namespace { static std::string mu_scm_path; -static std::string mu_scm_shell_path; +static std::string mu_scm_repl_path; +static std::string mu_scm_socket_path; +constexpr auto SOCKET_PATH_ENV = "MU_SCM_SOCKET_PATH"; } static Result<void> @@ -104,12 +106,11 @@ prepare_run(const Mu::Scm::Config& conf) else return Err(path.error()); - if (const auto path = make_mu_scm_path("mu-scm-shell.scm"); path) - mu_scm_shell_path = *path; + if (const auto path = make_mu_scm_path("mu-scm-repl.scm"); path) + mu_scm_repl_path = *path; else return Err(path.error()); - if (config->options.scm.script_path) { const auto path{config->options.scm.script_path->c_str()}; if (const auto res = ::access(path, R_OK); res != 0) { @@ -121,9 +122,28 @@ prepare_run(const Mu::Scm::Config& conf) return Ok(); } -Result<void> -Mu::Scm::run(const Mu::Scm::Config& conf) { +// make a unique unix-socket path +static std::string +maybe_set_uds_path(bool set) +{ + if (set) { + GRand* grand{g_rand_new()}; + auto path = join_paths(g_get_user_runtime_dir(), + mu_format("mu-scm-socket-{:08x}", + g_rand_int(grand))); + g_rand_free(grand); + g_setenv(SOCKET_PATH_ENV, path.c_str(), 1); + return path; + } else { + g_unsetenv(SOCKET_PATH_ENV); + return {}; + } +} + +Result<void> +Mu::Scm::run(const Mu::Scm::Config& conf) +{ if (const auto res = prepare_run(conf); !res) return Err(res.error()); @@ -151,10 +171,13 @@ Mu::Scm::run(const Mu::Scm::Config& conf) { "-c", cmd.c_str()}) args.emplace_back(arg); } else { - // otherwise, drop us into an interactive shell/repl (and - // shell spec) + // otherwise, drop us into an interactive shell/repl + // or start listening on a domain socket. + mu_scm_socket_path = + maybe_set_uds_path(config->options.scm.listen); + args.emplace_back("--no-auto-compile"); args.emplace_back("-l"); - args.emplace_back(mu_scm_shell_path.c_str()); + args.emplace_back(mu_scm_repl_path.c_str()); } /* ahem...*/ scm_shell(std::size(args), const_cast<char**>(args.data())); |
