commit 2b442f74442f969930e2ce424287c45745b67a46
parent 487d842b528c2d851cd35ae9c07835da9af982c7
Author: Egor <egor@opensrc.club>
Date: Tue, 10 May 2022 20:03:54 +0300
fs: invert the meaning of NOCTTY/CLOEXEC in flags
the same reasoning as with sockets and pipes
Signed-off-by: Egor <egor@opensrc.club>
Diffstat:
8 files changed, 26 insertions(+), 44 deletions(-)
diff --git a/fs/types.ha b/fs/types.ha
@@ -168,13 +168,15 @@ export fn dirent_finish(e: *dirent) void = free(e.name);
// Flags to use for opening a file. Not all operating systems support all flags;
// at a minimum, RDONLY, WRONLY, RDWR, and CREATE will be supported.
+// Note that NOCTTY and CLOEXEC are on by default, and the CTTY/NOCLOEXEC flags
+// respectively disable them.
export type flags = enum int {
RDONLY = 0,
WRONLY = 1,
RDWR = 2,
CREATE = 0o100,
EXCL = 0o200,
- NOCTTY = 0o400,
+ CTTY = 0o400,
TRUNC = 0o1000,
APPEND = 0o2000,
NONBLOCK = 0o4000,
@@ -184,7 +186,7 @@ export type flags = enum int {
DIRECTORY = 0o200000,
NOFOLLOW = 0o400000,
NOATIME = 0o1000000,
- CLOEXEC = 0o2000000,
+ NOCLOEXEC = 0o2000000,
PATH = 0o10000000,
TMPFILE = 0o20200000,
};
diff --git a/os/+freebsd/dirfdfs.ha b/os/+freebsd/dirfdfs.ha
@@ -19,11 +19,6 @@ type os_filesystem = struct {
// Opens a file descriptor as an [[fs::fs]]. This file descriptor must be a
// directory file. The file will be closed when the fs is closed.
-//
-// If no other flags are provided to [[fs::open]] and [[fs::create]] when used with
-// a dirfdfs, [[fs::flags::NOCTTY]] and [[fs::flags::CLOEXEC]] are used when opening
-// the file. If you pass your own flags, it is recommended that you add these
-// unless you know that you do not want them.
export fn dirfdopen(fd: io::file) *fs::fs = {
let ofs = alloc(os_filesystem { ... });
let fs = static_dirfdopen(fd, ofs);
@@ -112,7 +107,7 @@ fn _fs_open(
};
fn fsflags_to_bsd(flags: fs::flags) int = {
- let out = 0;
+ let out = rt::O_NOCTTY | rt::O_CLOEXEC;
if (flags & fs::flags::WRONLY > 0) {
out |= rt::O_WRONLY;
};
@@ -125,8 +120,8 @@ fn fsflags_to_bsd(flags: fs::flags) int = {
if (flags & fs::flags::EXCL > 0) {
out |= rt::O_EXCL;
};
- if (flags & fs::flags::NOCTTY > 0) {
- out |= rt::O_NOCTTY;
+ if (flags & fs::flags::CTTY > 0) {
+ out &= ~rt::O_NOCTTY;
};
if (flags & fs::flags::TRUNC > 0) {
out |= rt::O_TRUNC;
@@ -152,8 +147,8 @@ fn fsflags_to_bsd(flags: fs::flags) int = {
if (flags & fs::flags::NOFOLLOW > 0) {
out |= rt::O_NOFOLLOW;
};
- if (flags & fs::flags::CLOEXEC > 0) {
- out |= rt::O_CLOEXEC;
+ if (flags & fs::flags::NOCLOEXEC > 0) {
+ out &= ~rt::O_CLOEXEC;
};
if (flags & fs::flags::PATH > 0) {
abort("fs::flags::PATH is not supported on FreeBSD");
@@ -173,12 +168,10 @@ fn fs_open_file(
flags: fs::flags...
) (io::file | fs::error) = {
let oflags = fs::flags::RDONLY;
- if (len(flags) == 0z) {
- oflags |= fs::flags::NOCTTY | fs::flags::CLOEXEC;
- };
for (let i = 0z; i < len(flags); i += 1z) {
oflags |= flags[i];
};
+ oflags ^= fs::flags::CTTY | fs::flags::NOCLOEXEC; // invert NOCTTY/CLOEXEC
return _fs_open(fs, path, fsflags_to_bsd(oflags), 0);
};
@@ -194,13 +187,14 @@ fn fs_create_file(
mode: fs::mode,
flags: fs::flags...
) (io::file | fs::error) = {
- let oflags = fs::flags::RDONLY;
+ let oflags = 0;
if (len(flags) == 0z) {
- oflags |= fs::flags::NOCTTY | fs::flags::CLOEXEC;
+ oflags |= fs::flags::WRONLY;
};
for (let i = 0z; i < len(flags); i += 1z) {
oflags |= flags[i];
};
+ oflags ^= fs::flags::CTTY | fs::flags::NOCLOEXEC; // invert NOCTTY/CLOEXEC
oflags |= fs::flags::CREATE;
return _fs_open(fs, path, fsflags_to_bsd(oflags), mode)?;
};
diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha
@@ -51,11 +51,6 @@ type os_filesystem = struct {
// Opens a file descriptor as an [[fs::fs]]. This file descriptor must be a
// directory file. The file will be closed when the fs is closed.
-//
-// If no other flags are provided to [[fs::open]] and [[fs::create]] when used with
-// a dirfdfs, [[fs::flags::NOCTTY]] and [[fs::flags::CLOEXEC]] are used when opening
-// the file. If you pass your own flags, it is recommended that you add these
-// unless you know that you do not want them.
export fn dirfdopen(fd: io::file, resolve: resolve_flags...) *fs::fs = {
let ofs = alloc(os_filesystem { ... });
let fs = static_dirfdopen(fd, ofs);
@@ -180,15 +175,11 @@ fn fs_open_file(
path: str,
flags: fs::flags...
) (io::file | fs::error) = {
- let oflags = 0;
- if (len(flags) == 0z) {
- oflags |= (fs::flags::NOCTTY
- | fs::flags::CLOEXEC
- | fs::flags::RDONLY): int;
- };
+ let oflags = fs::flags::RDONLY: int;
for (let i = 0z; i < len(flags); i += 1z) {
oflags |= flags[i]: int;
};
+ oflags ^= fs::flags::CTTY | fs::flags::NOCLOEXEC; // invert NOCTTY/CLOEXEC
if ((oflags: fs::flags & fs::flags::DIRECTORY) == fs::flags::DIRECTORY) {
// This is arch-specific
@@ -217,13 +208,12 @@ fn fs_create_file(
) (io::file | fs::error) = {
let oflags = 0;
if (len(flags) == 0z) {
- oflags |= (fs::flags::NOCTTY
- | fs::flags::CLOEXEC
- | fs::flags::WRONLY): int;
+ oflags |= fs::flags::WRONLY;
};
for (let i = 0z; i < len(flags); i += 1z) {
oflags |= flags[i]: int;
};
+ oflags ^= fs::flags::CTTY | fs::flags::NOCLOEXEC; // invert NOCTTY/CLOEXEC
oflags |= fs::flags::CREATE: int;
let oh = rt::open_how {
diff --git a/os/fs.ha b/os/fs.ha
@@ -69,19 +69,15 @@ export fn readlink(path: str) (str | fs::error) = fs::readlink(cwd, path);
// Opens a file.
//
-// If no flags are provided, [[fs::flags::RDONLY]], [[fs::flags::NOCTTY]],
-// [[fs::flags::CLOEXEC]] are used when opening the file. If you pass your own
-// flags, it is recommended that you add the latter two unless you know that you
-// do not want them.
+// If no flags are provided, [[fs::flags::RDONLY]] is used when opening the
+// file.
export fn open(path: str, flags: fs::flags...) (io::file | fs::error) =
fs::open_file(cwd, path, flags...);
// Creates a new file and opens it for writing.
//
-// If no flags are provided, [[fs::flags::WRONLY]], [[fs::flags::NOCTTY]],
-// [[fs::flags::CLOEXEC]] are used when opening the file. If you pass your own
-// flags, it is recommended that you add the latter two unless you know that you
-// do not want them.
+// If no flags are provided, [[fs::flags::WRONLY]] is used when opening the
+// file.
//
// Only the permission bits of the mode are used. If other bits are set, they
// are discarded.
diff --git a/temp/+freebsd.ha b/temp/+freebsd.ha
@@ -53,7 +53,7 @@ export fn named(
assert(len(mode) == 0 || len(mode) == 1);
let fmode = if (len(mode) != 0) mode[0] else 0o644: fs::mode;
- let oflags = fs::flags::EXCL | fs::flags::CLOEXEC;
+ let oflags = fs::flags::EXCL;
if (iomode == io::mode::RDWR) {
oflags |= fs::flags::RDWR;
} else {
diff --git a/temp/+linux.ha b/temp/+linux.ha
@@ -31,7 +31,7 @@ export fn file(
assert(iomode == io::mode::WRITE || iomode == io::mode::RDWR);
assert(len(mode) == 0 || len(mode) == 1);
let fmode = if (len(mode) != 0) mode[0] else 0o644: fs::mode;
- let oflags = fs::flags::TMPFILE | fs::flags::EXCL | fs::flags::CLOEXEC;
+ let oflags = fs::flags::TMPFILE | fs::flags::EXCL;
if (iomode == io::mode::RDWR) {
oflags |= fs::flags::RDWR;
} else {
@@ -67,7 +67,7 @@ export fn named(
assert(len(mode) == 0 || len(mode) == 1);
let fmode = if (len(mode) != 0) mode[0] else 0o644: fs::mode;
- let oflags = fs::flags::EXCL | fs::flags::CLOEXEC;
+ let oflags = fs::flags::EXCL;
if (iomode == io::mode::RDWR) {
oflags |= fs::flags::RDWR;
} else {
diff --git a/unix/tty/+freebsd/open.ha b/unix/tty/+freebsd/open.ha
@@ -9,7 +9,7 @@ use os;
// Returns a stream connected to the TTY of the current process. The caller must
// close it using [[io::close]].
export fn open() (io::file | error) = {
- match (os::open("/dev/tty", fs::flags::RDWR, fs::flags::CLOEXEC)) {
+ match (os::open("/dev/tty", fs::flags::RDWR)) {
case let f: io::file =>
return f;
case fs::error =>
diff --git a/unix/tty/+linux/open.ha b/unix/tty/+linux/open.ha
@@ -11,7 +11,7 @@ use os;
// Returns a stream connected to the TTY of the current process. The caller must
// close it using [[io::close]].
export fn open() (io::file | error) = {
- match (os::open("/dev/tty", fs::flags::RDWR, fs::flags::CLOEXEC)) {
+ match (os::open("/dev/tty", fs::flags::RDWR)) {
case let f: io::file =>
return f;
case fs::error =>