diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2021-02-16 15:15:00 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2021-02-16 15:50:15 +0100 |
| commit | bf95eb1c09c6a3bf6a04dcc4ca55a78ade32d6a2 (patch) | |
| tree | 745d52c9938183e822fb5dea48e93b5360e82978 /src/drivers/Posix | |
| parent | 1298bf00f577292a46c4ff22ff46a0e2ee3ba30d (diff) | |
Remove FL_CFG_SYS_POSIX preprocessor variable from fl_open_uri.cxx
Diffstat (limited to 'src/drivers/Posix')
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.cxx | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index 20b7aef28..75df02e7a 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -1,7 +1,7 @@ // -// Definition of Apple Darwin system driver. +// Definition of Posix system driver (used by both the X11 and macOS platforms). // -// Copyright 1998-2020 by Bill Spitzak and others. +// Copyright 1998-2021 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -33,6 +33,11 @@ #include <pwd.h> #include <unistd.h> #include <time.h> +#include <unistd.h> +#include <sys/wait.h> +#include <signal.h> +#include <fcntl.h> +#include <errno.h> // // Define missing POSIX/XPG4 macros as needed... @@ -93,3 +98,76 @@ void Fl_Posix_System_Driver::gettime(time_t *sec, int *usec) { *sec = tv.tv_sec; *usec = tv.tv_usec; } + +// Run the specified program, returning 1 on success and 0 on failure +int Fl_Posix_System_Driver::run_program(const char *program, char **argv, char *msg, int msglen) { + pid_t pid; // Process ID of first child + int status; // Exit status from first child + sigset_t set, oldset; // Signal masks + + + // Block SIGCHLD while we run the program... + // + // Note that I only use the POSIX signal APIs, however older operating + // systems may either not support POSIX signals or have side effects. + // IRIX, for example, provides three separate and incompatible signal + // APIs, so it is possible that an application setting a signal handler + // via signal() or sigset() will not have its SIGCHLD signals blocked... + + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, &oldset); + + // Create child processes that actually run the program for us... + if ((pid = fork()) == 0) { + // First child comes here, fork a second child and exit... + if (!fork()) { + // Second child comes here, redirect stdin/out/err to /dev/null... + close(0); + ::open("/dev/null", O_RDONLY); + + close(1); + ::open("/dev/null", O_WRONLY); + + close(2); + ::open("/dev/null", O_WRONLY); + + // Detach from the current process group... + setsid(); + + // Run the program... + execv(program, argv); + _exit(0); + } else { + // First child gets here, exit immediately... + _exit(0); + } + } else if (pid < 0) { + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating failure... + return 0; + } + + // Wait for the first child to exit... + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { + // Someone else grabbed the child status... + if (msg) snprintf(msg, msglen, "waitpid(%ld) failed: %s", (long)pid, + strerror(errno)); + + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating failure... + return 0; + } + } + + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating success... + return 1; +} |
