From 83d837813999b73771a0e9623ed1c6c5339e4f4c Mon Sep 17 00:00:00 2001 From: aiotter Date: Fri, 6 May 2022 21:58:20 +0900 Subject: [PATCH 1/3] std.c: Add C APIs to read directories --- lib/std/c.zig | 15 +++++++++++++++ lib/std/c/darwin.zig | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/lib/std/c.zig b/lib/std/c.zig index d98dbf0cde..0590c3554a 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -59,6 +59,20 @@ pub usingnamespace switch (builtin.os.tag) { pub const whence_t = if (builtin.os.tag == .wasi) std.os.wasi.whence_t else c_int; +// Unix-like systems +pub usingnamespace switch (builtin.os.tag) { + .netbsd, .windows => struct {}, + else => struct { + pub const DIR = opaque {}; + pub extern "c" fn opendir(pathname: [*:0]const u8) ?*DIR; + pub extern "c" fn fdopendir(fd: c_int) ?*DIR; + pub extern "c" fn rewinddir(dp: *DIR) void; + pub extern "c" fn closedir(dp: *DIR) c_int; + pub extern "c" fn telldir(dp: *DIR) c_long; + pub extern "c" fn seekdir(dp: *DIR, loc: c_long) void; + }, +}; + pub usingnamespace switch (builtin.os.tag) { .netbsd, .macos, .ios, .watchos, .tvos, .windows => struct {}, else => struct { @@ -76,6 +90,7 @@ pub usingnamespace switch (builtin.os.tag) { pub extern "c" fn sigfillset(set: ?*c.sigset_t) void; pub extern "c" fn alarm(seconds: c_uint) c_uint; pub extern "c" fn sigwait(set: ?*c.sigset_t, sig: ?*c_int) c_int; + pub extern "c" fn readdir(dp: *c.DIR) ?*c.dirent; }, }; diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index b536471a30..d40701f04e 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -62,9 +62,13 @@ const private = struct { /// force 64bit version. /// Note that this is fixed on aarch64 and no longer necessary. extern "c" fn @"fstatat$INODE64"(dirfd: fd_t, path_name: [*:0]const u8, buf: *Stat, flags: u32) c_int; + + extern "c" fn readdir(dir: *std.c.DIR) ?*dirent; + extern "c" fn @"readdir$INODE64"(dir: *std.c.DIR) ?*dirent; }; pub const fstat = if (native_arch == .aarch64) private.fstat else private.@"fstat$INODE64"; pub const fstatat = if (native_arch == .aarch64) private.fstatat else private.@"fstatat$INODE64"; +pub const readdir = if (native_arch == .aarch64) private.readdir else private.@"readdir$INODE64"; pub extern "c" fn mach_absolute_time() u64; pub extern "c" fn mach_continuous_time() u64; From ad7f725dbacb8144bdff7f0ce3bcfaf47725a4bc Mon Sep 17 00:00:00 2001 From: aiotter Date: Fri, 6 May 2022 23:52:21 +0900 Subject: [PATCH 2/3] std.c: Move Darwin-unspecific functions from std/c/darwin.zig to std/c.zig --- lib/std/c.zig | 33 ++++++++++++++++++++------------- lib/std/c/darwin.zig | 13 ------------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/lib/std/c.zig b/lib/std/c.zig index 0590c3554a..c33d7b35ab 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -70,26 +70,33 @@ pub usingnamespace switch (builtin.os.tag) { pub extern "c" fn closedir(dp: *DIR) c_int; pub extern "c" fn telldir(dp: *DIR) c_long; pub extern "c" fn seekdir(dp: *DIR, loc: c_long) void; + + pub extern "c" fn clock_gettime(clk_id: c_int, tp: *c.timespec) c_int; + pub extern "c" fn clock_getres(clk_id: c_int, tp: *c.timespec) c_int; + pub extern "c" fn gettimeofday(noalias tv: ?*c.timeval, noalias tz: ?*c.timezone) c_int; + pub extern "c" fn nanosleep(rqtp: *const c.timespec, rmtp: ?*c.timespec) c_int; + + pub extern "c" fn getrusage(who: c_int, usage: *c.rusage) c_int; + + pub extern "c" fn sched_yield() c_int; + + pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const c.Sigaction, noalias oact: ?*c.Sigaction) c_int; + pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const c.sigset_t, noalias oset: ?*c.sigset_t) c_int; + pub extern "c" fn sigfillset(set: ?*c.sigset_t) void; + pub extern "c" fn sigwait(set: ?*c.sigset_t, sig: ?*c_int) c_int; + + pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int; + + pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *c.Stat) c_int; + + pub extern "c" fn alarm(seconds: c_uint) c_uint; }, }; pub usingnamespace switch (builtin.os.tag) { .netbsd, .macos, .ios, .watchos, .tvos, .windows => struct {}, else => struct { - pub extern "c" fn clock_getres(clk_id: c_int, tp: *c.timespec) c_int; - pub extern "c" fn clock_gettime(clk_id: c_int, tp: *c.timespec) c_int; pub extern "c" fn fstat(fd: c.fd_t, buf: *c.Stat) c_int; - pub extern "c" fn getrusage(who: c_int, usage: *c.rusage) c_int; - pub extern "c" fn gettimeofday(noalias tv: ?*c.timeval, noalias tz: ?*c.timezone) c_int; - pub extern "c" fn nanosleep(rqtp: *const c.timespec, rmtp: ?*c.timespec) c_int; - pub extern "c" fn sched_yield() c_int; - pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const c.Sigaction, noalias oact: ?*c.Sigaction) c_int; - pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const c.sigset_t, noalias oset: ?*c.sigset_t) c_int; - pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int; - pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *c.Stat) c_int; - pub extern "c" fn sigfillset(set: ?*c.sigset_t) void; - pub extern "c" fn alarm(seconds: c_uint) c_uint; - pub extern "c" fn sigwait(set: ?*c.sigset_t, sig: ?*c_int) c_int; pub extern "c" fn readdir(dp: *c.DIR) ?*c.dirent; }, }; diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index d40701f04e..e44da7e1f7 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -700,19 +700,6 @@ pub extern "c" fn os_unfair_lock_assert_not_owner(o: os_unfair_lock_t) void; // XXX: close -> close$NOCANCEL // XXX: getdirentries -> _getdirentries64 -pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int; -pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int; -pub extern "c" fn getrusage(who: c_int, usage: *rusage) c_int; -pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; -pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; -pub extern "c" fn sched_yield() c_int; -pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int; -pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; -pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int; -pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *Stat) c_int; -pub extern "c" fn sigfillset(set: ?*sigset_t) void; -pub extern "c" fn alarm(seconds: c_uint) c_uint; -pub extern "c" fn sigwait(set: ?*sigset_t, sig: ?*c_int) c_int; // See: https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/sys/_types.h.auto.html // TODO: audit mode_t/pid_t, should likely be u16/i32 From 552ef5f2e4ecc4b788476be6836d262aaf3216d3 Mon Sep 17 00:00:00 2001 From: aiotter Date: Sat, 7 May 2022 10:10:21 +0900 Subject: [PATCH 3/3] std.c: Implement dirent on std/c/linux.zig --- lib/std/c/linux.zig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index 5f96fe3fe0..325ef3a894 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -364,3 +364,18 @@ pub const RTLD = struct { pub const GLOBAL = 256; pub const LOCAL = 0; }; + +pub const dirent = struct { + d_ino: c_uint, + d_off: c_uint, + d_reclen: c_ushort, + d_type: u8, + d_name: [256]u8, +}; +pub const dirent64 = struct { + d_ino: c_ulong, + d_off: c_ulong, + d_reclen: c_ushort, + d_type: u8, + d_name: [256]u8, +};