Commit 6b0372229d

Al Hoang <3811822-hoanga@users.noreply.gitlab.com>
2020-12-29 06:00:31
initial support for haiku continue clean up
* remove unused definitions * setup os specific blocks
1 parent 025635c
lib/std/c/haiku.zig
@@ -11,15 +11,13 @@ const builtin = std.builtin;
 usingnamespace std.c;
 
 extern "c" fn _errnop() *c_int;
+
 pub const _errno = _errnop;
 
-// not supported in haiku
-pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
+pub extern "c" fn _kern_read_dir(fd: c_int, buf_ptr: [*]u8, nbytes: usize, maxcount: u32) usize;
 
-pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
-//pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
+pub extern "c" fn _get_next_image_info(team: c_int, cookie: *i32, image_info: *image_info) usize;
 
-//
 pub const sem_t = extern struct {
     _magic: u32,
     _kern: extern struct {
lib/std/os/bits/haiku.zig
@@ -162,13 +162,11 @@ pub const timespec = extern struct {
 };
 
 pub const dirent = extern struct {
-    d_fileno: usize,
-    d_off: i64,
+    d_dev: i32,
+    d_pdev: i32,
+    d_ino: i64,
+    d_pino: i64,
     d_reclen: u16,
-    d_type: u8,
-    d_pad0: u8,
-    d_namlen: u16,
-    d_pad1: u16,
     d_name: [256]u8,
 
     pub fn reclen(self: dirent) u16 {
@@ -176,6 +174,24 @@ pub const dirent = extern struct {
     }
 };
 
+pub const image_info = extern struct {
+    id: u32,        //image_id
+    type: u32,      // image_type
+    sequence: i32,
+    init_order: i32,
+    init_routine: *c_void,
+    term_routine: *c_void,
+    device: i32,
+    node: i32,
+    name: [1024]u8,
+    text: *c_void,
+    data: *c_void,
+    text_size: i32,
+    data_size: i32,
+    api_version: i32,
+    abi: i32,
+};
+
 pub const in_port_t = u16;
 pub const sa_family_t = u8;
 
lib/std/debug.zig
@@ -1350,7 +1350,6 @@ pub const DebugInfo = struct {
 
         return &di;
     }
-
 };
 
 const SymbolInfo = struct {
@@ -1717,17 +1716,6 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
             unreachable;
         }
     },
-    .haiku => struct {
-        // Haiku should implement dl_iterat_phdr (https://dev.haiku-os.org/ticket/15743)
-        base_address: usize,
-        dwarf: DW.DwarfInfo,
-        mapped_memory: []const u8,
-
-        pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
-            // TODO: implement me
-            return SymbolInfo{};
-        }
-    },
     else => DW.DwarfInfo,
 };
 
