Skip to content

Commit

Permalink
FEAT: posibility to use pipe() where pipe2() is not available
Browse files Browse the repository at this point in the history
  • Loading branch information
Oldes committed Oct 26, 2017
1 parent d78caf6 commit 6a8303c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 22 deletions.
61 changes: 49 additions & 12 deletions src/os/posix/host-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,42 @@ static void *Task_Ready;
//SetEvent(Task_Ready);
}

//Helper function for OS_Create_Process:
//see: https://stackoverflow.com/questions/41976446/pipe2-vs-pipe-fcntl-why-different
static inline REBOOL Open_Pipe_Fails(int pipefd[2]) {
#ifdef USE_OLD_PIPE
//
// NOTE: pipe() is POSIX, but pipe2() is Linux-specific. With pipe() it
// takes an additional call to fcntl() to request non-blocking behavior,
// so it's a small amount more work. However, there are other flags which
// if aren't passed atomically at the moment of opening allow for a race
// condition in threading if split, e.g. FD_CLOEXEC.
//
// (If you don't have FD_CLOEXEC set on the file descriptor, then all
// instances of CALL will act as a /WAIT.)
//
// At time of writing, this is mostly academic...but the code needed to be
// patched to work with pipe() since some older libcs do not have pipe2().
// So the ability to target both are kept around, saving the pipe2() call
// for later Linuxes known to have it (and O_CLOEXEC).
//
if (pipe(pipefd) < 0)
return TRUE;
int direction; // READ=0, WRITE=1
for (direction = 0; direction < 2; ++direction) {
int oldflags = fcntl(pipefd[direction], F_GETFD);
if (oldflags < 0)
return TRUE;
if (fcntl(pipefd[direction], F_SETFD, oldflags | FD_CLOEXEC) < 0)
return TRUE;
}
#else
if (pipe2(pipefd, O_CLOEXEC))
return TRUE;
#endif
return FALSE;
}


