FLUID: defer calling Fl::add_fd.

This commit is contained in:
Matthias Melcher 2023-01-29 11:51:44 +01:00
parent 86a0a28815
commit 85ac3d3147
2 changed files with 31 additions and 11 deletions

View File

@ -59,11 +59,8 @@ 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;
}
alert_pipe_[0] = alert_pipe_[1] = -1;
alert_pipe_open_ = false;
}
/**
@ -76,11 +73,12 @@ ExternalCodeEditor::~ExternalCodeEditor() {
(void*)this, (long)pid_);
close_editor(); // close editor, delete tmp file
set_filename(0); // free()s filename
if (alert_pipe_[0] != -1) {
if (alert_pipe_open_) {
Fl::remove_fd(alert_pipe_[0]);
::close(alert_pipe_[0]);
if (alert_pipe_[0] != -1) ::close(alert_pipe_[0]);
if (alert_pipe_[1] != -1) ::close(alert_pipe_[1]);
}
if (alert_pipe_[1] != -1) ::close(alert_pipe_[1]);
}
/**
@ -359,6 +357,23 @@ static int make_args(char *s, // string containing words (gets trashed!)
return(t);
}
/**
If no alert pipe is open yet, try to create the pipe and hook it up the the fd callback.
The alert pipe is used to communicate from the forked process to the main
FLTK app in case launching the editor failed.
*/
void ExternalCodeEditor::open_alert_pipe() {
if (!alert_pipe_open_) {
if (::pipe(alert_pipe_) == 0) {
Fl::add_fd(alert_pipe_[0], FL_READ, alert_pipe_cb, this);
alert_pipe_open_ = true;
} else {
alert_pipe_[0] = alert_pipe_[1] = -1;
}
}
}
/**
Start editor in background (fork/exec)
\return 0 on success, leaves editor child process running as 'pid_'
@ -371,6 +386,7 @@ int ExternalCodeEditor::start_editor(const char *editor_cmd,
char cmd[1024];
snprintf(cmd, sizeof(cmd), "%s %s", editor_cmd, filename);
command_line_.value(editor_cmd);
open_alert_pipe();
// Fork editor to background..
switch ( pid_ = fork() ) {
case -1: // error
@ -384,8 +400,10 @@ int ExternalCodeEditor::start_editor(const char *editor_cmd,
char **args = 0;
if (make_args(cmd, &nargs, &args) > 0) {
execvp(args[0], args); // run command - doesn't return if succeeds
int err = errno;
::write(alert_pipe_[1], &err, sizeof(int));
if (alert_pipe_open_) {
int err = errno;
::write(alert_pipe_[1], &err, sizeof(int));
}
exit(1);
}
exit(1);
@ -541,7 +559,7 @@ void ExternalCodeEditor::alert_pipe_cb(FL_SOCKET s, void* d) {
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_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];

View File

@ -27,6 +27,7 @@ class ExternalCodeEditor {
Fd_String command_line_;
int last_error_;
int alert_pipe_[2];
bool alert_pipe_open_;
static void alert_pipe_cb(FL_SOCKET, void*);
protected:
@ -35,6 +36,7 @@ protected:
const char *tmp_filename();
int start_editor(const char *cmd, const char *filename);
void set_filename(const char *val);
void open_alert_pipe();
public:
ExternalCodeEditor();