hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit c308da0802b3c24a3aa6dbf944c256fcf03b88f0
parent 9543f477330e07de1b50bc6eb0e3bed97f748246
Author: Egor <egor@opensrc.club>
Date:   Tue, 10 May 2022 20:03:56 +0300

os::exec: clear FD_CLOEXEC when dup2ing fd to itself

If you try to dup2 a fd to itself, it's a no-op. Since we want the child
process to inherit the fd, we must ensure to clear CLOEXEC in this case.

posix_spawn_file_actions_adddup2 in musl and glibc works similarly.

Signed-off-by: Egor <egor@opensrc.club>

Diffstat:
Mos/exec/exec+freebsd.ha | 18++++++++++++++----
Mos/exec/exec+linux.ha | 18++++++++++++++----
Mrt/+linux/types.ha | 2++
3 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/os/exec/exec+freebsd.ha b/os/exec/exec+freebsd.ha @@ -119,10 +119,20 @@ fn platform_exec(cmd: *command) error = { continue; }; - match (rt::dup2(from, cmd.files[i].1)) { - case int => void; - case let e: rt::errno => - return errors::errno(e); + if (cmd.files[i].1 == from) { + let flags = match (rt::fcntl(from, rt::F_GETFD, 0)) { + case let flags: int => + yield flags; + case let e: rt::errno => + return errors::errno(e); + }; + rt::fcntl(from, rt::F_SETFD, flags & ~rt::FD_CLOEXEC)!; + } else { + match (rt::dup2(from, cmd.files[i].1)) { + case int => void; + case let e: rt::errno => + return errors::errno(e); + }; }; }; diff --git a/os/exec/exec+linux.ha b/os/exec/exec+linux.ha @@ -120,10 +120,20 @@ fn platform_exec(cmd: *command) error = { continue; }; - match (rt::dup2(from, cmd.files[i].1)) { - case int => void; - case let e: rt::errno => - return errors::errno(e); + if (cmd.files[i].1 == from) { + let flags = match (rt::fcntl(from, rt::F_GETFD, 0)) { + case let flags: int => + yield flags; + case let e: rt::errno => + return errors::errno(e); + }; + rt::fcntl(from, rt::F_SETFD, flags & ~rt::FD_CLOEXEC)!; + } else { + match (rt::dup2(from, cmd.files[i].1)) { + case int => void; + case let e: rt::errno => + return errors::errno(e); + }; }; }; diff --git a/rt/+linux/types.ha b/rt/+linux/types.ha @@ -242,6 +242,8 @@ export def F_SETOWN_EX: int = 15; export def F_GETOWN_EX: int = 16; export def F_GETOWNER_UIDS: int = 17; +export def FD_CLOEXEC: int = 1; + export type st_flock = struct { l_type: i16, l_whence: i16,