Skip to content

Commit

Permalink
std.os: spring-cleanup and specify organization
Browse files Browse the repository at this point in the history
- Alphabetically sort things, where reasonable.
- Document, that **only** non-portable posix things belong into posix.zig
  * If there is a portable abstraction, do not offer one in posix.zig
  * Reason: Prevent useless abstractions and needless strong coupling.
- Move posix-only functions into posix.zig, which have either incompatible
  or more extensive execution semantics than their counterparts and can be
  grouped into
  * File permission system
  * Process management
  * Memory management
  * IPC
  * Signaling

Work on ziglang#6600.
  • Loading branch information
matu3ba committed Mar 8, 2023
1 parent 06b2638 commit ca8d99f
Show file tree
Hide file tree
Showing 21 changed files with 997 additions and 942 deletions.
6 changes: 3 additions & 3 deletions lib/std/Thread.zig
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@ const LinuxThreadImpl = struct {
// map all memory needed without read/write permissions
// to avoid committing the whole region right away
// anonymous mapping ensures file descriptor limits are not exceeded
const mapped = os.mmap(
const mapped = os.posix.mmap(
null,
map_bytes,
os.PROT.NONE,
Expand All @@ -962,7 +962,7 @@ const LinuxThreadImpl = struct {
else => |e| return e,
};
assert(mapped.len >= map_bytes);
errdefer os.munmap(mapped);
errdefer os.posix.munmap(mapped);

// map everything but the guard page as read/write
os.mprotect(
Expand Down Expand Up @@ -1035,7 +1035,7 @@ const LinuxThreadImpl = struct {
}

fn join(self: Impl) void {
defer os.munmap(self.thread.mapped);
defer os.posix.munmap(self.thread.mapped);

var spin: u8 = 10;
while (true) {
Expand Down
45 changes: 23 additions & 22 deletions lib/std/child_process.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const unicode = std.unicode;
const io = std.io;
const fs = std.fs;
const os = std.os;
const posix = os.posix;
const process = std.process;
const File = std.fs.File;
const windows = os.windows;
Expand Down Expand Up @@ -70,7 +71,7 @@ pub const ChildProcess = struct {
/// Darwin-only. Start child process in suspended state as if SIGSTOP was sent.
start_suspended: bool = false,

pub const Arg0Expand = os.Arg0Expand;
pub const Arg0Expand = os.posix.Arg0Expand;

pub const SpawnError = error{
OutOfMemory,
Expand All @@ -86,8 +87,8 @@ pub const ChildProcess = struct {
/// Windows-only. `cwd` was provided, but the path did not exist when spawning the child process.
CurrentWorkingDirectoryUnlinked,
} ||
os.ExecveError ||
os.SetIdError ||
os.posix.ExecveError ||
os.posix.SetIdError ||
os.ChangeCurDirError ||
windows.CreateProcessError ||
windows.WaitForSingleObjectError ||
Expand Down Expand Up @@ -184,7 +185,7 @@ pub const ChildProcess = struct {
self.cleanupStreams();
return term;
}
try os.kill(self.id, os.SIG.TERM);
try posix.kill(self.pid, os.SIG.TERM);
try self.waitUnwrapped();
return self.term.?;
}
Expand Down Expand Up @@ -314,7 +315,7 @@ pub const ChildProcess = struct {
return term;
}

try self.waitUnwrapped();
try self.waitUnwrappedPosix();
return self.term.?;
}

Expand All @@ -336,11 +337,11 @@ pub const ChildProcess = struct {
return result;
}

fn waitUnwrapped(self: *ChildProcess) !void {
const res: os.WaitPidResult = if (comptime builtin.target.isDarwin())
fn waitUnwrappedPosix(self: *ChildProcess) !void {
const res: os.posix.WaitPidResult = if (comptime builtin.target.isDarwin())
try os.posix_spawn.waitpid(self.id, 0)
else
os.waitpid(self.id, 0);
os.posix.waitpid(self.id, 0);
const status = res.status;
self.cleanupStreams();
self.handleWaitResult(status);
Expand Down Expand Up @@ -418,13 +419,13 @@ pub const ChildProcess = struct {

fn spawnMacos(self: *ChildProcess) SpawnError!void {
const pipe_flags = if (io.is_async) os.O.NONBLOCK else 0;
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
errdefer if (self.stdin_behavior == StdIo.Pipe) destroyPipe(stdin_pipe);

const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
errdefer if (self.stdout_behavior == StdIo.Pipe) destroyPipe(stdout_pipe);

const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
errdefer if (self.stderr_behavior == StdIo.Pipe) destroyPipe(stderr_pipe);

const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
Expand Down Expand Up @@ -533,17 +534,17 @@ pub const ChildProcess = struct {

fn spawnPosix(self: *ChildProcess) SpawnError!void {
const pipe_flags = if (io.is_async) os.O.NONBLOCK else 0;
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
errdefer if (self.stdin_behavior == StdIo.Pipe) {
destroyPipe(stdin_pipe);
};

const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
errdefer if (self.stdout_behavior == StdIo.Pipe) {
destroyPipe(stdout_pipe);
};

const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
errdefer if (self.stderr_behavior == StdIo.Pipe) {
destroyPipe(stderr_pipe);
};
Expand Down Expand Up @@ -608,12 +609,12 @@ pub const ChildProcess = struct {
// end with eventfd
break :blk [2]os.fd_t{ fd, fd };
} else {
break :blk try os.pipe2(os.O.CLOEXEC);
break :blk try os.posix.pipe2(os.O.CLOEXEC);
}
};
errdefer destroyPipe(err_pipe);

const pid_result = try os.fork();
const pid_result = try os.posix.fork();
if (pid_result == 0) {
// we are the child
setUpChildIo(self.stdin_behavior, stdin_pipe[0], os.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
Expand All @@ -640,16 +641,16 @@ pub const ChildProcess = struct {
}

if (self.gid) |gid| {
os.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
os.posix.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
}

if (self.uid) |uid| {
os.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
os.posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
}

const err = switch (self.expand_arg0) {
.expand => os.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
.no_expand => os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
.expand => os.posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
.no_expand => os.posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
};
forkChildErrReport(err_pipe[1], err);
}
Expand Down Expand Up @@ -955,10 +956,10 @@ pub const ChildProcess = struct {

fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
switch (stdio) {
.Pipe => try os.dup2(pipe_fd, std_fileno),
.Pipe => try os.posix.dup2(pipe_fd, std_fileno),
.Close => os.close(std_fileno),
.Inherit => {},
.Ignore => try os.dup2(dev_null_fd, std_fileno),
.Ignore => try os.posix.dup2(dev_null_fd, std_fileno),
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions lib/std/crypto/tlcsprng.zig
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
if (want_fork_safety and maybe_have_wipe_on_fork or is_haiku) {
// Allocate a per-process page, madvise operates with page
// granularity.
wipe_mem = os.mmap(
wipe_mem = os.posix.mmap(
null,
@sizeOf(Context),
os.PROT.READ | os.PROT.WRITE,
Expand Down Expand Up @@ -111,11 +111,11 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
// Qemu user-mode emulation ignores any valid/invalid madvise
// hint and returns success. Check if this is the case by
// passing bogus parameters, we expect EINVAL as result.
if (os.madvise(wipe_mem.ptr, 0, 0xffffffff)) |_| {
if (os.posix.madvise(wipe_mem.ptr, 0, 0xffffffff)) |_| {
break :wof;
} else |_| {}

if (os.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV.WIPEONFORK)) |_| {
if (os.posix.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV.WIPEONFORK)) |_| {
return initAndFill(buffer);
} else |_| {}
}
Expand Down
20 changes: 10 additions & 10 deletions lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,9 @@ pub const StackIterator = struct {

if (native_os != .windows) {
if (native_os != .wasi) {
os.msync(aligned_memory, os.MSF.ASYNC) catch |err| {
os.posix.msync(aligned_memory, os.MSF.ASYNC) catch |err| {
switch (err) {
os.MSyncError.UnmappedMemory => {
os.posix.MSyncError.UnmappedMemory => {
return false;
},
else => unreachable,
Expand Down Expand Up @@ -1222,15 +1222,15 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
defer file.close();

const file_len = math.cast(usize, try file.getEndPos()) orelse math.maxInt(usize);
const mapped_mem = try os.mmap(
const mapped_mem = try os.posix.mmap(
null,
file_len,
os.PROT.READ,
os.MAP.SHARED,
file.handle,
0,
);
errdefer os.munmap(mapped_mem);
errdefer os.posix.munmap(mapped_mem);

return mapped_mem;
}
Expand Down Expand Up @@ -1491,7 +1491,7 @@ pub const ModuleDebugInfo = switch (native_os) {
}
self.ofiles.deinit();
allocator.free(self.symbols);
os.munmap(self.mapped_memory);
os.posix.munmap(self.mapped_memory);
}

fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !OFileInfo {
Expand Down Expand Up @@ -1798,7 +1798,7 @@ pub const ModuleDebugInfo = switch (native_os) {

fn deinit(self: *@This(), allocator: mem.Allocator) void {
self.dwarf.deinit(allocator);
os.munmap(self.mapped_memory);
os.posix.munmap(self.mapped_memory);
}

pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo {
Expand Down Expand Up @@ -1880,10 +1880,10 @@ pub fn maybeEnableSegfaultHandler() void {
var windows_segfault_handle: ?windows.HANDLE = null;

pub fn updateSegfaultHandler(act: ?*const os.Sigaction) error{OperationNotSupported}!void {
try os.sigaction(os.SIG.SEGV, act, null);
try os.sigaction(os.SIG.ILL, act, null);
try os.sigaction(os.SIG.BUS, act, null);
try os.sigaction(os.SIG.FPE, act, null);
try os.posix.sigaction(os.SIG.SEGV, act, null);
try os.posix.sigaction(os.SIG.ILL, act, null);
try os.posix.sigaction(os.SIG.BUS, act, null);
try os.posix.sigaction(os.SIG.FPE, act, null);
}

/// Attaches a global SIGSEGV handler which calls @panic("segmentation fault");
Expand Down
14 changes: 7 additions & 7 deletions lib/std/dynamic_library.zig
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ pub const ElfDynLib = struct {

// This one is to read the ELF info. We do more mmapping later
// corresponding to the actual LOAD sections.
const file_bytes = try os.mmap(
const file_bytes = try os.posix.mmap(
null,
mem.alignForward(size, mem.page_size),
os.PROT.READ,
os.MAP.PRIVATE,
fd,
0,
);
defer os.munmap(file_bytes);
defer os.posix.munmap(file_bytes);

const eh = @ptrCast(*elf.Ehdr, file_bytes.ptr);
if (!mem.eql(u8, eh.e_ident[0..4], elf.MAGIC)) return error.NotElfFile;
Expand Down Expand Up @@ -161,15 +161,15 @@ pub const ElfDynLib = struct {
const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation;

// Reserve the entire range (with no permissions) so that we can do MAP.FIXED below.
const all_loaded_mem = try os.mmap(
const all_loaded_mem = try os.posix.mmap(
null,
virt_addr_end,
os.PROT.NONE,
os.MAP.PRIVATE | os.MAP.ANONYMOUS,
-1,
0,
);
errdefer os.munmap(all_loaded_mem);
errdefer os.posix.munmap(all_loaded_mem);

const base = @ptrToInt(all_loaded_mem.ptr);

Expand All @@ -193,7 +193,7 @@ pub const ElfDynLib = struct {
const prot = elfToMmapProt(ph.p_flags);
if ((ph.p_flags & elf.PF_W) == 0) {
// If it does not need write access, it can be mapped from the fd.
_ = try os.mmap(
_ = try os.posix.mmap(
ptr,
extended_memsz,
prot,
Expand All @@ -202,7 +202,7 @@ pub const ElfDynLib = struct {
ph.p_offset - extra_bytes,
);
} else {
const sect_mem = try os.mmap(
const sect_mem = try os.posix.mmap(
ptr,
extended_memsz,
prot,
Expand Down Expand Up @@ -256,7 +256,7 @@ pub const ElfDynLib = struct {

/// Trusts the file
pub fn close(self: *ElfDynLib) void {
os.munmap(self.memory);
os.posix.munmap(self.memory);
self.* = undefined;
}

Expand Down
8 changes: 4 additions & 4 deletions lib/std/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ pub const Dir = struct {
}

if (has_flock_open_flags and flags.lock_nonblocking) {
var fl_flags = os.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
var fl_flags = os.posix.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
error.PermissionDenied => unreachable,
Expand All @@ -1203,7 +1203,7 @@ pub const Dir = struct {
else => |e| return e,
};
fl_flags &= ~@as(usize, os.O.NONBLOCK);
_ = os.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
_ = os.posix.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
error.PermissionDenied => unreachable,
Expand Down Expand Up @@ -1350,7 +1350,7 @@ pub const Dir = struct {
}

if (has_flock_open_flags and flags.lock_nonblocking) {
var fl_flags = os.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
var fl_flags = os.posix.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
error.PermissionDenied => unreachable,
Expand All @@ -1359,7 +1359,7 @@ pub const Dir = struct {
else => |e| return e,
};
fl_flags &= ~@as(usize, os.O.NONBLOCK);
_ = os.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
_ = os.posix.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
error.PermissionDenied => unreachable,
Expand Down
Loading

0 comments on commit ca8d99f

Please sign in to comment.