From 06b263825a67e68cec128c640a6287fa1716dc63 Mon Sep 17 00:00:00 2001 From: Jan Philipp Hafer Date: Sun, 5 Mar 2023 18:41:52 +0100 Subject: [PATCH] std.os: add missing mmap errors Man page for posix lists EMFILE, man page for linux ENFILE. Also posix says "The mmap() function adds an extra reference to the file associated with the file descriptor fildes which is not removed by a subsequent close() on that file descriptor. This reference is removed when there are no more mappings to the file." It sounds counter-intuitive, that a process limit but no system limit can be exceeeded. As far as I understand, fildes is only used for file descriptor backed mmaps. --- lib/std/Thread.zig | 3 +++ lib/std/os.zig | 41 +++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 8004f94d7f..27f7fa5030 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -945,6 +945,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( null, map_bytes, @@ -956,6 +957,8 @@ const LinuxThreadImpl = struct { error.MemoryMappingNotSupported => unreachable, error.AccessDenied => unreachable, error.PermissionDenied => unreachable, + error.ProcessFdQuotaExceeded => unreachable, + error.SystemFdQuotaExceeded => unreachable, else => |e| return e, }; assert(mapped.len >= map_bytes); diff --git a/lib/std/os.zig b/lib/std/os.zig index 821c544cc8..6c680e9a38 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -253,6 +253,25 @@ pub var argv: [][*:0]u8 = if (builtin.link_libc) undefined else switch (builtin. else => undefined, }; +pub const have_sigpipe_support = @hasDecl(@This(), "SIG") and @hasDecl(SIG, "PIPE"); + +fn noopSigHandler(_: c_int) callconv(.C) void {} + +/// On default executed by posix startup code before main(), if SIGPIPE is supported. +pub fn maybeIgnoreSigpipe() void { + if (have_sigpipe_support and !std.options.keep_sigpipe) { + const act = Sigaction{ + // We set handler to a noop function instead of SIG.IGN so we don't leak our + // signal disposition to a child process + .handler = .{ .handler = noopSigHandler }, + .mask = empty_sigset, + .flags = 0, + }; + sigaction(SIG.PIPE, &act, null) catch |err| + std.debug.panic("failed to install noop SIGPIPE handler with '{s}'", .{@errorName(err)}); + } +} + /// To obtain errno, call this function with the return value of the /// system function call. For some systems this will obtain the value directly /// from the return code; for others it will use a thread-local errno variable. @@ -4306,6 +4325,8 @@ pub const MMapError = error{ /// a filesystem that was mounted no-exec. PermissionDenied, LockedMemoryLimitExceeded, + ProcessFdQuotaExceeded, + SystemFdQuotaExceeded, OutOfMemory, } || UnexpectedError; @@ -4347,6 +4368,8 @@ pub fn mmap( .OVERFLOW => unreachable, // The number of pages used for length + offset would overflow. .NODEV => return error.MemoryMappingNotSupported, .INVAL => unreachable, // Invalid parameters to mmap() + .MFILE => return error.ProcessFdQuotaExceeded, + .NFILE => return error.SystemFdQuotaExceeded, .NOMEM => return error.OutOfMemory, else => return unexpectedErrno(err), } @@ -7081,21 +7104,3 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec { else => |err| return unexpectedErrno(err), }; } - -pub const have_sigpipe_support = @hasDecl(@This(), "SIG") and @hasDecl(SIG, "PIPE"); - -fn noopSigHandler(_: c_int) callconv(.C) void {} - -pub fn maybeIgnoreSigpipe() void { - if (have_sigpipe_support and !std.options.keep_sigpipe) { - const act = Sigaction{ - // We set handler to a noop function instead of SIG.IGN so we don't leak our - // signal disposition to a child process - .handler = .{ .handler = noopSigHandler }, - .mask = empty_sigset, - .flags = 0, - }; - sigaction(SIG.PIPE, &act, null) catch |err| - std.debug.panic("failed to install noop SIGPIPE handler with '{s}'", .{@errorName(err)}); - } -}