Skip to content

Commit

Permalink
LyricsPage: use posix_spawn() to launch the editor
Browse files Browse the repository at this point in the history
This is simpler than fork()/exec and may be more portable.
  • Loading branch information
MaxKellermann committed Sep 11, 2024
1 parent 1108dc0 commit 8a877d9
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions src/LyricsPage.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <assert.h>
#include <errno.h>
#include <spawn.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -348,25 +349,33 @@ LyricsPage::Edit() noexcept
def_prog_mode();
endwin();

/* TODO: fork/exec/wait won't work on Windows, but building a command
string for system() is too tricky */
int status;
pid_t pid = fork();
if (pid == -1) {
posix_spawnattr_t attr;
posix_spawnattr_init(&attr);

#ifdef USE_SIGNALFD
/* unblock all signals which may be blocked for signalfd */
posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK);
#endif

char *const argv[] = {
const_cast<char *>(editor),
const_cast<char *>(path.c_str()),
nullptr
};

pid_t pid;
if (posix_spawn(&pid, editor, nullptr, &attr,
argv, environ) != 0) {
reset_prog_mode();
FmtAlert("{} ({})"sv, _("Can't start editor"), strerror(errno));
return;
} else if (pid == 0) {
execlp(editor, editor, path.c_str(), nullptr);
/* exec failed, do what system does */
_exit(127);
} else {
int ret;
do {
ret = waitpid(pid, &status, 0);
} while (ret == -1 && errno == EINTR);
}

int ret, status;
do {
ret = waitpid(pid, &status, 0);
} while (ret == -1 && errno == EINTR);

reset_prog_mode();

/* TODO: hardly portable */
Expand Down

0 comments on commit 8a877d9

Please sign in to comment.