| author | |
| committer | |
| log | b600b6e5e08bc443ef9742b36d51c95715c8150a |
| tree | ff9dc624970254de1b3500858df3064095cafb87 |
| parent | ea30f86113cb1ef2ea53f8d35598061ebb153c8e |
16 files changed, 165 insertions(+), 234 deletions(-)
lib/c/unistd.zig+30| ... | @@ -14,6 +14,8 @@ comptime { | ... | @@ -14,6 +14,8 @@ comptime { |
| 14 | symbol(&acctLinux, "acct"); | 14 | symbol(&acctLinux, "acct"); |
| 15 | symbol(&chdirLinux, "chdir"); | 15 | symbol(&chdirLinux, "chdir"); |
| 16 | symbol(&chownLinux, "chown"); | 16 | symbol(&chownLinux, "chown"); |
| 17 | symbol(&close, "close"); | ||
| 18 | symbol(&posix_close, "posix_close"); | ||
| 17 | symbol(&fchownatLinux, "fchownat"); | 19 | symbol(&fchownatLinux, "fchownat"); |
| 18 | symbol(&lchownLinux, "lchown"); | 20 | symbol(&lchownLinux, "lchown"); |
| 19 | symbol(&chrootLinux, "chroot"); | 21 | symbol(&chrootLinux, "chroot"); |
| ... | @@ -49,6 +51,9 @@ comptime { | ... | @@ -49,6 +51,9 @@ comptime { |
| 49 | if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { | 51 | if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { |
| 50 | symbol(&swab, "swab"); | 52 | symbol(&swab, "swab"); |
| 51 | } | 53 | } |
| 54 | if (builtin.target.isWasiLibC()) { | ||
| 55 | symbol(&closeWasi, "close"); | ||
| 56 | } | ||
| 52 | } | 57 | } |
| 53 | 58 | ||
| 54 | fn _exit(exit_code: c_int) callconv(.c) noreturn { | 59 | fn _exit(exit_code: c_int) callconv(.c) noreturn { |
| ... | @@ -226,3 +231,28 @@ test swab { | ... | @@ -226,3 +231,28 @@ test swab { |
| 226 | swab("abcd", &a, 3); | 231 | swab("abcd", &a, 3); |
| 227 | try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a); | 232 | try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a); |
| 228 | } | 233 | } |
| 234 | |||
| 235 | fn close(fd: std.c.fd_t) callconv(.c) c_int { | ||
| 236 | const signed: isize = @bitCast(linux.close(fd)); | ||
| 237 | if (signed < 0) { | ||
| 238 | @branchHint(.unlikely); | ||
| 239 | if (-signed == @intFromEnum(linux.E.INTR)) return 0; | ||
| 240 | std.c._errno().* = @intCast(-signed); | ||
| 241 | return -1; | ||
| 242 | } | ||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | |||
| 246 | fn posix_close(fd: std.c.fd_t, _: c_int) callconv(.c) c_int { | ||
| 247 | return close(fd); | ||
| 248 | } | ||
| 249 | |||
| 250 | fn closeWasi(fd: std.c.fd_t) callconv(.c) c_int { | ||
| 251 | switch (std.os.wasi.fd_close(fd)) { | ||
| 252 | .SUCCESS => return 0, | ||
| 253 | else => |e| { | ||
| 254 | std.c._errno().* = @intFromEnum(e); | ||
| 255 | return -1; | ||
| 256 | }, | ||
| 257 | } | ||
| 258 | } |
lib/libc/musl/src/unistd/close.c deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | #include <unistd.h> | ||
| 2 | #include <errno.h> | ||
| 3 | #include "aio_impl.h" | ||
| 4 | #include "syscall.h" | ||
| 5 | |||
| 6 | static int dummy(int fd) | ||
| 7 | { | ||
| 8 | 	return fd; | ||
| 9 | } | ||
| 10 | |||
| 11 | weak_alias(dummy, __aio_close); | ||
| 12 | |||
| 13 | int close(int fd) | ||
| 14 | { | ||
| 15 | 	fd = __aio_close(fd); | ||
| 16 | 	int r = __syscall_cp(SYS_close, fd); | ||
| 17 | 	if (r == -EINTR) r = 0; | ||
| 18 | 	return __syscall_ret(r); | ||
| 19 | } | ||
lib/libc/musl/src/unistd/posix_close.c deleted-6| ... | @@ -1,6 +0,0 @@ | ||
| 1 | #include <unistd.h> | ||
| 2 | |||
| 3 | int posix_close(int fd, int flags) | ||
| 4 | { | ||
| 5 | 	return close(fd); | ||
| 6 | } | ||
lib/libc/wasi/libc-bottom-half/sources/__wasilibc_fd_renumber.c-38| ... | @@ -70,41 +70,3 @@ void drop_udp_socket(udp_socket_t socket) { | ... | @@ -70,41 +70,3 @@ void drop_udp_socket(udp_socket_t socket) { |
| 70 | udp_udp_socket_drop_own(socket.socket); | 70 | udp_udp_socket_drop_own(socket.socket); |
| 71 | } | 71 | } |
| 72 | #endif // __wasilibc_use_wasip2 | 72 | #endif // __wasilibc_use_wasip2 |
| 73 | |||
| 74 | int close(int fd) { | ||
| 75 | // Scan the preopen fds before making any changes. | ||
| 76 | __wasilibc_populate_preopens(); | ||
| 77 | |||
| 78 | #ifdef __wasilibc_use_wasip2 | ||
| 79 | descriptor_table_entry_t entry; | ||
| 80 | if (descriptor_table_remove(fd, &entry)) { | ||
| 81 | |||
| 82 | switch (entry.tag) | ||
| 83 | { | ||
| 84 | case DESCRIPTOR_TABLE_ENTRY_TCP_SOCKET: | ||
| 85 | drop_tcp_socket(entry.tcp_socket); | ||
| 86 | break; | ||
| 87 | case DESCRIPTOR_TABLE_ENTRY_UDP_SOCKET: | ||
| 88 | drop_udp_socket(entry.udp_socket); | ||
| 89 | break; | ||
| 90 | default: /* unreachable */ abort(); | ||
| 91 | } | ||
| 92 | |||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | #endif // __wasilibc_use_wasip2 | ||
| 96 | |||
| 97 | __wasi_errno_t error = __wasi_fd_close(fd); | ||
| 98 | if (error != 0) { | ||
| 99 | errno = error; | ||
| 100 | return -1; | ||
| 101 | } | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | weak void __wasilibc_populate_preopens(void) { | ||
| 107 | // This version does nothing. It may be overridden by a version which does | ||
| 108 | // something if `__wasilibc_find_abspath` or `__wasilibc_find_relpath` are | ||
| 109 | // used. | ||
| 110 | } |
lib/std/Build/Watch.zig+2-2| ... | @@ -693,7 +693,7 @@ const Os = switch (builtin.os.tag) { | ... | @@ -693,7 +693,7 @@ const Os = switch (builtin.os.tag) { |
| 693 | fatal("failed to open directory {f}: {t}", .{ path, err }); | 693 | fatal("failed to open directory {f}: {t}", .{ path, err }); |
| 694 | }; | 694 | }; |
| 695 | // Empirically the dir has to stay open or else no events are triggered. | 695 | // Empirically the dir has to stay open or else no events are triggered. |
| 696 | errdefer if (!skip_open_dir) posix.close(dir_fd); | 696 | errdefer if (!skip_open_dir) std.Io.Threaded.closeFd(dir_fd); |
| 697 | const changes = [1]posix.Kevent{.{ | 697 | const changes = [1]posix.Kevent{.{ |
| 698 | .ident = @bitCast(@as(isize, dir_fd)), | 698 | .ident = @bitCast(@as(isize, dir_fd)), |
| 699 | .filter = std.c.EVFILT.VNODE, | 699 | .filter = std.c.EVFILT.VNODE, |
| ... | @@ -793,7 +793,7 @@ const Os = switch (builtin.os.tag) { | ... | @@ -793,7 +793,7 @@ const Os = switch (builtin.os.tag) { |
| 793 | }; | 793 | }; |
| 794 | const filtered_changes = if (i == handles.len - 1) changes[0..1] else &changes; | 794 | const filtered_changes = if (i == handles.len - 1) changes[0..1] else &changes; |
| 795 | _ = try Io.Kqueue.kevent(w.os.kq_fd, filtered_changes, &.{}, null); | 795 | _ = try Io.Kqueue.kevent(w.os.kq_fd, filtered_changes, &.{}, null); |
| 796 | if (path.sub_path.len != 0) posix.close(dir_fd); | 796 | if (path.sub_path.len != 0) std.Io.Threaded.closeFd(dir_fd); |
| 797 | 797 | ||
| 798 | w.dir_table.swapRemoveAt(i); | 798 | w.dir_table.swapRemoveAt(i); |
| 799 | handles.swapRemove(i); | 799 | handles.swapRemove(i); |
lib/std/Io/IoUring.zig+1-1| ... | @@ -549,7 +549,7 @@ const CachedFd = struct { | ... | @@ -549,7 +549,7 @@ const CachedFd = struct { |
| 549 | .initializing => unreachable, | 549 | .initializing => unreachable, |
| 550 | _ => |fd| { | 550 | _ => |fd| { |
| 551 | assert(@intFromEnum(fd) >= 0); | 551 | assert(@intFromEnum(fd) >= 0); |
| 552 | std.posix.close(@intFromEnum(fd)); | 552 | _ = std.os.linux.close(@intFromEnum(fd)); |
| 553 | cached_fd.* = .init; | 553 | cached_fd.* = .init; |
| 554 | }, | 554 | }, |
| 555 | } | 555 | } |
lib/std/Io/Kqueue.zig+8-7| ... | @@ -11,6 +11,7 @@ const Allocator = std.mem.Allocator; | ... | @@ -11,6 +11,7 @@ const Allocator = std.mem.Allocator; |
| 11 | const Alignment = std.mem.Alignment; | 11 | const Alignment = std.mem.Alignment; |
| 12 | const IpAddress = std.Io.net.IpAddress; | 12 | const IpAddress = std.Io.net.IpAddress; |
| 13 | const errnoBug = std.Io.Threaded.errnoBug; | 13 | const errnoBug = std.Io.Threaded.errnoBug; |
| 14 | const closeFd = std.Io.Threaded.closeFd; | ||
| 14 | const posix = std.posix; | 15 | const posix = std.posix; |
| 15 | 16 | ||
| 16 | /// Must be a thread-safe allocator. | 17 | /// Must be a thread-safe allocator. |
| ... | @@ -64,7 +65,7 @@ const Thread = struct { | ... | @@ -64,7 +65,7 @@ const Thread = struct { |
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | fn deinit(thread: *Thread, gpa: Allocator) void { | 67 | fn deinit(thread: *Thread, gpa: Allocator) void { |
| 67 | posix.close(thread.kq_fd); | 68 | closeFd(thread.kq_fd); |
| 68 | assert(thread.wait_queues.count() == 0); | 69 | assert(thread.wait_queues.count() == 0); |
| 69 | thread.wait_queues.deinit(gpa); | 70 | thread.wait_queues.deinit(gpa); |
| 70 | thread.* = undefined; | 71 | thread.* = undefined; |
| ... | @@ -212,7 +213,7 @@ pub fn init(k: *Kqueue, gpa: Allocator, options: InitOptions) !void { | ... | @@ -212,7 +213,7 @@ pub fn init(k: *Kqueue, gpa: Allocator, options: InitOptions) !void { |
| 212 | .steal_ready_search_index = 1, | 213 | .steal_ready_search_index = 1, |
| 213 | .wait_queues = .empty, | 214 | .wait_queues = .empty, |
| 214 | }; | 215 | }; |
| 215 | errdefer std.posix.close(main_thread.kq_fd); | 216 | errdefer closeFd(main_thread.kq_fd); |
| 216 | std.log.debug("created main idle {*}", .{&main_thread.idle_context}); | 217 | std.log.debug("created main idle {*}", .{&main_thread.idle_context}); |
| 217 | std.log.debug("created main {*}", .{main_fiber}); | 218 | std.log.debug("created main {*}", .{main_fiber}); |
| 218 | } | 219 | } |
| ... | @@ -371,7 +372,7 @@ fn schedule(k: *Kqueue, thread: *Thread, ready_queue: Fiber.Queue) void { | ... | @@ -371,7 +372,7 @@ fn schedule(k: *Kqueue, thread: *Thread, ready_queue: Fiber.Queue) void { |
| 371 | .stack_size = idle_stack_size, | 372 | .stack_size = idle_stack_size, |
| 372 | .allocator = k.gpa, | 373 | .allocator = k.gpa, |
| 373 | }, threadEntry, .{ k, new_thread_index }) catch |err| { | 374 | }, threadEntry, .{ k, new_thread_index }) catch |err| { |
| 374 | posix.close(new_thread.kq_fd); | 375 | closeFd(new_thread.kq_fd); |
| 375 | @atomicStore(u32, &k.threads.reserved, new_thread_index, .release); | 376 | @atomicStore(u32, &k.threads.reserved, new_thread_index, .release); |
| 376 | // no more access to `thread` after giving up reservation | 377 | // no more access to `thread` after giving up reservation |
| 377 | std.log.warn("unable to create worker thread due spawn failure: {s}", .{@errorName(err)}); | 378 | std.log.warn("unable to create worker thread due spawn failure: {s}", .{@errorName(err)}); |
| ... | @@ -1234,7 +1235,7 @@ fn netBindIp( | ... | @@ -1234,7 +1235,7 @@ fn netBindIp( |
| 1234 | const k: *Kqueue = @ptrCast(@alignCast(userdata)); | 1235 | const k: *Kqueue = @ptrCast(@alignCast(userdata)); |
| 1235 | const family = Io.Threaded.posixAddressFamily(address); | 1236 | const family = Io.Threaded.posixAddressFamily(address); |
| 1236 | const socket_fd = try openSocketPosix(k, family, options); | 1237 | const socket_fd = try openSocketPosix(k, family, options); |
| 1237 | errdefer std.posix.close(socket_fd); | 1238 | errdefer closeFd(socket_fd); |
| 1238 | var storage: Io.Threaded.PosixAddress = undefined; | 1239 | var storage: Io.Threaded.PosixAddress = undefined; |
| 1239 | var addr_len = Io.Threaded.addressToPosix(address, &storage); | 1240 | var addr_len = Io.Threaded.addressToPosix(address, &storage); |
| 1240 | try posixBind(k, socket_fd, &storage.any, addr_len); | 1241 | try posixBind(k, socket_fd, &storage.any, addr_len); |
| ... | @@ -1252,7 +1253,7 @@ fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: n | ... | @@ -1252,7 +1253,7 @@ fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: n |
| 1252 | .mode = options.mode, | 1253 | .mode = options.mode, |
| 1253 | .protocol = options.protocol, | 1254 | .protocol = options.protocol, |
| 1254 | }); | 1255 | }); |
| 1255 | errdefer posix.close(socket_fd); | 1256 | errdefer closeFd(socket_fd); |
| 1256 | var storage: Io.Threaded.PosixAddress = undefined; | 1257 | var storage: Io.Threaded.PosixAddress = undefined; |
| 1257 | var addr_len = Io.Threaded.addressToPosix(address, &storage); | 1258 | var addr_len = Io.Threaded.addressToPosix(address, &storage); |
| 1258 | try posixConnect(k, socket_fd, &storage.any, addr_len); | 1259 | try posixConnect(k, socket_fd, &storage.any, addr_len); |
| ... | @@ -1565,7 +1566,7 @@ fn openSocketPosix( | ... | @@ -1565,7 +1566,7 @@ fn openSocketPosix( |
| 1565 | switch (posix.errno(socket_rc)) { | 1566 | switch (posix.errno(socket_rc)) { |
| 1566 | .SUCCESS => { | 1567 | .SUCCESS => { |
| 1567 | const fd: posix.fd_t = @intCast(socket_rc); | 1568 | const fd: posix.fd_t = @intCast(socket_rc); |
| 1568 | errdefer posix.close(fd); | 1569 | errdefer closeFd(fd); |
| 1569 | if (Io.Threaded.socket_flags_unsupported) { | 1570 | if (Io.Threaded.socket_flags_unsupported) { |
| 1570 | while (true) { | 1571 | while (true) { |
| 1571 | try k.checkCancel(); | 1572 | try k.checkCancel(); |
| ... | @@ -1614,7 +1615,7 @@ fn openSocketPosix( | ... | @@ -1614,7 +1615,7 @@ fn openSocketPosix( |
| 1614 | else => |err| return posix.unexpectedErrno(err), | 1615 | else => |err| return posix.unexpectedErrno(err), |
| 1615 | } | 1616 | } |
| 1616 | }; | 1617 | }; |
| 1617 | errdefer posix.close(socket_fd); | 1618 | errdefer closeFd(socket_fd); |
| 1618 | 1619 | ||
| 1619 | if (options.ip6_only) { | 1620 | if (options.ip6_only) { |
| 1620 | if (posix.IPV6 == void) return error.OptionUnsupported; | 1621 | if (posix.IPV6 == void) return error.OptionUnsupported; |
lib/std/Io/Threaded.zig+64-38| ... | @@ -303,7 +303,7 @@ pub const NullFile = switch (native_os) { | ... | @@ -303,7 +303,7 @@ pub const NullFile = switch (native_os) { |
| 303 | 303 | ||
| 304 | fn deinit(this: *@This()) void { | 304 | fn deinit(this: *@This()) void { |
| 305 | if (this.fd >= 0) { | 305 | if (this.fd >= 0) { |
| 306 | posix.close(this.fd); | 306 | closeFd(this.fd); |
| 307 | this.fd = -1; | 307 | this.fd = -1; |
| 308 | } | 308 | } |
| 309 | } | 309 | } |
| ... | @@ -4337,7 +4337,7 @@ fn dirCreateFilePosix( | ... | @@ -4337,7 +4337,7 @@ fn dirCreateFilePosix( |
| 4337 | } | 4337 | } |
| 4338 | } | 4338 | } |
| 4339 | }; | 4339 | }; |
| 4340 | errdefer posix.close(fd); | 4340 | errdefer closeFd(fd); |
| 4341 | 4341 | ||
| 4342 | if (have_flock and !have_flock_open_flags and flags.lock != .none) { | 4342 | if (have_flock and !have_flock_open_flags and flags.lock != .none) { |
| 4343 | const lock_nonblocking: i32 = if (flags.lock_nonblocking) posix.LOCK.NB else 0; | 4343 | const lock_nonblocking: i32 = if (flags.lock_nonblocking) posix.LOCK.NB else 0; |
| ... | @@ -4917,7 +4917,7 @@ fn dirOpenFilePosix( | ... | @@ -4917,7 +4917,7 @@ fn dirOpenFilePosix( |
| 4917 | } | 4917 | } |
| 4918 | } | 4918 | } |
| 4919 | }; | 4919 | }; |
| 4920 | errdefer posix.close(fd); | 4920 | errdefer closeFd(fd); |
| 4921 | 4921 | ||
| 4922 | if (!flags.allow_directory) { | 4922 | if (!flags.allow_directory) { |
| 4923 | const is_dir = is_dir: { | 4923 | const is_dir = is_dir: { |
| ... | @@ -5241,7 +5241,7 @@ fn dirOpenFileWasi( | ... | @@ -5241,7 +5241,7 @@ fn dirOpenFileWasi( |
| 5241 | }, | 5241 | }, |
| 5242 | } | 5242 | } |
| 5243 | } | 5243 | } |
| 5244 | errdefer posix.close(fd); | 5244 | errdefer closeFd(fd); |
| 5245 | 5245 | ||
| 5246 | if (!flags.allow_directory) { | 5246 | if (!flags.allow_directory) { |
| 5247 | const is_dir = is_dir: { | 5247 | const is_dir = is_dir: { |
| ... | @@ -5457,7 +5457,13 @@ pub fn dirOpenDirWindows( | ... | @@ -5457,7 +5457,13 @@ pub fn dirOpenDirWindows( |
| 5457 | fn dirClose(userdata: ?*anyopaque, dirs: []const Dir) void { | 5457 | fn dirClose(userdata: ?*anyopaque, dirs: []const Dir) void { |
| 5458 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 5458 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 5459 | _ = t; | 5459 | _ = t; |
| 5460 | for (dirs) |dir| posix.close(dir.handle); | 5460 | for (dirs) |dir| { |
| 5461 | if (is_windows) { | ||
| 5462 | windows.CloseHandle(dir.handle); | ||
| 5463 | } else { | ||
| 5464 | closeFd(dir.handle); | ||
| 5465 | } | ||
| 5466 | } | ||
| 5461 | } | 5467 | } |
| 5462 | 5468 | ||
| 5463 | const dirRead = switch (native_os) { | 5469 | const dirRead = switch (native_os) { |
| ... | @@ -6777,7 +6783,7 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o | ... | @@ -6777,7 +6783,7 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o |
| 6777 | }, | 6783 | }, |
| 6778 | } | 6784 | } |
| 6779 | }; | 6785 | }; |
| 6780 | defer posix.close(fd); | 6786 | defer closeFd(fd); |
| 6781 | return realPathPosix(fd, out_buffer); | 6787 | return realPathPosix(fd, out_buffer); |
| 6782 | } | 6788 | } |
| 6783 | 6789 | ||
| ... | @@ -8367,7 +8373,7 @@ fn fchmodatFallback( | ... | @@ -8367,7 +8373,7 @@ fn fchmodatFallback( |
| 8367 | } | 8373 | } |
| 8368 | } | 8374 | } |
| 8369 | }; | 8375 | }; |
| 8370 | defer posix.close(path_fd); | 8376 | defer closeFd(path_fd); |
| 8371 | 8377 | ||
| 8372 | const path_mode = mode: { | 8378 | const path_mode = mode: { |
| 8373 | const sys = if (statx_use_c) std.c else std.os.linux; | 8379 | const sys = if (statx_use_c) std.c else std.os.linux; |
| ... | @@ -9592,7 +9598,13 @@ fn dirHardLink( | ... | @@ -9592,7 +9598,13 @@ fn dirHardLink( |
| 9592 | fn fileClose(userdata: ?*anyopaque, files: []const File) void { | 9598 | fn fileClose(userdata: ?*anyopaque, files: []const File) void { |
| 9593 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 9599 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 9594 | _ = t; | 9600 | _ = t; |
| 9595 | for (files) |file| posix.close(file.handle); | 9601 | for (files) |file| { |
| 9602 | if (is_windows) { | ||
| 9603 | windows.CloseHandle(file.handle); | ||
| 9604 | } else { | ||
| 9605 | closeFd(file.handle); | ||
| 9606 | } | ||
| 9607 | } | ||
| 9596 | } | 9608 | } |
| 9597 | 9609 | ||
| 9598 | fn fileReadStreaming(userdata: ?*anyopaque, file: File, data: []const []u8) File.ReadStreamingError!usize { | 9610 | fn fileReadStreaming(userdata: ?*anyopaque, file: File, data: []const []u8) File.ReadStreamingError!usize { |
| ... | @@ -11783,7 +11795,7 @@ fn netListenIpPosix( | ... | @@ -11783,7 +11795,7 @@ fn netListenIpPosix( |
| 11783 | .mode = options.mode, | 11795 | .mode = options.mode, |
| 11784 | .protocol = options.protocol, | 11796 | .protocol = options.protocol, |
| 11785 | }); | 11797 | }); |
| 11786 | errdefer posix.close(socket_fd); | 11798 | errdefer closeFd(socket_fd); |
| 11787 | 11799 | ||
| 11788 | if (options.reuse_address) { | 11800 | if (options.reuse_address) { |
| 11789 | try setSocketOption(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1); | 11801 | try setSocketOption(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1); |
| ... | @@ -11946,7 +11958,7 @@ fn netListenUnixPosix( | ... | @@ -11946,7 +11958,7 @@ fn netListenUnixPosix( |
| 11946 | error.OptionUnsupported => return error.Unexpected, | 11958 | error.OptionUnsupported => return error.Unexpected, |
| 11947 | else => |e| return e, | 11959 | else => |e| return e, |
| 11948 | }; | 11960 | }; |
| 11949 | errdefer posix.close(socket_fd); | 11961 | errdefer closeFd(socket_fd); |
| 11950 | 11962 | ||
| 11951 | var storage: UnixAddress = undefined; | 11963 | var storage: UnixAddress = undefined; |
| 11952 | const addr_len = addressUnixToPosix(address, &storage); | 11964 | const addr_len = addressUnixToPosix(address, &storage); |
| ... | @@ -12362,7 +12374,7 @@ fn netConnectIpPosix( | ... | @@ -12362,7 +12374,7 @@ fn netConnectIpPosix( |
| 12362 | .mode = options.mode, | 12374 | .mode = options.mode, |
| 12363 | .protocol = options.protocol, | 12375 | .protocol = options.protocol, |
| 12364 | }); | 12376 | }); |
| 12365 | errdefer posix.close(socket_fd); | 12377 | errdefer closeFd(socket_fd); |
| 12366 | var storage: PosixAddress = undefined; | 12378 | var storage: PosixAddress = undefined; |
| 12367 | var addr_len = addressToPosix(address, &storage); | 12379 | var addr_len = addressToPosix(address, &storage); |
| 12368 | try posixConnect(socket_fd, &storage.any, addr_len); | 12380 | try posixConnect(socket_fd, &storage.any, addr_len); |
| ... | @@ -12462,7 +12474,7 @@ fn netConnectUnixPosix( | ... | @@ -12462,7 +12474,7 @@ fn netConnectUnixPosix( |
| 12462 | error.OptionUnsupported => return error.Unexpected, | 12474 | error.OptionUnsupported => return error.Unexpected, |
| 12463 | else => |e| return e, | 12475 | else => |e| return e, |
| 12464 | }; | 12476 | }; |
| 12465 | errdefer posix.close(socket_fd); | 12477 | errdefer closeFd(socket_fd); |
| 12466 | var storage: UnixAddress = undefined; | 12478 | var storage: UnixAddress = undefined; |
| 12467 | const addr_len = addressUnixToPosix(address, &storage); | 12479 | const addr_len = addressUnixToPosix(address, &storage); |
| 12468 | try posixConnectUnix(socket_fd, &storage.any, addr_len); | 12480 | try posixConnectUnix(socket_fd, &storage.any, addr_len); |
| ... | @@ -12536,7 +12548,7 @@ fn netBindIpPosix( | ... | @@ -12536,7 +12548,7 @@ fn netBindIpPosix( |
| 12536 | _ = t; | 12548 | _ = t; |
| 12537 | const family = posixAddressFamily(address); | 12549 | const family = posixAddressFamily(address); |
| 12538 | const socket_fd = try openSocketPosix(family, options); | 12550 | const socket_fd = try openSocketPosix(family, options); |
| 12539 | errdefer posix.close(socket_fd); | 12551 | errdefer closeFd(socket_fd); |
| 12540 | var storage: PosixAddress = undefined; | 12552 | var storage: PosixAddress = undefined; |
| 12541 | var addr_len = addressToPosix(address, &storage); | 12553 | var addr_len = addressToPosix(address, &storage); |
| 12542 | try posixBind(socket_fd, &storage.any, addr_len); | 12554 | try posixBind(socket_fd, &storage.any, addr_len); |
| ... | @@ -12642,7 +12654,7 @@ fn openSocketPosix( | ... | @@ -12642,7 +12654,7 @@ fn openSocketPosix( |
| 12642 | .SUCCESS => { | 12654 | .SUCCESS => { |
| 12643 | syscall.finish(); | 12655 | syscall.finish(); |
| 12644 | const fd: posix.fd_t = @intCast(rc); | 12656 | const fd: posix.fd_t = @intCast(rc); |
| 12645 | errdefer posix.close(fd); | 12657 | errdefer closeFd(fd); |
| 12646 | if (socket_flags_unsupported) try setCloexec(fd); | 12658 | if (socket_flags_unsupported) try setCloexec(fd); |
| 12647 | break fd; | 12659 | break fd; |
| 12648 | }, | 12660 | }, |
| ... | @@ -12661,7 +12673,7 @@ fn openSocketPosix( | ... | @@ -12661,7 +12673,7 @@ fn openSocketPosix( |
| 12661 | else => |err| return syscall.unexpectedErrno(err), | 12673 | else => |err| return syscall.unexpectedErrno(err), |
| 12662 | } | 12674 | } |
| 12663 | }; | 12675 | }; |
| 12664 | errdefer posix.close(socket_fd); | 12676 | errdefer closeFd(socket_fd); |
| 12665 | 12677 | ||
| 12666 | if (options.ip6_only) { | 12678 | if (options.ip6_only) { |
| 12667 | if (posix.IPV6 == void) return error.OptionUnsupported; | 12679 | if (posix.IPV6 == void) return error.OptionUnsupported; |
| ... | @@ -12707,8 +12719,8 @@ fn netSocketCreatePair( | ... | @@ -12707,8 +12719,8 @@ fn netSocketCreatePair( |
| 12707 | .SUCCESS => { | 12719 | .SUCCESS => { |
| 12708 | syscall.finish(); | 12720 | syscall.finish(); |
| 12709 | errdefer { | 12721 | errdefer { |
| 12710 | posix.close(sockets[0]); | 12722 | closeFd(sockets[0]); |
| 12711 | posix.close(sockets[1]); | 12723 | closeFd(sockets[1]); |
| 12712 | } | 12724 | } |
| 12713 | if (socket_flags_unsupported) { | 12725 | if (socket_flags_unsupported) { |
| 12714 | try setCloexec(sockets[0]); | 12726 | try setCloexec(sockets[0]); |
| ... | @@ -12809,7 +12821,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve | ... | @@ -12809,7 +12821,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve |
| 12809 | .SUCCESS => { | 12821 | .SUCCESS => { |
| 12810 | syscall.finish(); | 12822 | syscall.finish(); |
| 12811 | const fd: posix.fd_t = @intCast(rc); | 12823 | const fd: posix.fd_t = @intCast(rc); |
| 12812 | errdefer posix.close(fd); | 12824 | errdefer closeFd(fd); |
| 12813 | if (!have_accept4) try setCloexec(fd); | 12825 | if (!have_accept4) try setCloexec(fd); |
| 12814 | break fd; | 12826 | break fd; |
| 12815 | }, | 12827 | }, |
| ... | @@ -13679,7 +13691,7 @@ fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { | ... | @@ -13679,7 +13691,7 @@ fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { |
| 13679 | _ = t; | 13691 | _ = t; |
| 13680 | switch (native_os) { | 13692 | switch (native_os) { |
| 13681 | .windows => for (handles) |handle| closeSocketWindows(handle), | 13693 | .windows => for (handles) |handle| closeSocketWindows(handle), |
| 13682 | else => for (handles) |handle| posix.close(handle), | 13694 | else => for (handles) |handle| closeFd(handle), |
| 13683 | } | 13695 | } |
| 13684 | } | 13696 | } |
| 13685 | 13697 | ||
| ... | @@ -13787,7 +13799,7 @@ fn netInterfaceNameResolve( | ... | @@ -13787,7 +13799,7 @@ fn netInterfaceNameResolve( |
| 13787 | error.OptionUnsupported => return error.Unexpected, | 13799 | error.OptionUnsupported => return error.Unexpected, |
| 13788 | else => |e| return e, | 13800 | else => |e| return e, |
| 13789 | }; | 13801 | }; |
| 13790 | defer posix.close(sock_fd); | 13802 | defer closeFd(sock_fd); |
| 13791 | 13803 | ||
| 13792 | var ifr: posix.ifreq = .{ | 13804 | var ifr: posix.ifreq = .{ |
| 13793 | .ifrn = .{ .name = @bitCast(name.bytes) }, | 13805 | .ifrn = .{ .name = @bitCast(name.bytes) }, |
| ... | @@ -15329,13 +15341,13 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp | ... | @@ -15329,13 +15341,13 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp |
| 15329 | const pid: posix.pid_t = @intCast(pid_result); // We are the parent. | 15341 | const pid: posix.pid_t = @intCast(pid_result); // We are the parent. |
| 15330 | errdefer comptime unreachable; // The child is forked; we must not error from now on | 15342 | errdefer comptime unreachable; // The child is forked; we must not error from now on |
| 15331 | 15343 | ||
| 15332 | posix.close(err_pipe[1]); // make sure only the child holds the write end open | 15344 | closeFd(err_pipe[1]); // make sure only the child holds the write end open |
| 15333 | 15345 | ||
| 15334 | if (options.stdin == .pipe) posix.close(stdin_pipe[0]); | 15346 | if (options.stdin == .pipe) closeFd(stdin_pipe[0]); |
| 15335 | if (options.stdout == .pipe) posix.close(stdout_pipe[1]); | 15347 | if (options.stdout == .pipe) closeFd(stdout_pipe[1]); |
| 15336 | if (options.stderr == .pipe) posix.close(stderr_pipe[1]); | 15348 | if (options.stderr == .pipe) closeFd(stderr_pipe[1]); |
| 15337 | 15349 | ||
| 15338 | if (prog_pipe[1] != -1) posix.close(prog_pipe[1]); | 15350 | if (prog_pipe[1] != -1) closeFd(prog_pipe[1]); |
| 15339 | options.progress_node.setIpcFile(t, .{ .handle = prog_pipe[0], .flags = .{ .nonblocking = true } }); | 15351 | options.progress_node.setIpcFile(t, .{ .handle = prog_pipe[0], .flags = .{ .nonblocking = true } }); |
| 15340 | 15352 | ||
| 15341 | return .{ | 15353 | return .{ |
| ... | @@ -15373,7 +15385,7 @@ fn getDevNullFd(t: *Threaded) !posix.fd_t { | ... | @@ -15373,7 +15385,7 @@ fn getDevNullFd(t: *Threaded) !posix.fd_t { |
| 15373 | mutexLock(&t.mutex); // Another thread might have won the race. | 15385 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 15374 | defer mutexUnlock(&t.mutex); | 15386 | defer mutexUnlock(&t.mutex); |
| 15375 | if (t.null_file.fd != -1) { | 15387 | if (t.null_file.fd != -1) { |
| 15376 | posix.close(fresh_fd); | 15388 | closeFd(fresh_fd); |
| 15377 | return t.null_file.fd; | 15389 | return t.null_file.fd; |
| 15378 | } else { | 15390 | } else { |
| 15379 | t.null_file.fd = fresh_fd; | 15391 | t.null_file.fd = fresh_fd; |
| ... | @@ -15399,7 +15411,7 @@ fn getDevNullFd(t: *Threaded) !posix.fd_t { | ... | @@ -15399,7 +15411,7 @@ fn getDevNullFd(t: *Threaded) !posix.fd_t { |
| 15399 | fn processSpawnPosix(userdata: ?*anyopaque, options: process.SpawnOptions) process.SpawnError!process.Child { | 15411 | fn processSpawnPosix(userdata: ?*anyopaque, options: process.SpawnOptions) process.SpawnError!process.Child { |
| 15400 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 15412 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 15401 | const spawned = try spawnPosix(t, options); | 15413 | const spawned = try spawnPosix(t, options); |
| 15402 | defer posix.close(spawned.err_fd); | 15414 | defer closeFd(spawned.err_fd); |
| 15403 | 15415 | ||
| 15404 | // Wait for the child to report any errors in or before `execvpe`. | 15416 | // Wait for the child to report any errors in or before `execvpe`. |
| 15405 | if (readIntFd(spawned.err_fd)) |child_err_int| { | 15417 | if (readIntFd(spawned.err_fd)) |child_err_int| { |
| ... | @@ -15666,15 +15678,15 @@ fn childKillPosix(child: *process.Child) !void { | ... | @@ -15666,15 +15678,15 @@ fn childKillPosix(child: *process.Child) !void { |
| 15666 | 15678 | ||
| 15667 | fn childCleanupPosix(child: *process.Child) void { | 15679 | fn childCleanupPosix(child: *process.Child) void { |
| 15668 | if (child.stdin) |*stdin| { | 15680 | if (child.stdin) |*stdin| { |
| 15669 | posix.close(stdin.handle); | 15681 | closeFd(stdin.handle); |
| 15670 | child.stdin = null; | 15682 | child.stdin = null; |
| 15671 | } | 15683 | } |
| 15672 | if (child.stdout) |*stdout| { | 15684 | if (child.stdout) |*stdout| { |
| 15673 | posix.close(stdout.handle); | 15685 | closeFd(stdout.handle); |
| 15674 | child.stdout = null; | 15686 | child.stdout = null; |
| 15675 | } | 15687 | } |
| 15676 | if (child.stderr) |*stderr| { | 15688 | if (child.stderr) |*stderr| { |
| 15677 | posix.close(stderr.handle); | 15689 | closeFd(stderr.handle); |
| 15678 | child.stderr = null; | 15690 | child.stderr = null; |
| 15679 | } | 15691 | } |
| 15680 | child.id = null; | 15692 | child.id = null; |
| ... | @@ -15743,14 +15755,14 @@ fn readIntFd(fd: posix.fd_t) !ErrInt { | ... | @@ -15743,14 +15755,14 @@ fn readIntFd(fd: posix.fd_t) !ErrInt { |
| 15743 | const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); | 15755 | const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); |
| 15744 | 15756 | ||
| 15745 | fn destroyPipe(pipe: [2]posix.fd_t) void { | 15757 | fn destroyPipe(pipe: [2]posix.fd_t) void { |
| 15746 | if (pipe[0] != -1) posix.close(pipe[0]); | 15758 | if (pipe[0] != -1) closeFd(pipe[0]); |
| 15747 | if (pipe[0] != pipe[1]) posix.close(pipe[1]); | 15759 | if (pipe[0] != pipe[1]) closeFd(pipe[1]); |
| 15748 | } | 15760 | } |
| 15749 | 15761 | ||
| 15750 | fn setUpChildIo(stdio: process.SpawnOptions.StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void { | 15762 | fn setUpChildIo(stdio: process.SpawnOptions.StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void { |
| 15751 | switch (stdio) { | 15763 | switch (stdio) { |
| 15752 | .pipe => try dup2(pipe_fd, std_fileno), | 15764 | .pipe => try dup2(pipe_fd, std_fileno), |
| 15753 | .close => posix.close(std_fileno), | 15765 | .close => closeFd(std_fileno), |
| 15754 | .inherit => {}, | 15766 | .inherit => {}, |
| 15755 | .ignore => try dup2(dev_null_fd, std_fileno), | 15767 | .ignore => try dup2(dev_null_fd, std_fileno), |
| 15756 | .file => @panic("TODO implement setUpChildIo when file is used"), | 15768 | .file => @panic("TODO implement setUpChildIo when file is used"), |
| ... | @@ -17439,7 +17451,7 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { | ... | @@ -17439,7 +17451,7 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { |
| 17439 | } | 17451 | } |
| 17440 | } | 17452 | } |
| 17441 | }; | 17453 | }; |
| 17442 | errdefer posix.close(fd); | 17454 | errdefer closeFd(fd); |
| 17443 | 17455 | ||
| 17444 | switch (native_os) { | 17456 | switch (native_os) { |
| 17445 | .linux => { | 17457 | .linux => { |
| ... | @@ -17454,7 +17466,7 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { | ... | @@ -17454,7 +17466,7 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { |
| 17454 | mutexLock(&t.mutex); // Another thread might have won the race. | 17466 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 17455 | defer mutexUnlock(&t.mutex); | 17467 | defer mutexUnlock(&t.mutex); |
| 17456 | if (t.random_file.fd >= 0) { | 17468 | if (t.random_file.fd >= 0) { |
| 17457 | posix.close(fd); | 17469 | closeFd(fd); |
| 17458 | return t.random_file.fd; | 17470 | return t.random_file.fd; |
| 17459 | } else if (!posix.S.ISCHR(statx.mode)) { | 17471 | } else if (!posix.S.ISCHR(statx.mode)) { |
| 17460 | t.random_file.fd = -2; | 17472 | t.random_file.fd = -2; |
| ... | @@ -17482,7 +17494,7 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { | ... | @@ -17482,7 +17494,7 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { |
| 17482 | mutexLock(&t.mutex); // Another thread might have won the race. | 17494 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 17483 | defer mutexUnlock(&t.mutex); | 17495 | defer mutexUnlock(&t.mutex); |
| 17484 | if (t.random_file.fd >= 0) { | 17496 | if (t.random_file.fd >= 0) { |
| 17485 | posix.close(fd); | 17497 | closeFd(fd); |
| 17486 | return t.random_file.fd; | 17498 | return t.random_file.fd; |
| 17487 | } else if (!posix.S.ISCHR(stat.mode)) { | 17499 | } else if (!posix.S.ISCHR(stat.mode)) { |
| 17488 | t.random_file.fd = -2; | 17500 | t.random_file.fd = -2; |
| ... | @@ -18170,8 +18182,8 @@ pub fn pipe2(flags: posix.O) PipeError![2]posix.fd_t { | ... | @@ -18170,8 +18182,8 @@ pub fn pipe2(flags: posix.O) PipeError![2]posix.fd_t { |
| 18170 | else => |err| return posix.unexpectedErrno(err), | 18182 | else => |err| return posix.unexpectedErrno(err), |
| 18171 | } | 18183 | } |
| 18172 | errdefer { | 18184 | errdefer { |
| 18173 | posix.close(fds[0]); | 18185 | closeFd(fds[0]); |
| 18174 | posix.close(fds[1]); | 18186 | closeFd(fds[1]); |
| 18175 | } | 18187 | } |
| 18176 | 18188 | ||
| 18177 | // https://github.com/ziglang/zig/issues/18882 | 18189 | // https://github.com/ziglang/zig/issues/18882 |
| ... | @@ -19164,3 +19176,17 @@ fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!windows | ... | @@ -19164,3 +19176,17 @@ fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!windows |
| 19164 | } | 19176 | } |
| 19165 | } | 19177 | } |
| 19166 | } | 19178 | } |
| 19179 | |||
| 19180 | pub fn closeFd(fd: posix.fd_t) void { | ||
| 19181 | if (native_os == .wasi and !builtin.link_libc) { | ||
| 19182 | switch (std.os.wasi.fd_close(fd)) { | ||
| 19183 | .SUCCESS, .INTR => {}, | ||
| 19184 | .BADF => recoverableOsBugDetected(), // use after free | ||
| 19185 | else => recoverableOsBugDetected(), // unexpected failure | ||
| 19186 | } | ||
| 19187 | } else switch (posix.errno(posix.system.close(fd))) { | ||
| 19188 | .SUCCESS, .INTR => {}, // INTR still a success, see https://github.com/ziglang/zig/issues/2425 | ||
| 19189 | .BADF => recoverableOsBugDetected(), // use after free | ||
| 19190 | else => recoverableOsBugDetected(), // unexpected failure | ||
| 19191 | } | ||
| 19192 | } |
lib/std/os/linux.zig+1-1| ... | @@ -1571,7 +1571,7 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize { | ... | @@ -1571,7 +1571,7 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize { |
| 1571 | return syscall2(.clone, flags, child_stack_ptr); | 1571 | return syscall2(.clone, flags, child_stack_ptr); |
| 1572 | } | 1572 | } |
| 1573 | 1573 | ||
| 1574 | pub fn close(fd: i32) usize { | 1574 | pub fn close(fd: fd_t) usize { |
| 1575 | return syscall1(.close, @as(usize, @bitCast(@as(isize, fd)))); | 1575 | return syscall1(.close, @as(usize, @bitCast(@as(isize, fd)))); |
| 1576 | } | 1576 | } |
| 1577 | 1577 |
lib/std/os/linux/IoUring.zig+2-2| ... | @@ -67,7 +67,7 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring { | ... | @@ -67,7 +67,7 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring { |
| 67 | } | 67 | } |
| 68 | const fd = @as(linux.fd_t, @intCast(res)); | 68 | const fd = @as(linux.fd_t, @intCast(res)); |
| 69 | assert(fd >= 0); | 69 | assert(fd >= 0); |
| 70 | errdefer posix.close(fd); | 70 | errdefer _ = linux.close(fd); |
| 71 | 71 | ||
| 72 | // Kernel versions 5.4 and up use only one mmap() for the submission and completion queues. | 72 | // Kernel versions 5.4 and up use only one mmap() for the submission and completion queues. |
| 73 | // This is not an optional feature for us... if the kernel does it, we have to do it. | 73 | // This is not an optional feature for us... if the kernel does it, we have to do it. |
| ... | @@ -125,7 +125,7 @@ pub fn deinit(self: *IoUring) void { | ... | @@ -125,7 +125,7 @@ pub fn deinit(self: *IoUring) void { |
| 125 | // The mmaps depend on the fd, so the order of these calls is important: | 125 | // The mmaps depend on the fd, so the order of these calls is important: |
| 126 | self.cq.deinit(); | 126 | self.cq.deinit(); |
| 127 | self.sq.deinit(); | 127 | self.sq.deinit(); |
| 128 | posix.close(self.fd); | 128 | _ = linux.close(self.fd); |
| 129 | self.fd = -1; | 129 | self.fd = -1; |
| 130 | } | 130 | } |
| 131 | 131 |
lib/std/os/linux/IoUring/test.zig+21-21| ... | @@ -440,7 +440,7 @@ test "openat" { | ... | @@ -440,7 +440,7 @@ test "openat" { |
| 440 | try testing.expect(cqe_openat.res > 0); | 440 | try testing.expect(cqe_openat.res > 0); |
| 441 | try testing.expectEqual(@as(u32, 0), cqe_openat.flags); | 441 | try testing.expectEqual(@as(u32, 0), cqe_openat.flags); |
| 442 | 442 | ||
| 443 | posix.close(cqe_openat.res); | 443 | _ = linux.close(cqe_openat.res); |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | test "close" { | 446 | test "close" { |
| ... | @@ -530,7 +530,7 @@ test "sendmsg/recvmsg" { | ... | @@ -530,7 +530,7 @@ test "sendmsg/recvmsg" { |
| 530 | }; | 530 | }; |
| 531 | 531 | ||
| 532 | const server = try socket(address_server.family, posix.SOCK.DGRAM, 0); | 532 | const server = try socket(address_server.family, posix.SOCK.DGRAM, 0); |
| 533 | defer posix.close(server); | 533 | defer _ = linux.close(server); |
| 534 | try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEPORT, &mem.toBytes(@as(c_int, 1))); | 534 | try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEPORT, &mem.toBytes(@as(c_int, 1))); |
| 535 | try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1))); | 535 | try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1))); |
| 536 | try bind(server, addrAny(&address_server), @sizeOf(linux.sockaddr.in)); | 536 | try bind(server, addrAny(&address_server), @sizeOf(linux.sockaddr.in)); |
| ... | @@ -540,7 +540,7 @@ test "sendmsg/recvmsg" { | ... | @@ -540,7 +540,7 @@ test "sendmsg/recvmsg" { |
| 540 | try getsockname(server, addrAny(&address_server), &slen); | 540 | try getsockname(server, addrAny(&address_server), &slen); |
| 541 | 541 | ||
| 542 | const client = try socket(address_server.family, posix.SOCK.DGRAM, 0); | 542 | const client = try socket(address_server.family, posix.SOCK.DGRAM, 0); |
| 543 | defer posix.close(client); | 543 | defer _ = linux.close(client); |
| 544 | 544 | ||
| 545 | const buffer_send = [_]u8{42} ** 128; | 545 | const buffer_send = [_]u8{42} ** 128; |
| 546 | const iovecs_send = [_]iovec_const{ | 546 | const iovecs_send = [_]iovec_const{ |
| ... | @@ -1034,7 +1034,7 @@ test "shutdown" { | ... | @@ -1034,7 +1034,7 @@ test "shutdown" { |
| 1034 | // Socket bound, expect shutdown to work | 1034 | // Socket bound, expect shutdown to work |
| 1035 | { | 1035 | { |
| 1036 | const server = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 1036 | const server = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 1037 | defer posix.close(server); | 1037 | defer _ = linux.close(server); |
| 1038 | try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1))); | 1038 | try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1))); |
| 1039 | try bind(server, addrAny(&address), @sizeOf(linux.sockaddr.in)); | 1039 | try bind(server, addrAny(&address), @sizeOf(linux.sockaddr.in)); |
| 1040 | try listen(server, 1); | 1040 | try listen(server, 1); |
| ... | @@ -1067,7 +1067,7 @@ test "shutdown" { | ... | @@ -1067,7 +1067,7 @@ test "shutdown" { |
| 1067 | // Socket not bound, expect to fail with ENOTCONN | 1067 | // Socket not bound, expect to fail with ENOTCONN |
| 1068 | { | 1068 | { |
| 1069 | const server = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 1069 | const server = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 1070 | defer posix.close(server); | 1070 | defer _ = linux.close(server); |
| 1071 | 1071 | ||
| 1072 | const shutdown_sqe = ring.shutdown(0x445445445, server, linux.SHUT.RD) catch |err| switch (err) { | 1072 | const shutdown_sqe = ring.shutdown(0x445445445, server, linux.SHUT.RD) catch |err| switch (err) { |
| 1073 | else => |errno| std.debug.panic("unhandled errno: {}", .{errno}), | 1073 | else => |errno| std.debug.panic("unhandled errno: {}", .{errno}), |
| ... | @@ -1741,7 +1741,7 @@ test "accept multishot" { | ... | @@ -1741,7 +1741,7 @@ test "accept multishot" { |
| 1741 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 1741 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), |
| 1742 | }; | 1742 | }; |
| 1743 | const listener_socket = try createListenerSocket(&address); | 1743 | const listener_socket = try createListenerSocket(&address); |
| 1744 | defer posix.close(listener_socket); | 1744 | defer _ = linux.close(listener_socket); |
| 1745 | 1745 | ||
| 1746 | // submit multishot accept operation | 1746 | // submit multishot accept operation |
| 1747 | var addr: posix.sockaddr = undefined; | 1747 | var addr: posix.sockaddr = undefined; |
| ... | @@ -1754,7 +1754,7 @@ test "accept multishot" { | ... | @@ -1754,7 +1754,7 @@ test "accept multishot" { |
| 1754 | while (nr > 0) : (nr -= 1) { | 1754 | while (nr > 0) : (nr -= 1) { |
| 1755 | // connect client | 1755 | // connect client |
| 1756 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 1756 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 1757 | errdefer posix.close(client); | 1757 | errdefer _ = linux.close(client); |
| 1758 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); | 1758 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); |
| 1759 | 1759 | ||
| 1760 | // test accept completion | 1760 | // test accept completion |
| ... | @@ -1764,7 +1764,7 @@ test "accept multishot" { | ... | @@ -1764,7 +1764,7 @@ test "accept multishot" { |
| 1764 | try testing.expect(cqe.user_data == userdata); | 1764 | try testing.expect(cqe.user_data == userdata); |
| 1765 | try testing.expect(cqe.flags & linux.IORING_CQE_F_MORE > 0); // more flag is set | 1765 | try testing.expect(cqe.flags & linux.IORING_CQE_F_MORE > 0); // more flag is set |
| 1766 | 1766 | ||
| 1767 | posix.close(client); | 1767 | _ = linux.close(client); |
| 1768 | } | 1768 | } |
| 1769 | } | 1769 | } |
| 1770 | 1770 | ||
| ... | @@ -1848,7 +1848,7 @@ test "accept_direct" { | ... | @@ -1848,7 +1848,7 @@ test "accept_direct" { |
| 1848 | try ring.register_files(registered_fds[0..]); | 1848 | try ring.register_files(registered_fds[0..]); |
| 1849 | 1849 | ||
| 1850 | const listener_socket = try createListenerSocket(&address); | 1850 | const listener_socket = try createListenerSocket(&address); |
| 1851 | defer posix.close(listener_socket); | 1851 | defer _ = linux.close(listener_socket); |
| 1852 | 1852 | ||
| 1853 | const accept_userdata: u64 = 0xaaaaaaaa; | 1853 | const accept_userdata: u64 = 0xaaaaaaaa; |
| 1854 | const read_userdata: u64 = 0xbbbbbbbb; | 1854 | const read_userdata: u64 = 0xbbbbbbbb; |
| ... | @@ -1866,7 +1866,7 @@ test "accept_direct" { | ... | @@ -1866,7 +1866,7 @@ test "accept_direct" { |
| 1866 | // connect | 1866 | // connect |
| 1867 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 1867 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 1868 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); | 1868 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); |
| 1869 | defer posix.close(client); | 1869 | defer _ = linux.close(client); |
| 1870 | 1870 | ||
| 1871 | // accept completion | 1871 | // accept completion |
| 1872 | const cqe_accept = try ring.copy_cqe(); | 1872 | const cqe_accept = try ring.copy_cqe(); |
| ... | @@ -1900,7 +1900,7 @@ test "accept_direct" { | ... | @@ -1900,7 +1900,7 @@ test "accept_direct" { |
| 1900 | // connect | 1900 | // connect |
| 1901 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 1901 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 1902 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); | 1902 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); |
| 1903 | defer posix.close(client); | 1903 | defer _ = linux.close(client); |
| 1904 | // completion with error | 1904 | // completion with error |
| 1905 | const cqe_accept = try ring.copy_cqe(); | 1905 | const cqe_accept = try ring.copy_cqe(); |
| 1906 | try testing.expect(cqe_accept.user_data == accept_userdata); | 1906 | try testing.expect(cqe_accept.user_data == accept_userdata); |
| ... | @@ -1936,7 +1936,7 @@ test "accept_multishot_direct" { | ... | @@ -1936,7 +1936,7 @@ test "accept_multishot_direct" { |
| 1936 | try ring.register_files(registered_fds[0..]); | 1936 | try ring.register_files(registered_fds[0..]); |
| 1937 | 1937 | ||
| 1938 | const listener_socket = try createListenerSocket(&address); | 1938 | const listener_socket = try createListenerSocket(&address); |
| 1939 | defer posix.close(listener_socket); | 1939 | defer _ = linux.close(listener_socket); |
| 1940 | 1940 | ||
| 1941 | const accept_userdata: u64 = 0xaaaaaaaa; | 1941 | const accept_userdata: u64 = 0xaaaaaaaa; |
| 1942 | 1942 | ||
| ... | @@ -1950,7 +1950,7 @@ test "accept_multishot_direct" { | ... | @@ -1950,7 +1950,7 @@ test "accept_multishot_direct" { |
| 1950 | // connect | 1950 | // connect |
| 1951 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 1951 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 1952 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); | 1952 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); |
| 1953 | defer posix.close(client); | 1953 | defer _ = linux.close(client); |
| 1954 | 1954 | ||
| 1955 | // accept completion | 1955 | // accept completion |
| 1956 | const cqe_accept = try ring.copy_cqe(); | 1956 | const cqe_accept = try ring.copy_cqe(); |
| ... | @@ -1965,7 +1965,7 @@ test "accept_multishot_direct" { | ... | @@ -1965,7 +1965,7 @@ test "accept_multishot_direct" { |
| 1965 | // connect | 1965 | // connect |
| 1966 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 1966 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 1967 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); | 1967 | try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); |
| 1968 | defer posix.close(client); | 1968 | defer _ = linux.close(client); |
| 1969 | // completion with error | 1969 | // completion with error |
| 1970 | const cqe_accept = try ring.copy_cqe(); | 1970 | const cqe_accept = try ring.copy_cqe(); |
| 1971 | try testing.expect(cqe_accept.user_data == accept_userdata); | 1971 | try testing.expect(cqe_accept.user_data == accept_userdata); |
| ... | @@ -1998,7 +1998,7 @@ test "socket" { | ... | @@ -1998,7 +1998,7 @@ test "socket" { |
| 1998 | const fd: linux.fd_t = @intCast(cqe.res); | 1998 | const fd: linux.fd_t = @intCast(cqe.res); |
| 1999 | try testing.expect(fd > 2); | 1999 | try testing.expect(fd > 2); |
| 2000 | 2000 | ||
| 2001 | posix.close(fd); | 2001 | _ = linux.close(fd); |
| 2002 | } | 2002 | } |
| 2003 | 2003 | ||
| 2004 | test "socket_direct/socket_direct_alloc/close_direct" { | 2004 | test "socket_direct/socket_direct_alloc/close_direct" { |
| ... | @@ -2042,7 +2042,7 @@ test "socket_direct/socket_direct_alloc/close_direct" { | ... | @@ -2042,7 +2042,7 @@ test "socket_direct/socket_direct_alloc/close_direct" { |
| 2042 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 2042 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), |
| 2043 | }; | 2043 | }; |
| 2044 | const listener_socket = try createListenerSocket(&address); | 2044 | const listener_socket = try createListenerSocket(&address); |
| 2045 | defer posix.close(listener_socket); | 2045 | defer _ = linux.close(listener_socket); |
| 2046 | const accept_userdata: u64 = 0xaaaaaaaa; | 2046 | const accept_userdata: u64 = 0xaaaaaaaa; |
| 2047 | const connect_userdata: u64 = 0xbbbbbbbb; | 2047 | const connect_userdata: u64 = 0xbbbbbbbb; |
| 2048 | const close_userdata: u64 = 0xcccccccc; | 2048 | const close_userdata: u64 = 0xcccccccc; |
| ... | @@ -2599,8 +2599,8 @@ pub const SocketTestHarness = struct { | ... | @@ -2599,8 +2599,8 @@ pub const SocketTestHarness = struct { |
| 2599 | client: posix.socket_t, | 2599 | client: posix.socket_t, |
| 2600 | 2600 | ||
| 2601 | pub fn close(self: SocketTestHarness) void { | 2601 | pub fn close(self: SocketTestHarness) void { |
| 2602 | posix.close(self.client); | 2602 | _ = linux.close(self.client); |
| 2603 | posix.close(self.listener); | 2603 | _ = linux.close(self.listener); |
| 2604 | } | 2604 | } |
| 2605 | }; | 2605 | }; |
| 2606 | 2606 | ||
| ... | @@ -2611,7 +2611,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { | ... | @@ -2611,7 +2611,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { |
| 2611 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 2611 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), |
| 2612 | }; | 2612 | }; |
| 2613 | const listener_socket = try createListenerSocket(&address); | 2613 | const listener_socket = try createListenerSocket(&address); |
| 2614 | errdefer posix.close(listener_socket); | 2614 | errdefer _ = linux.close(listener_socket); |
| 2615 | 2615 | ||
| 2616 | // Submit 1 accept | 2616 | // Submit 1 accept |
| 2617 | var accept_addr: posix.sockaddr = undefined; | 2617 | var accept_addr: posix.sockaddr = undefined; |
| ... | @@ -2620,7 +2620,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { | ... | @@ -2620,7 +2620,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { |
| 2620 | 2620 | ||
| 2621 | // Create a TCP client socket | 2621 | // Create a TCP client socket |
| 2622 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 2622 | const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 2623 | errdefer posix.close(client); | 2623 | errdefer _ = linux.close(client); |
| 2624 | _ = try ring.connect(0xcccccccc, client, addrAny(&address), @sizeOf(linux.sockaddr.in)); | 2624 | _ = try ring.connect(0xcccccccc, client, addrAny(&address), @sizeOf(linux.sockaddr.in)); |
| 2625 | 2625 | ||
| 2626 | try testing.expectEqual(@as(u32, 2), try ring.submit()); | 2626 | try testing.expectEqual(@as(u32, 2), try ring.submit()); |
| ... | @@ -2660,7 +2660,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { | ... | @@ -2660,7 +2660,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { |
| 2660 | fn createListenerSocket(address: *linux.sockaddr.in) !posix.socket_t { | 2660 | fn createListenerSocket(address: *linux.sockaddr.in) !posix.socket_t { |
| 2661 | const kernel_backlog = 1; | 2661 | const kernel_backlog = 1; |
| 2662 | const listener_socket = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); | 2662 | const listener_socket = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); |
| 2663 | errdefer posix.close(listener_socket); | 2663 | errdefer _ = linux.close(listener_socket); |
| 2664 | 2664 | ||
| 2665 | try posix.setsockopt(listener_socket, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1))); | 2665 | try posix.setsockopt(listener_socket, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1))); |
| 2666 | try bind(listener_socket, addrAny(address), @sizeOf(linux.sockaddr.in)); | 2666 | try bind(listener_socket, addrAny(address), @sizeOf(linux.sockaddr.in)); |
lib/std/os/linux/test.zig+36| ... | @@ -407,6 +407,42 @@ test "futex2_requeue" { | ... | @@ -407,6 +407,42 @@ test "futex2_requeue" { |
| 407 | try expectEqual(0, rc); | 407 | try expectEqual(0, rc); |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | test "timerfd" { | ||
| 411 | const tfd: linux.fd_t = rc: { | ||
| 412 | const rc = linux.timerfd_create(.MONOTONIC, .{ .CLOEXEC = true }); | ||
| 413 | switch (linux.errno(rc)) { | ||
| 414 | .SUCCESS => break :rc @intCast(rc), | ||
| 415 | else => @panic("test failed"), | ||
| 416 | } | ||
| 417 | }; | ||
| 418 | defer _ = linux.close(tfd); | ||
| 419 | |||
| 420 | // Fire event 10_000_000ns = 10ms after the posix.timerfd_settime call. | ||
| 421 | var sit: linux.itimerspec = .{ .it_interval = .{ .sec = 0, .nsec = 0 }, .it_value = .{ .sec = 0, .nsec = 10 * (1000 * 1000) } }; | ||
| 422 | const flags: linux.TFD.TIMER = .{}; | ||
| 423 | switch (linux.errno(linux.timerfd_settime(tfd, @bitCast(flags), &sit, null))) { | ||
| 424 | .SUCCESS => {}, | ||
| 425 | else => @panic("test failed"), | ||
| 426 | } | ||
| 427 | |||
| 428 | var fds: [1]std.posix.pollfd = .{.{ .fd = tfd, .events = linux.POLL.IN, .revents = 0 }}; | ||
| 429 | try expectEqual(@as(usize, 1), try std.posix.poll(&fds, -1)); // -1 => infinite waiting | ||
| 430 | |||
| 431 | const git = rc: { | ||
| 432 | var curr_value: linux.itimerspec = undefined; | ||
| 433 | const rc = linux.timerfd_gettime(tfd, &curr_value); | ||
| 434 | switch (linux.errno(rc)) { | ||
| 435 | .SUCCESS => break :rc curr_value, | ||
| 436 | else => @panic("test failed"), | ||
| 437 | } | ||
| 438 | }; | ||
| 439 | const expect_disarmed_timer: linux.itimerspec = .{ | ||
| 440 | .it_interval = .{ .sec = 0, .nsec = 0 }, | ||
| 441 | .it_value = .{ .sec = 0, .nsec = 0 }, | ||
| 442 | }; | ||
| 443 | try expectEqual(expect_disarmed_timer, git); | ||
| 444 | } | ||
| 445 | |||
| 410 | test { | 446 | test { |
| 411 | _ = linux.IoUring; | 447 | _ = linux.IoUring; |
| 412 | } | 448 | } |
lib/std/posix.zig-78| ... | @@ -278,30 +278,6 @@ pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t; | ... | @@ -278,30 +278,6 @@ pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t; |
| 278 | /// the system function call whose errno value is intended to be observed. | 278 | /// the system function call whose errno value is intended to be observed. |
| 279 | pub const errno = system.errno; | 279 | pub const errno = system.errno; |
| 280 | 280 | ||
| 281 | /// Closes the file descriptor. | ||
| 282 | /// | ||
| 283 | /// Asserts the file descriptor is open. | ||
| 284 | /// | ||
| 285 | /// This function is not capable of returning any indication of failure. An | ||
| 286 | /// application which wants to ensure writes have succeeded before closing must | ||
| 287 | /// call `fsync` before `close`. | ||
| 288 | /// | ||
| 289 | /// The Zig standard library does not support POSIX thread cancellation. | ||
| 290 | pub fn close(fd: fd_t) void { | ||
| 291 | if (native_os == .windows) { | ||
| 292 | return windows.CloseHandle(fd); | ||
| 293 | } | ||
| 294 | if (native_os == .wasi and !builtin.link_libc) { | ||
| 295 | _ = std.os.wasi.fd_close(fd); | ||
| 296 | return; | ||
| 297 | } | ||
| 298 | switch (errno(system.close(fd))) { | ||
| 299 | .BADF => unreachable, // Always a race condition. | ||
| 300 | .INTR => return, // This is still a success. See https://github.com/ziglang/zig/issues/2425 | ||
| 301 | else => return, | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | pub const RebootError = error{ | 281 | pub const RebootError = error{ |
| 306 | PermissionDenied, | 282 | PermissionDenied, |
| 307 | } || UnexpectedError; | 283 | } || UnexpectedError; |
| ... | @@ -1541,60 +1517,6 @@ pub fn perf_event_open( | ... | @@ -1541,60 +1517,6 @@ pub fn perf_event_open( |
| 1541 | } | 1517 | } |
| 1542 | } | 1518 | } |
| 1543 | 1519 | ||
| 1544 | pub const TimerFdCreateError = error{ | ||
| 1545 | PermissionDenied, | ||
| 1546 | ProcessFdQuotaExceeded, | ||
| 1547 | SystemFdQuotaExceeded, | ||
| 1548 | NoDevice, | ||
| 1549 | SystemResources, | ||
| 1550 | } || UnexpectedError; | ||
| 1551 | |||
| 1552 | pub const TimerFdGetError = error{InvalidHandle} || UnexpectedError; | ||
| 1553 | pub const TimerFdSetError = TimerFdGetError || error{Canceled}; | ||
| 1554 | |||
| 1555 | pub fn timerfd_create(clock_id: system.timerfd_clockid_t, flags: system.TFD) TimerFdCreateError!fd_t { | ||
| 1556 | const rc = system.timerfd_create(clock_id, @bitCast(flags)); | ||
| 1557 | return switch (errno(rc)) { | ||
| 1558 | .SUCCESS => @intCast(rc), | ||
| 1559 | .INVAL => unreachable, | ||
| 1560 | .MFILE => return error.ProcessFdQuotaExceeded, | ||
| 1561 | .NFILE => return error.SystemFdQuotaExceeded, | ||
| 1562 | .NODEV => return error.NoDevice, | ||
| 1563 | .NOMEM => return error.SystemResources, | ||
| 1564 | .PERM => return error.PermissionDenied, | ||
| 1565 | else => |err| return unexpectedErrno(err), | ||
| 1566 | }; | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | pub fn timerfd_settime( | ||
| 1570 | fd: i32, | ||
| 1571 | flags: system.TFD.TIMER, | ||
| 1572 | new_value: *const system.itimerspec, | ||
| 1573 | old_value: ?*system.itimerspec, | ||
| 1574 | ) TimerFdSetError!void { | ||
| 1575 | const rc = system.timerfd_settime(fd, @bitCast(flags), new_value, old_value); | ||
| 1576 | return switch (errno(rc)) { | ||
| 1577 | .SUCCESS => {}, | ||
| 1578 | .BADF => error.InvalidHandle, | ||
| 1579 | .FAULT => unreachable, | ||
| 1580 | .INVAL => unreachable, | ||
| 1581 | .CANCELED => error.Canceled, | ||
| 1582 | else => |err| return unexpectedErrno(err), | ||
| 1583 | }; | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | pub fn timerfd_gettime(fd: i32) TimerFdGetError!system.itimerspec { | ||
| 1587 | var curr_value: system.itimerspec = undefined; | ||
| 1588 | const rc = system.timerfd_gettime(fd, &curr_value); | ||
| 1589 | return switch (errno(rc)) { | ||
| 1590 | .SUCCESS => return curr_value, | ||
| 1591 | .BADF => error.InvalidHandle, | ||
| 1592 | .FAULT => unreachable, | ||
| 1593 | .INVAL => unreachable, | ||
| 1594 | else => |err| return unexpectedErrno(err), | ||
| 1595 | }; | ||
| 1596 | } | ||
| 1597 | |||
| 1598 | pub const PtraceError = error{ | 1520 | pub const PtraceError = error{ |
| 1599 | DeadLock, | 1521 | DeadLock, |
| 1600 | DeviceBusy, | 1522 | DeviceBusy, |
lib/std/posix/test.zig-18| ... | @@ -522,21 +522,3 @@ test "rename smoke test" { | ... | @@ -522,21 +522,3 @@ test "rename smoke test" { |
| 522 | try expectError(error.FileNotFound, Io.Dir.cwd().openDir(io, file_path, .{})); | 522 | try expectError(error.FileNotFound, Io.Dir.cwd().openDir(io, file_path, .{})); |
| 523 | } | 523 | } |
| 524 | } | 524 | } |
| 525 | |||
| 526 | test "timerfd" { | ||
| 527 | if (native_os != .linux) return error.SkipZigTest; | ||
| 528 | |||
| 529 | const tfd = try posix.timerfd_create(.MONOTONIC, .{ .CLOEXEC = true }); | ||
| 530 | defer posix.close(tfd); | ||
| 531 | |||
| 532 | // Fire event 10_000_000ns = 10ms after the posix.timerfd_settime call. | ||
| 533 | var sit: linux.itimerspec = .{ .it_interval = .{ .sec = 0, .nsec = 0 }, .it_value = .{ .sec = 0, .nsec = 10 * (1000 * 1000) } }; | ||
| 534 | try posix.timerfd_settime(tfd, .{}, &sit, null); | ||
| 535 | |||
| 536 | var fds: [1]posix.pollfd = .{.{ .fd = tfd, .events = linux.POLL.IN, .revents = 0 }}; | ||
| 537 | try expectEqual(@as(usize, 1), try posix.poll(&fds, -1)); // -1 => infinite waiting | ||
| 538 | |||
| 539 | const git = try posix.timerfd_gettime(tfd); | ||
| 540 | const expect_disarmed_timer: linux.itimerspec = .{ .it_interval = .{ .sec = 0, .nsec = 0 }, .it_value = .{ .sec = 0, .nsec = 0 } }; | ||
| 541 | try expectEqual(expect_disarmed_timer, git); | ||
| 542 | } |
src/libs/musl.zig-2| ... | @@ -1830,7 +1830,6 @@ const src_files = [_][]const u8{ | ... | @@ -1830,7 +1830,6 @@ const src_files = [_][]const u8{ |
| 1830 | "musl/src/time/wcsftime.c", | 1830 | "musl/src/time/wcsftime.c", |
| 1831 | "musl/src/time/__year_to_secs.c", | 1831 | "musl/src/time/__year_to_secs.c", |
| 1832 | "musl/src/unistd/alarm.c", | 1832 | "musl/src/unistd/alarm.c", |
| 1833 | "musl/src/unistd/close.c", | ||
| 1834 | "musl/src/unistd/dup2.c", | 1833 | "musl/src/unistd/dup2.c", |
| 1835 | "musl/src/unistd/dup3.c", | 1834 | "musl/src/unistd/dup3.c", |
| 1836 | "musl/src/unistd/faccessat.c", | 1835 | "musl/src/unistd/faccessat.c", |
| ... | @@ -1849,7 +1848,6 @@ const src_files = [_][]const u8{ | ... | @@ -1849,7 +1848,6 @@ const src_files = [_][]const u8{ |
| 1849 | "musl/src/unistd/nice.c", | 1848 | "musl/src/unistd/nice.c", |
| 1850 | "musl/src/unistd/pause.c", | 1849 | "musl/src/unistd/pause.c", |
| 1851 | "musl/src/unistd/pipe2.c", | 1850 | "musl/src/unistd/pipe2.c", |
| 1852 | "musl/src/unistd/posix_close.c", | ||
| 1853 | "musl/src/unistd/pread.c", | 1851 | "musl/src/unistd/pread.c", |
| 1854 | "musl/src/unistd/preadv.c", | 1852 | "musl/src/unistd/preadv.c", |
| 1855 | "musl/src/unistd/pwrite.c", | 1853 | "musl/src/unistd/pwrite.c", |
src/libs/wasi_libc.zig-1| ... | @@ -999,7 +999,6 @@ const libc_top_half_src_files = [_][]const u8{ | ... | @@ -999,7 +999,6 @@ const libc_top_half_src_files = [_][]const u8{ |
| 999 | "musl/src/time/strptime.c", | 999 | "musl/src/time/strptime.c", |
| 1000 | "musl/src/time/timespec_get.c", | 1000 | "musl/src/time/timespec_get.c", |
| 1001 | "musl/src/time/__year_to_secs.c", | 1001 | "musl/src/time/__year_to_secs.c", |
| 1002 | "musl/src/unistd/posix_close.c", | ||
| 1003 | 1002 | ||
| 1004 | "wasi/libc-top-half/musl/src/conf/fpathconf.c", | 1003 | "wasi/libc-top-half/musl/src/conf/fpathconf.c", |
| 1005 | "wasi/libc-top-half/musl/src/conf/sysconf.c", | 1004 | "wasi/libc-top-half/musl/src/conf/sysconf.c", |