From 873d355ec271b22f0e48dac1c8eaca7deb075e66 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Fri, 27 Jan 2023 11:35:05 +0100 Subject: FLUID: fixe external command alert on Unix --- fluid/ExternalCodeEditor_UNIX.cxx | 34 +++++++++++++++++++++++++++++++++- fluid/ExternalCodeEditor_UNIX.h | 6 ++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/fluid/ExternalCodeEditor_UNIX.cxx b/fluid/ExternalCodeEditor_UNIX.cxx index 687927f70..286076793 100644 --- a/fluid/ExternalCodeEditor_UNIX.cxx +++ b/fluid/ExternalCodeEditor_UNIX.cxx @@ -59,6 +59,11 @@ ExternalCodeEditor::ExternalCodeEditor() { filename_ = 0; file_mtime_ = 0; file_size_ = 0; + if (::pipe(alert_pipe_) == 0) { + Fl::add_fd(alert_pipe_[0], FL_READ, alert_pipe_cb, this); + } else { + alert_pipe_[0] = alert_pipe_[1] = -1; + } } /** @@ -71,6 +76,8 @@ ExternalCodeEditor::~ExternalCodeEditor() { (void*)this, (long)pid_); close_editor(); // close editor, delete tmp file set_filename(0); // free()s filename + if (alert_pipe_[0] != -1) ::close(alert_pipe_[0]); + if (alert_pipe_[1] != -1) ::close(alert_pipe_[1]); } /** @@ -360,6 +367,7 @@ int ExternalCodeEditor::start_editor(const char *editor_cmd, editor_cmd, filename); char cmd[1024]; snprintf(cmd, sizeof(cmd), "%s %s", editor_cmd, filename); + command_line_.value(editor_cmd); // Fork editor to background.. switch ( pid_ = fork() ) { case -1: // error @@ -367,11 +375,14 @@ int ExternalCodeEditor::start_editor(const char *editor_cmd, return -1; case 0: { // child // NOTE: OSX wants minimal code between fork/exec, see Apple TN2083 + // NOTE: no FLTK calls after a fork. Use a pipe to tell the app if the + // command can't launch int nargs; char **args = 0; if (make_args(cmd, &nargs, &args) > 0) { execvp(args[0], args); // run command - doesn't return if succeeds - fl_alert("couldn't exec() '%s': %s", cmd, strerror(errno)); + int err = errno; + ::write(alert_pipe_[1], &err, sizeof(int)); exit(1); } exit(1); @@ -516,3 +527,24 @@ void ExternalCodeEditor::set_update_timer_callback(Fl_Timeout_Handler cb) { int ExternalCodeEditor::editors_open() { return L_editors_open; } + +/** + It the forked process can't run the editor, it will send the errno through a pipe. + */ +void ExternalCodeEditor::alert_pipe_cb(FL_SOCKET s, void* d) { + ExternalCodeEditor* self = (ExternalCodeEditor*)d; + self->last_error_ = 0; + ::read(s, &self->last_error_, sizeof(int)); + const char* cmd = self->command_line_.value(); + if (cmd && *cmd) { + if (cmd[0] == '/') { // is this an absoluet filename? + fl_alert("Can't launch external editor '%s':\n%s\n\ncmd: \"%s\")", + fl_filename_name(cmd), strerror(self->last_error_), cmd); + } else { + char pwd[FL_PATH_MAX+1]; + fl_getcwd(pwd, FL_PATH_MAX); + fl_alert("Can't launch external editor '%s':\n%s\n\ncmd: \"%s\"\npwd: \"%s\"", + fl_filename_name(cmd), strerror(self->last_error_), cmd, pwd); + } + } +} diff --git a/fluid/ExternalCodeEditor_UNIX.h b/fluid/ExternalCodeEditor_UNIX.h index 186a5b5ec..87feba850 100644 --- a/fluid/ExternalCodeEditor_UNIX.h +++ b/fluid/ExternalCodeEditor_UNIX.h @@ -9,6 +9,8 @@ #include +#include "fluid.h" + #include /* errno */ #include /* strerror() */ #include /* stat().. */ @@ -22,6 +24,10 @@ class ExternalCodeEditor { time_t file_mtime_; // last modify time of the file (used to determine if file changed) size_t file_size_; // last file size (used to determine if changed) const char *filename_; + Fd_String command_line_; + int last_error_; + int alert_pipe_[2]; + static void alert_pipe_cb(FL_SOCKET, void*); protected: void kill_editor(); -- cgit v1.2.3