Commit 63b5c1d9 authored by Kirill Smelkov's avatar Kirill Smelkov

internal/syscall: Adjust Pipe to take flags

This way e.g. O_CLOEXEC can be passed in at pipe creation time removing
potential race in between pipe+fcntl vs exec in the middle. It will also
help in windows porting in follow-up patches becuase there is no fcntl
on Windows, but pipe with O_CLOEXEC semantic can be created directly
with flags=_O_NOINHERIT.
parent 534033a5
...@@ -26,4 +26,6 @@ ...@@ -26,4 +26,6 @@
#include <io.h> #include <io.h>
#define O_CLOEXEC _O_NOINHERIT
#endif // _NXD_LIBGOLANG_COMPAT_WIN_UNISTD_H #endif // _NXD_LIBGOLANG_COMPAT_WIN_UNISTD_H
...@@ -249,7 +249,7 @@ tuple<string, error> ReadFile(const string& path) { ...@@ -249,7 +249,7 @@ tuple<string, error> ReadFile(const string& path) {
tuple<File, File, error> Pipe() { tuple<File, File, error> Pipe() {
int vfd[2], syserr; int vfd[2], syserr;
syserr = sys::Pipe(vfd); syserr = sys::Pipe(vfd, 0);
if (syserr != 0) if (syserr != 0)
return make_tuple(nil, nil, fmt::errorf("pipe: %w", sys::NewErrno(syserr))); return make_tuple(nil, nil, fmt::errorf("pipe: %w", sys::NewErrno(syserr)));
......
// Copyright (C) 2021-2022 Nexedi SA and Contributors. // Copyright (C) 2021-2023 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
...@@ -160,10 +160,8 @@ void _init() { ...@@ -160,10 +160,8 @@ void _init() {
// create _wakerx <-> _waketx pipe; set _waketx to nonblocking mode // create _wakerx <-> _waketx pipe; set _waketx to nonblocking mode
int vfd[2]; int vfd[2];
if (sys::Pipe(vfd) < 0) if (sys::Pipe(vfd, O_CLOEXEC) < 0)
panic("pipe(_wakerx, _waketx)"); // TODO +syserr panic("pipe(_wakerx, _waketx)"); // TODO +syserr
if (sys::Fcntl(vfd[0], F_SETFD, FD_CLOEXEC) < 0)
panic("fcntl(_wakerx, FD_CLOEXEC)"); // TODO +syserr
error err; error err;
tie(_wakerx, err) = os::NewFile(vfd[0], "_wakerx"); tie(_wakerx, err) = os::NewFile(vfd[0], "_wakerx");
if (err != nil) if (err != nil)
...@@ -171,8 +169,6 @@ void _init() { ...@@ -171,8 +169,6 @@ void _init() {
_waketx = vfd[1]; _waketx = vfd[1];
if (sys::Fcntl(_waketx, F_SETFL, O_NONBLOCK) < 0) if (sys::Fcntl(_waketx, F_SETFL, O_NONBLOCK) < 0)
panic("fcntl(_waketx, O_NONBLOCK)"); // TODO +syserr panic("fcntl(_waketx, O_NONBLOCK)"); // TODO +syserr
if (sys::Fcntl(_waketx, F_SETFD, FD_CLOEXEC) < 0)
panic("fcntl(_waketx, FD_CLOEXEC)"); // TODO +syserr
_actIgnore.sa_handler = SIG_IGN; _actIgnore.sa_handler = SIG_IGN;
_actIgnore.sa_flags = 0; _actIgnore.sa_flags = 0;
......
// Copyright (C) 2021-2022 Nexedi SA and Contributors. // Copyright (C) 2021-2023 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
...@@ -126,9 +126,30 @@ int Open(const char *path, int flags, mode_t mode) { ...@@ -126,9 +126,30 @@ int Open(const char *path, int flags, mode_t mode) {
return fd; return fd;
} }
__Errno Pipe(int vfd[2]) { __Errno Pipe(int vfd[2], int flags) {
// supported flags: O_CLOEXEC
if (flags & ~(O_CLOEXEC))
return -EINVAL;
int save_errno = errno; int save_errno = errno;
int err = ::pipe(vfd); int err;
#ifdef __linux__
err = ::pipe2(vfd, flags);
#else
err = ::pipe(vfd);
if (err)
goto out;
if (flags & O_CLOEXEC) {
for (int i=0; i<2; i++) {
err = Fcntl(vfd[i], F_SETFD, FD_CLOEXEC);
if (err) {
Close(vfd[0]);
Close(vfd[1]);
goto out;
}
}
}
out:
#endif
if (err == -1) if (err == -1)
err = -errno; err = -errno;
errno = save_errno; errno = save_errno;
......
...@@ -66,7 +66,7 @@ LIBGOLANG_API __Errno Close(int fd); ...@@ -66,7 +66,7 @@ LIBGOLANG_API __Errno Close(int fd);
LIBGOLANG_API __Errno Fcntl(int fd, int cmd, int arg); LIBGOLANG_API __Errno Fcntl(int fd, int cmd, int arg);
LIBGOLANG_API __Errno Fstat(int fd, struct ::stat *out_st); LIBGOLANG_API __Errno Fstat(int fd, struct ::stat *out_st);
LIBGOLANG_API int/*fd|err*/ Open(const char *path, int flags, mode_t mode); LIBGOLANG_API int/*fd|err*/ Open(const char *path, int flags, mode_t mode);
LIBGOLANG_API __Errno Pipe(int vfd[2]); LIBGOLANG_API __Errno Pipe(int vfd[2], int flags);
LIBGOLANG_API __Errno Sigaction(int signo, const struct ::sigaction *act, struct ::sigaction *oldact); LIBGOLANG_API __Errno Sigaction(int signo, const struct ::sigaction *act, struct ::sigaction *oldact);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment