mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
plan 9: filesystem support
This commit is contained in:
parent
6293a646e3
commit
b9aa1dcaf1
@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
|
||||
/// fit into a UTF-8 encoded array of this length.
|
||||
/// The byte count includes room for a null sentinel byte.
|
||||
pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
|
||||
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris => os.PATH_MAX,
|
||||
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .plan9 => os.PATH_MAX,
|
||||
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
|
||||
// If it would require 4 UTF-8 bytes, then there would be a surrogate
|
||||
// pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
|
||||
@ -1160,7 +1160,9 @@ pub const Dir = struct {
|
||||
return self.openFileW(path_w.span(), flags);
|
||||
}
|
||||
|
||||
var os_flags: u32 = os.O.CLOEXEC;
|
||||
var os_flags: u32 = 0;
|
||||
if (@hasDecl(os.O, "CLOEXEC")) os_flags = os.O.CLOEXEC;
|
||||
|
||||
// Use the O locking flags if the os supports them to acquire the lock
|
||||
// atomically.
|
||||
const has_flock_open_flags = @hasDecl(os.O, "EXLOCK");
|
||||
@ -1180,7 +1182,7 @@ pub const Dir = struct {
|
||||
if (@hasDecl(os.O, "LARGEFILE")) {
|
||||
os_flags |= os.O.LARGEFILE;
|
||||
}
|
||||
if (!flags.allow_ctty) {
|
||||
if (@hasDecl(os.O, "NOCTTY") and !flags.allow_ctty) {
|
||||
os_flags |= os.O.NOCTTY;
|
||||
}
|
||||
os_flags |= switch (flags.mode) {
|
||||
@ -1196,7 +1198,7 @@ pub const Dir = struct {
|
||||
|
||||
// WASI doesn't have os.flock so we intetinally check OS prior to the inner if block
|
||||
// since it is not compiltime-known and we need to avoid undefined symbol in Wasm.
|
||||
if (builtin.target.os.tag != .wasi) {
|
||||
if (@hasDecl(os.system, "LOCK") and builtin.target.os.tag != .wasi) {
|
||||
if (!has_flock_open_flags and flags.lock != .none) {
|
||||
// TODO: integrate async I/O
|
||||
const lock_nonblocking = if (flags.lock_nonblocking) os.LOCK.NB else @as(i32, 0);
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
const std = @import("../std.zig");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const fd_t = i32;
|
||||
|
||||
pub const STDIN_FILENO = 0;
|
||||
pub const STDOUT_FILENO = 1;
|
||||
pub const STDERR_FILENO = 2;
|
||||
pub const PATH_MAX = 1023;
|
||||
pub const syscall_bits = switch (builtin.cpu.arch) {
|
||||
.x86_64 => @import("plan9/x86_64.zig"),
|
||||
else => @compileError("more plan9 syscall implementations (needs more inline asm in stage2"),
|
||||
@ -57,7 +63,8 @@ pub const SIG = struct {
|
||||
};
|
||||
pub const sigset_t = c_long;
|
||||
pub const empty_sigset = 0;
|
||||
pub const siginfo_t = c_long; // TODO plan9 doesn't have sigaction_fn. Sigaction is not a union, but we incude it here to be compatible.
|
||||
pub const siginfo_t = c_long;
|
||||
// TODO plan9 doesn't have sigaction_fn. Sigaction is not a union, but we incude it here to be compatible.
|
||||
pub const Sigaction = extern struct {
|
||||
pub const handler_fn = *const fn (c_int) callconv(.C) void;
|
||||
pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
|
||||
@ -69,6 +76,9 @@ pub const Sigaction = extern struct {
|
||||
mask: sigset_t,
|
||||
flags: c_int,
|
||||
};
|
||||
pub const AT = struct {
|
||||
pub const FDCWD = -100; // we just make up a constant; FDCWD and openat don't actually exist in plan9
|
||||
};
|
||||
// TODO implement sigaction
|
||||
// right now it is just a shim to allow using start.zig code
|
||||
pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize {
|
||||
@ -132,20 +142,47 @@ pub const SYS = enum(usize) {
|
||||
_NSEC = 53,
|
||||
};
|
||||
|
||||
pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize {
|
||||
return syscall_bits.syscall4(.PWRITE, fd, @intFromPtr(buf), count, offset);
|
||||
pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
|
||||
return syscall_bits.syscall3(._WRITE, @bitCast(@as(isize, fd)), @intFromPtr(buf), count);
|
||||
}
|
||||
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
|
||||
return syscall_bits.syscall4(.PWRITE, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, offset);
|
||||
}
|
||||
|
||||
pub fn pread(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize {
|
||||
return syscall_bits.syscall4(.PREAD, fd, @intFromPtr(buf), count, offset);
|
||||
pub fn read(fd: i32, buf: [*]const u8, count: usize) usize {
|
||||
return syscall_bits.syscall3(._READ, @bitCast(@as(isize, fd)), @intFromPtr(buf), count);
|
||||
}
|
||||
pub fn pread(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
|
||||
return syscall_bits.syscall4(.PREAD, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, offset);
|
||||
}
|
||||
|
||||
pub fn open(path: [*:0]const u8, omode: OpenMode) usize {
|
||||
return syscall_bits.syscall2(.OPEN, @intFromPtr(path), @intFromEnum(omode));
|
||||
pub fn open(path: [*:0]const u8, omode: mode_t) usize {
|
||||
return syscall_bits.syscall2(.OPEN, @intFromPtr(path), @bitCast(@as(isize, omode)));
|
||||
}
|
||||
|
||||
pub fn create(path: [*:0]const u8, omode: OpenMode, perms: usize) usize {
|
||||
return syscall_bits.syscall3(.CREATE, @intFromPtr(path), @intFromEnum(omode), perms);
|
||||
pub fn openat(dirfd: i32, path: [*:0]const u8, _: u32, omode: mode_t) usize {
|
||||
if (dirfd == AT.FDCWD) { // openat(AT_FDCWD, ...) == open(...)
|
||||
return open(path, omode);
|
||||
}
|
||||
var dir_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
var total_path_buf: [std.fs.MAX_PATH_BYTES + 1]u8 = undefined;
|
||||
const rc = fd2path(dirfd, &dir_path_buf, std.fs.MAX_PATH_BYTES);
|
||||
if (rc != 0) return rc;
|
||||
var fba = std.heap.FixedBufferAllocator.init(&total_path_buf);
|
||||
var alloc = fba.allocator();
|
||||
const dir_path = std.mem.span(@as([*:0]u8, @ptrCast(&dir_path_buf)));
|
||||
const total_path = std.fs.path.join(alloc, &.{ dir_path, std.mem.span(path) }) catch unreachable; // the allocation shouldn't fail because it should not exceed MAX_PATH_BYTES
|
||||
fba.reset();
|
||||
const total_path_z = alloc.dupeZ(u8, total_path) catch unreachable; // should not exceed MAX_PATH_BYTES + 1
|
||||
return open(total_path_z.ptr, omode);
|
||||
}
|
||||
|
||||
pub fn fd2path(fd: i32, buf: [*]u8, nbuf: usize) usize {
|
||||
return syscall_bits.syscall3(.FD2PATH, @bitCast(@as(isize, fd)), @intFromPtr(buf), nbuf);
|
||||
}
|
||||
|
||||
pub fn create(path: [*:0]const u8, omode: mode_t, perms: usize) usize {
|
||||
return syscall_bits.syscall3(.CREATE, @intFromPtr(path), @bitCast(@as(isize, omode)), perms);
|
||||
}
|
||||
|
||||
pub fn exit(status: u8) noreturn {
|
||||
@ -163,16 +200,19 @@ pub fn exits(status: ?[*:0]const u8) noreturn {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
pub fn close(fd: usize) usize {
|
||||
return syscall_bits.syscall1(.CLOSE, fd);
|
||||
pub fn close(fd: i32) usize {
|
||||
return syscall_bits.syscall1(.CLOSE, @bitCast(@as(isize, fd)));
|
||||
}
|
||||
pub const OpenMode = enum(usize) {
|
||||
OREAD = 0, //* open for read
|
||||
OWRITE = 1, //* write
|
||||
ORDWR = 2, //* read and write
|
||||
OEXEC = 3, //* execute, == read but check execute permission
|
||||
OTRUNC = 16, //* or'ed in (except for exec), truncate file first
|
||||
OCEXEC = 32, //* or'ed in (per file descriptor), close on exec
|
||||
ORCLOSE = 64, //* or'ed in, remove on close
|
||||
OEXCL = 0x1000, //* or'ed in, exclusive create
|
||||
pub const mode_t = i32;
|
||||
pub const O = struct {
|
||||
pub const READ = 0; // open for read
|
||||
pub const RDONLY = 0;
|
||||
pub const WRITE = 1; // write
|
||||
pub const WRONLY = 1;
|
||||
pub const RDWR = 2; // read and write
|
||||
pub const EXEC = 3; // execute, == read but check execute permission
|
||||
pub const TRUNC = 16; // or'ed in (except for exec), truncate file first
|
||||
pub const CEXEC = 32; // or'ed in (per file descriptor), close on exec
|
||||
pub const RCLOSE = 64; // or'ed in, remove on close
|
||||
pub const EXCL = 0x1000; // or'ed in, exclusive create
|
||||
};
|
||||
|
||||
@ -73,4 +73,12 @@ pub const E = enum(u16) {
|
||||
// These added in 1003.1b-1993
|
||||
CANCELED = 61,
|
||||
INPROGRESS = 62,
|
||||
|
||||
// We just add these to be compatible with std.os, which uses them,
|
||||
// They should never get used.
|
||||
DQUOT,
|
||||
CONNRESET,
|
||||
OVERFLOW,
|
||||
LOOP,
|
||||
TXTBSY,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user