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 11, 2023
1 parent 4ea2f44 commit c65b248
Show file tree
Hide file tree
Showing 20 changed files with 990 additions and 934 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
37 changes: 19 additions & 18 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 @@ -179,7 +180,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 @@ -309,7 +310,7 @@ pub const ChildProcess = struct {
return term;
}

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

Expand All @@ -331,8 +332,8 @@ pub const ChildProcess = struct {
return result;
}

fn waitUnwrapped(self: *ChildProcess) !void {
const res: os.WaitPidResult = os.waitpid(self.id, 0);
fn waitUnwrappedPosix(self: *ChildProcess) !void {
const res: os.posix.WaitPidResult = os.posix.waitpid(self.id, 0);
const status = res.status;
self.cleanupStreams();
self.handleWaitResult(status);
Expand Down Expand Up @@ -410,17 +411,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 @@ -485,12 +486,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 @@ -517,16 +518,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 @@ -832,10 +833,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
12 changes: 6 additions & 6 deletions lib/std/fs/file.zig
Original file line number Diff line number Diff line change
Expand Up @@ -399,25 +399,25 @@ pub const File = struct {
return Stat.fromSystem(st);
}

pub const ChmodError = std.os.FChmodError;
pub const ChmodError = std.os.posix.FChmodError;

/// Changes the mode of the file.
/// The process must have the correct privileges in order to do this
/// successfully, or must have the effective user ID matching the owner
/// of the file.
pub fn chmod(self: File, new_mode: Mode) ChmodError!void {
try os.fchmod(self.handle, new_mode);
try os.posix.fchmod(self.handle, new_mode);
}

pub const ChownError = std.os.FChownError;
pub const ChownError = std.os.posix.FChownError;

/// Changes the owner and group of the file.
/// The process must have the correct privileges in order to do this
/// successfully. The group may be changed by the owner of the file to
/// any group of which the owner is a member. If the owner or group is
/// specified as `null`, the ID is not changed.
pub fn chown(self: File, owner: ?Uid, group: ?Gid) ChownError!void {
try os.fchown(self.handle, owner, group);
try os.posix.fchown(self.handle, owner, group);
}

/// Cross-platform representation of permissions on a file.
Expand Down Expand Up @@ -899,7 +899,7 @@ pub const File = struct {
};
}

pub const UpdateTimesError = os.FutimensError || windows.SetFileTimeError;
pub const UpdateTimesError = os.posix.FutimensError || windows.SetFileTimeError;

/// The underlying file system may have a different granularity than nanoseconds,
/// and therefore this function cannot guarantee any precision will be stored.
Expand Down Expand Up @@ -928,7 +928,7 @@ pub const File = struct {
.tv_nsec = math.cast(isize, @mod(mtime, std.time.ns_per_s)) orelse maxInt(isize),
},
};
try os.futimens(self.handle, &times);
try os.posix.futimens(self.handle, &times);
}

/// Reads all the bytes from the current position to the end of the file.
Expand Down
Loading

0 comments on commit c65b248

Please sign in to comment.