@@ -1746,7 +1734,7 @@ fn getDebugInfoAllocator() *mem.Allocator {
 pub const have_segfault_handling_support = switch (builtin.os.tag) {
     .linux, .netbsd => true,
     .windows => true,
-    .freebsd, .openbsd, .haiku => @hasDecl(os, "ucontext_t"),
+    .freebsd, .openbsd => @hasDecl(os, "ucontext_t"),
     else => false,
 };
 pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
lib/std/fs.zig
@@ -302,7 +302,7 @@ pub const Dir = struct {
     const IteratorError = error{AccessDenied} || os.UnexpectedError;
 
     pub const Iterator = switch (builtin.os.tag) {
-        .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => struct {
+        .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
             dir: Dir,
             seek: i64,
             buf: [8192]u8, // TODO align(@alignOf(os.dirent)),
@@ -319,7 +319,6 @@ pub const Dir = struct {
                 switch (builtin.os.tag) {
                     .macos, .ios => return self.nextDarwin(),
                     .freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
-                    .haiku => return self.nextHaiku(),
                     else => @compileError("unimplemented"),
                 }
             }
@@ -427,16 +426,61 @@ pub const Dir = struct {
                     };
                 }
             }
+        },
+        .haiku => struct {
+            dir: Dir,
+            buf: [8192]u8, // TODO align(@alignOf(os.dirent64)),
+            index: usize,
+            end_index: usize,
 
-            fn nextHaiku(self: *Self) !?Entry {
-                //const name = @ptrCast([*]u8, "placeholder-please-implement-me");
-                //const name = "placeholder-please-implement-me";
-                return Entry{
-                    .name = base64_alphabet,
-                    .kind = Entry.Kind.File,
-                };
-            }
+            const Self = @This();
 
+            pub const Error = IteratorError;
+
+            /// Memory such as file names referenced in this returned entry becomes invalid
+            /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized.
+            pub fn next(self: *Self) Error!?Entry {
+                start_over: while (true) {
+                    // TODO: find a better max
+                    const HAIKU_MAX_COUNT = 10000;
+                    if (self.index >= self.end_index) {
+                        const rc = os.system._kern_read_dir(
+                            self.dir.fd,
+                            &self.buf,
+                            self.buf.len,
+                            HAIKU_MAX_COUNT,
+                        );
+                        if (rc == 0) return null;
+                        if (rc < 0) {
+                            switch (os.errno(rc)) {
+                                os.EBADF => unreachable, // Dir is invalid or was opened without iteration ability
+                                os.EFAULT => unreachable,
+                                os.ENOTDIR => unreachable,
+                                os.EINVAL => unreachable,
+                                else => |err| return os.unexpectedErrno(err),
+                            }
+                        }
+                        self.index = 0;
+                        self.end_index = @intCast(usize, rc);
+                    }
+                    const haiku_entry = @ptrCast(*align(1) os.dirent, &self.buf[self.index]);
+                    const next_index = self.index + haiku_entry.reclen();
+                    self.index = next_index;
+                    const name = mem.spanZ(@ptrCast([*:0]u8, &haiku_entry.d_name));
+
+                    if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..") or (haiku_entry.d_ino == 0)) {
+                        continue :start_over;
+                    }
+
+                    // TODO: determine entry kind
+                    const entry_kind = Entry.Kind.File;
+
+                    return Entry{
+                        .name = name,
+                        .kind = entry_kind,
+                    };
+                }
+            }
         },
         .linux => struct {
             dir: Dir,
@@ -632,14 +676,14 @@ pub const Dir = struct {
 
     pub fn iterate(self: Dir) Iterator {
         switch (builtin.os.tag) {
-            .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => return Iterator{
+            .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, => return Iterator{
                 .dir = self,
                 .seek = 0,
                 .index = 0,
                 .end_index = 0,
                 .buf = undefined,
             },
-            .linux => return Iterator{
+            .linux, .haiku => return Iterator{
                 .dir = self,
                 .index = 0,
                 .end_index = 0,
lib/std/os.zig
@@ -53,6 +53,7 @@ test {
     _ = uefi;
     _ = wasi;
     _ = windows;
+    _ = haiku;
 
     _ = @import("os/test.zig");
 }
@@ -601,7 +602,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
 /// On these systems, the read races with concurrent writes to the same file descriptor.
 pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
     const have_pread_but_not_preadv = switch (std.Target.current.os.tag) {
-        .windows, .macos, .ios, .watchos, .tvos => true,
+        .windows, .macos, .ios, .watchos, .tvos, .haiku => true,
         else => false,
     };
     if (have_pread_but_not_preadv) {
lib/std/process.zig
@@ -777,7 +777,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
             }
             return paths.toOwnedSlice();
         },
-        // Haiku should implement dl_iterat_phdr (https://dev.haiku-os.org/ticket/15743)
+        // revisit if Haiku implements dl_iterat_phdr (https://dev.haiku-os.org/ticket/15743)
         .haiku => {
             var paths = List.init(allocator);
             errdefer {
@@ -787,7 +787,12 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
                 }
                 allocator.free(slice);
             }
-            //TODO: fill out placeholder
+
+            var b = "/boot/system/runtime_loader";
+            const item = try allocator.dupeZ(u8, mem.spanZ(b));
+            errdefer allocator.free(item);
+            try paths.append(item);
+
             return paths.toOwnedSlice();
         },
         else => @compileError("getSelfExeSharedLibPaths unimplemented for this target"),
lib/std/target.zig
@@ -379,6 +379,7 @@ pub const Target = struct {
                 .watchos,
                 .dragonfly,
                 .openbsd,
+                .haiku,
                 => true,
 
                 .linux,
@@ -390,7 +391,6 @@ pub const Target = struct {
                 .kfreebsd,
                 .lv2,
                 .solaris,
-                .haiku,
                 .minix,
                 .rtems,
                 .nacl,
@@ -468,7 +468,6 @@ pub const Target = struct {
                 .dragonfly,
                 .lv2,
                 .solaris,
-                .haiku,
                 .minix,
                 .rtems,
                 .nacl,
@@ -495,6 +494,7 @@ pub const Target = struct {
                 .kfreebsd,
                 .netbsd,
                 .hurd,
+                .haiku,
                 => return .gnu,
                 .windows,
                 .uefi,
@@ -1566,6 +1566,10 @@ pub const Target = struct {
             .other,
             => return result,
 
+            // Operating systems in this list have been verified as not having a standard
+            // dynamic linker path.
+            .haiku => return copy(&result, "/system/runtime_loader"),
+
             // TODO go over each item in this list and either move it to the above list, or
             // implement the standard dynamic linker path code for it.
             .ananas,
@@ -1574,7 +1578,6 @@ pub const Target = struct {
             .kfreebsd,
             .lv2,
             .solaris,
-            .haiku,
             .minix,
             .rtems,
             .nacl,