Skip to content

Commit 52ca8be

Browse files
author
Jan Philipp Hafer
committed
std.os: spring-cleanup and specify organization
- 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 #6600.
1 parent 36d47dd commit 52ca8be

21 files changed

+999
-938
lines changed

lib/std/Thread.zig

+6-3
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,8 @@ const LinuxThreadImpl = struct {
945945

946946
// map all memory needed without read/write permissions
947947
// to avoid committing the whole region right away
948-
const mapped = os.mmap(
948+
// anonymous mapping ensures file descriptor limits are not exceeded
949+
const mapped = os.posix.mmap(
949950
null,
950951
map_bytes,
951952
os.PROT.NONE,
@@ -956,10 +957,12 @@ const LinuxThreadImpl = struct {
956957
error.MemoryMappingNotSupported => unreachable,
957958
error.AccessDenied => unreachable,
958959
error.PermissionDenied => unreachable,
960+
error.ProcessFdQuotaExceeded => unreachable,
961+
error.SystemFdQuotaExceeded => unreachable,
959962
else => |e| return e,
960963
};
961964
assert(mapped.len >= map_bytes);
962-
errdefer os.munmap(mapped);
965+
errdefer os.posix.munmap(mapped);
963966

964967
// map everything but the guard page as read/write
965968
os.mprotect(
@@ -1032,7 +1035,7 @@ const LinuxThreadImpl = struct {
10321035
}
10331036

10341037
fn join(self: Impl) void {
1035-
defer os.munmap(self.thread.mapped);
1038+
defer os.posix.munmap(self.thread.mapped);
10361039

10371040
var spin: u8 = 10;
10381041
while (true) {

lib/std/child_process.zig

+23-22
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const unicode = std.unicode;
55
const io = std.io;
66
const fs = std.fs;
77
const os = std.os;
8+
const posix = os.posix;
89
const process = std.process;
910
const File = std.fs.File;
1011
const windows = os.windows;
@@ -70,7 +71,7 @@ pub const ChildProcess = struct {
7071
/// Darwin-only. Start child process in suspended state as if SIGSTOP was sent.
7172
start_suspended: bool = false,
7273

73-
pub const Arg0Expand = os.Arg0Expand;
74+
pub const Arg0Expand = os.posix.Arg0Expand;
7475

7576
pub const SpawnError = error{
7677
OutOfMemory,
@@ -86,8 +87,8 @@ pub const ChildProcess = struct {
8687
/// Windows-only. `cwd` was provided, but the path did not exist when spawning the child process.
8788
CurrentWorkingDirectoryUnlinked,
8889
} ||
89-
os.ExecveError ||
90-
os.SetIdError ||
90+
os.posix.ExecveError ||
91+
os.posix.SetIdError ||
9192
os.ChangeCurDirError ||
9293
windows.CreateProcessError ||
9394
windows.WaitForSingleObjectError ||
@@ -184,7 +185,7 @@ pub const ChildProcess = struct {
184185
self.cleanupStreams();
185186
return term;
186187
}
187-
try os.kill(self.id, os.SIG.TERM);
188+
try posix.kill(self.pid, os.SIG.TERM);
188189
try self.waitUnwrapped();
189190
return self.term.?;
190191
}
@@ -314,7 +315,7 @@ pub const ChildProcess = struct {
314315
return term;
315316
}
316317

317-
try self.waitUnwrapped();
318+
try self.waitUnwrappedPosix();
318319
return self.term.?;
319320
}
320321

@@ -336,11 +337,11 @@ pub const ChildProcess = struct {
336337
return result;
337338
}
338339

339-
fn waitUnwrapped(self: *ChildProcess) !void {
340-
const res: os.WaitPidResult = if (comptime builtin.target.isDarwin())
340+
fn waitUnwrappedPosix(self: *ChildProcess) !void {
341+
const res: os.posix.WaitPidResult = if (comptime builtin.target.isDarwin())
341342
try os.posix_spawn.waitpid(self.id, 0)
342343
else
343-
os.waitpid(self.id, 0);
344+
os.posix.waitpid(self.id, 0);
344345
const status = res.status;
345346
self.cleanupStreams();
346347
self.handleWaitResult(status);
@@ -418,13 +419,13 @@ pub const ChildProcess = struct {
418419

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

424-
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
425+
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
425426
errdefer if (self.stdout_behavior == StdIo.Pipe) destroyPipe(stdout_pipe);
426427

427-
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
428+
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
428429
errdefer if (self.stderr_behavior == StdIo.Pipe) destroyPipe(stderr_pipe);
429430

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

534535
fn spawnPosix(self: *ChildProcess) SpawnError!void {
535536
const pipe_flags = if (io.is_async) os.O.NONBLOCK else 0;
536-
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
537+
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
537538
errdefer if (self.stdin_behavior == StdIo.Pipe) {
538539
destroyPipe(stdin_pipe);
539540
};
540541

541-
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
542+
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
542543
errdefer if (self.stdout_behavior == StdIo.Pipe) {
543544
destroyPipe(stdout_pipe);
544545
};
545546

546-
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
547+
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.posix.pipe2(pipe_flags) else undefined;
547548
errdefer if (self.stderr_behavior == StdIo.Pipe) {
548549
destroyPipe(stderr_pipe);
549550
};
@@ -608,12 +609,12 @@ pub const ChildProcess = struct {
608609
// end with eventfd
609610
break :blk [2]os.fd_t{ fd, fd };
610611
} else {
611-
break :blk try os.pipe2(os.O.CLOEXEC);
612+
break :blk try os.posix.pipe2(os.O.CLOEXEC);
612613
}
613614
};
614615
errdefer destroyPipe(err_pipe);
615616

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

642643
if (self.gid) |gid| {
643-
os.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
644+
os.posix.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
644645
}
645646

646647
if (self.uid) |uid| {
647-
os.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
648+
os.posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
648649
}
649650

650651
const err = switch (self.expand_arg0) {
651-
.expand => os.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
652-
.no_expand => os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
652+
.expand => os.posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
653+
.no_expand => os.posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
653654
};
654655
forkChildErrReport(err_pipe[1], err);
655656
}
@@ -955,10 +956,10 @@ pub const ChildProcess = struct {
955956

956957
fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
957958
switch (stdio) {
958-
.Pipe => try os.dup2(pipe_fd, std_fileno),
959+
.Pipe => try os.posix.dup2(pipe_fd, std_fileno),
959960
.Close => os.close(std_fileno),
960961
.Inherit => {},
961-
.Ignore => try os.dup2(dev_null_fd, std_fileno),
962+
.Ignore => try os.posix.dup2(dev_null_fd, std_fileno),
962963
}
963964
}
964965
};

lib/std/crypto/tlcsprng.zig

+3-3
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
7575
if (want_fork_safety and maybe_have_wipe_on_fork or is_haiku) {
7676
// Allocate a per-process page, madvise operates with page
7777
// granularity.
78-
wipe_mem = os.mmap(
78+
wipe_mem = os.posix.mmap(
7979
null,
8080
@sizeOf(Context),
8181
os.PROT.READ | os.PROT.WRITE,
@@ -111,11 +111,11 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
111111
// Qemu user-mode emulation ignores any valid/invalid madvise
112112
// hint and returns success. Check if this is the case by
113113
// passing bogus parameters, we expect EINVAL as result.
114-
if (os.madvise(wipe_mem.ptr, 0, 0xffffffff)) |_| {
114+
if (os.posix.madvise(wipe_mem.ptr, 0, 0xffffffff)) |_| {
115115
break :wof;
116116
} else |_| {}
117117

118-
if (os.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV.WIPEONFORK)) |_| {
118+
if (os.posix.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV.WIPEONFORK)) |_| {
119119
return initAndFill(buffer);
120120
} else |_| {}
121121
}

lib/std/debug.zig

+10-10
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,9 @@ pub const StackIterator = struct {
482482

483483
if (native_os != .windows) {
484484
if (native_os != .wasi) {
485-
os.msync(aligned_memory, os.MSF.ASYNC) catch |err| {
485+
os.posix.msync(aligned_memory, os.MSF.ASYNC) catch |err| {
486486
switch (err) {
487-
os.MSyncError.UnmappedMemory => {
487+
os.posix.MSyncError.UnmappedMemory => {
488488
return false;
489489
},
490490
else => unreachable,
@@ -1222,15 +1222,15 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
12221222
defer file.close();
12231223

12241224
const file_len = math.cast(usize, try file.getEndPos()) orelse math.maxInt(usize);
1225-
const mapped_mem = try os.mmap(
1225+
const mapped_mem = try os.posix.mmap(
12261226
null,
12271227
file_len,
12281228
os.PROT.READ,
12291229
os.MAP.SHARED,
12301230
file.handle,
12311231
0,
12321232
);
1233-
errdefer os.munmap(mapped_mem);
1233+
errdefer os.posix.munmap(mapped_mem);
12341234

12351235
return mapped_mem;
12361236
}
@@ -1491,7 +1491,7 @@ pub const ModuleDebugInfo = switch (native_os) {
14911491
}
14921492
self.ofiles.deinit();
14931493
allocator.free(self.symbols);
1494-
os.munmap(self.mapped_memory);
1494+
os.posix.munmap(self.mapped_memory);
14951495
}
14961496

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

17991799
fn deinit(self: *@This(), allocator: mem.Allocator) void {
18001800
self.dwarf.deinit(allocator);
1801-
os.munmap(self.mapped_memory);
1801+
os.posix.munmap(self.mapped_memory);
18021802
}
18031803

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

18821882
pub fn updateSegfaultHandler(act: ?*const os.Sigaction) error{OperationNotSupported}!void {
1883-
try os.sigaction(os.SIG.SEGV, act, null);
1884-
try os.sigaction(os.SIG.ILL, act, null);
1885-
try os.sigaction(os.SIG.BUS, act, null);
1886-
try os.sigaction(os.SIG.FPE, act, null);
1883+
try os.posix.sigaction(os.SIG.SEGV, act, null);
1884+
try os.posix.sigaction(os.SIG.ILL, act, null);
1885+
try os.posix.sigaction(os.SIG.BUS, act, null);
1886+
try os.posix.sigaction(os.SIG.FPE, act, null);
18871887
}
18881888

18891889
/// Attaches a global SIGSEGV handler which calls @panic("segmentation fault");

lib/std/dynamic_library.zig

+7-7
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ pub const ElfDynLib = struct {
123123

124124
// This one is to read the ELF info. We do more mmapping later
125125
// corresponding to the actual LOAD sections.
126-
const file_bytes = try os.mmap(
126+
const file_bytes = try os.posix.mmap(
127127
null,
128128
mem.alignForward(size, mem.page_size),
129129
os.PROT.READ,
130130
os.MAP.PRIVATE,
131131
fd,
132132
0,
133133
);
134-
defer os.munmap(file_bytes);
134+
defer os.posix.munmap(file_bytes);
135135

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

163163
// Reserve the entire range (with no permissions) so that we can do MAP.FIXED below.
164-
const all_loaded_mem = try os.mmap(
164+
const all_loaded_mem = try os.posix.mmap(
165165
null,
166166
virt_addr_end,
167167
os.PROT.NONE,
168168
os.MAP.PRIVATE | os.MAP.ANONYMOUS,
169169
-1,
170170
0,
171171
);
172-
errdefer os.munmap(all_loaded_mem);
172+
errdefer os.posix.munmap(all_loaded_mem);
173173

174174
const base = @ptrToInt(all_loaded_mem.ptr);
175175

@@ -193,7 +193,7 @@ pub const ElfDynLib = struct {
193193
const prot = elfToMmapProt(ph.p_flags);
194194
if ((ph.p_flags & elf.PF_W) == 0) {
195195
// If it does not need write access, it can be mapped from the fd.
196-
_ = try os.mmap(
196+
_ = try os.posix.mmap(
197197
ptr,
198198
extended_memsz,
199199
prot,
@@ -202,7 +202,7 @@ pub const ElfDynLib = struct {
202202
ph.p_offset - extra_bytes,
203203
);
204204
} else {
205-
const sect_mem = try os.mmap(
205+
const sect_mem = try os.posix.mmap(
206206
ptr,
207207
extended_memsz,
208208
prot,
@@ -256,7 +256,7 @@ pub const ElfDynLib = struct {
256256

257257
/// Trusts the file
258258
pub fn close(self: *ElfDynLib) void {
259-
os.munmap(self.memory);
259+
os.posix.munmap(self.memory);
260260
self.* = undefined;
261261
}
262262

lib/std/fs.zig

+4-4
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@ pub const Dir = struct {
11941194
}
11951195

11961196
if (has_flock_open_flags and flags.lock_nonblocking) {
1197-
var fl_flags = os.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
1197+
var fl_flags = os.posix.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
11981198
error.FileBusy => unreachable,
11991199
error.Locked => unreachable,
12001200
error.PermissionDenied => unreachable,
@@ -1203,7 +1203,7 @@ pub const Dir = struct {
12031203
else => |e| return e,
12041204
};
12051205
fl_flags &= ~@as(usize, os.O.NONBLOCK);
1206-
_ = os.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
1206+
_ = os.posix.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
12071207
error.FileBusy => unreachable,
12081208
error.Locked => unreachable,
12091209
error.PermissionDenied => unreachable,
@@ -1350,7 +1350,7 @@ pub const Dir = struct {
13501350
}
13511351

13521352
if (has_flock_open_flags and flags.lock_nonblocking) {
1353-
var fl_flags = os.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
1353+
var fl_flags = os.posix.fcntl(fd, os.F.GETFL, 0) catch |err| switch (err) {
13541354
error.FileBusy => unreachable,
13551355
error.Locked => unreachable,
13561356
error.PermissionDenied => unreachable,
@@ -1359,7 +1359,7 @@ pub const Dir = struct {
13591359
else => |e| return e,
13601360
};
13611361
fl_flags &= ~@as(usize, os.O.NONBLOCK);
1362-
_ = os.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
1362+
_ = os.posix.fcntl(fd, os.F.SETFL, fl_flags) catch |err| switch (err) {
13631363
error.FileBusy => unreachable,
13641364
error.Locked => unreachable,
13651365
error.PermissionDenied => unreachable,

0 commit comments

Comments
 (0)