/***********************************************************************
**
Expand Down Expand Up @@ -641,26 +677,23 @@ static void *Task_Ready;
if (flags & FLAG_SHELL) flag_shell = TRUE;
if (flags & FLAG_INFO) flag_info = TRUE;

if (input_type == STRING_TYPE
|| input_type == BINARY_TYPE) {
if (pipe2(stdin_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
if (input_type == STRING_TYPE || input_type == BINARY_TYPE) {
if (Open_Pipe_Fails(stdin_pipe)) {
goto stdin_pipe_err;
}
}
if (output_type == STRING_TYPE
|| output_type == BINARY_TYPE) {
if (pipe2(stdout_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
if (output_type == STRING_TYPE || output_type == BINARY_TYPE) {
if (Open_Pipe_Fails(stdout_pipe)) {
goto stdout_pipe_err;
}
}
if (err_type == STRING_TYPE
|| err_type == BINARY_TYPE) {
if (pipe2(stderr_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
if (err_type == STRING_TYPE || err_type == BINARY_TYPE) {
if (Open_Pipe_Fails(stderr_pipe)) {
goto stderr_pipe_err;
}
}

if (pipe2(info_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
if (Open_Pipe_Fails(info_pipe)) {
goto info_pipe_err;
}

Expand Down Expand Up @@ -760,7 +793,9 @@ static void *Task_Ready;
sh = getenv("SHELL");
if (sh == NULL) {
int err = 2; /* shell does not exist */
write(info_pipe[W], &err, sizeof(err));
if(write(info_pipe[W], &err, sizeof(err)) == -1) {
//nothing there... just to avoid "unused-result" compiler warning
}
exit(EXIT_FAILURE);
}
argv_new = OS_Make((argc + 3) * sizeof(char*));
Expand All @@ -773,7 +808,9 @@ static void *Task_Ready;
execvp(argv[0], argv);
}
child_error:
write(info_pipe[W], &errno, sizeof(errno));
if(write(info_pipe[W], &errno, sizeof(errno)) == -1) {
//nothing there... just to avoid "unused-result" compiler warning
}
exit(EXIT_FAILURE); /* get here only when exec fails */
} else if (fpid > 0) {
/* parent */
Expand Down
21 changes: 11 additions & 10 deletions src/tools/systems.r
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ REBOL [
systems: [
[plat os-name os-base build-flags]
[0.1.03 "amiga" posix [BEN HID NPS +SC CMT COP -SP -LM]]
[0.2.04 "osx" posix [BEN +OS NCM -LM]] ; OSX/PPC; no shared lib possible
[0.2.05 "osxi" posix [LEN ARC +O1 NPS PIC NCM HID STX -LM]]
[0.2.40 "osx_x64" posix [LEN +O1 NPS PIC NCM HID STX -LM]]
[0.2.04 "osx" posix [BEN +OS NCM -LM UOP]] ; OSX/PPC; no shared lib possible
[0.2.05 "osxi" posix [LEN ARC +O1 NPS PIC NCM HID STX -LM UOP]]
[0.2.40 "osx_x64" posix [LEN +O1 NPS PIC NCM HID STX -LM UOP]]
[0.3.01 "win32" win32 [LEN +O2 UNI M32 W32 CON S4M EXE DIR -LM]]
[0.3.40 "win32_x64" win32 [LEN +O2 UNI M64 P64 W32 CON S4M EXE DIR -LM]]
[0.4.02 "linux" posix [LEN +O2 PIC LDL ST1 -LM]] ; libc 2.3
[0.4.03 "linux" posix [LEN +O2 PIC HID LDL ST1 -LM]] ; libc 2.5
[0.4.04 "linux" posix [LEN +O2 PIC HID LDL ST1 M32 -LM]] ; libc 2.11
[0.4.10 "linux_ppc" posix [BEN +O1 PIC HID LDL ST1 -LM]]
[0.4.20 "linux_arm" posix [LEN +O2 PIC HID LDL ST1 -LM]]
[0.4.21 "linux_arm" posix [LEN +O2 PIE HID LDL ST1 -LM]] ; bionic (Android)
[0.4.30 "linux_mips" posix [LEN +O2 PIC HID LDL ST1 -LM]]
[0.4.40 "linux_x64" posix [LEN +O2 PIC HID LDL ST1 -LM]]
[0.4.03 "linux" posix [LEN +O2 PIC LDL ST1 -LM HID]] ; libc 2.5
[0.4.04 "linux" posix [LEN +O2 PIC LDL ST1 -LM HID M32]] ; libc 2.11
[0.4.10 "linux_ppc" posix [BEN +O1 PIC LDL ST1 -LM HID]]
[0.4.20 "linux_arm" posix [LEN +O2 PIC LDL ST1 -LM HID]]
[0.4.21 "linux_arm" posix [LEN +O2 PIE LDL ST1 -LM HID]] ; bionic (Android)
[0.4.30 "linux_mips" posix [LEN +O2 PIC LDL ST1 -LM HID]]
[0.4.40 "linux_x64" posix [LEN +O2 PIC LDL ST1 -LM HID]]
[0.5.75 "haiku" posix [LEN +O2 ST1 NWK]]
[0.7.02 "freebsd" posix [LEN +O1 ST1 -LM]]
[0.7.40 "freebsd_x64" posix [LEN +O1 ST1 -LM]]
Expand Down Expand Up @@ -62,6 +62,7 @@ compile-flags: [
M64: "-m64" ; use 64-bit memory model
LEN: "-DENDIAN_LITTLE" ; uses little endian byte order
BEN: "-DENDIAN_BIG" ; uses big endian byte order
UOP: "-DUSE_OLD_PIPE" ; use pipe() instead of pipe2(), which may not be supported
]

linker-flags: [
Expand Down

0 comments on commit 6a8303c

Please sign in to comment.