diff --git a/src/main.zig b/src/main.zig index 5e2e5fd..6b50b2c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,11 +1,18 @@ const psp = @import("psp/pspsdk.zig"); +pub const os = @import("psp/pspos.zig"); +pub const panic = @import("psp/utils/debug.zig").panic; -comptime{ - asm(psp.module_info("Zig PSP", 0, 1, 0)); +const std = @import("std"); + +comptime { + asm (psp.module_info("Zig PSP", 0, 1, 0)); } pub fn main() !void { psp.utils.enableHBCB(); psp.debug.screenInit(); psp.debug.print("Hi!"); + + var f = try std.fs.cwd().openFile("hello.zig", .{.write = true}); + std.debug.warn("{}", .{f.isTty()}); } diff --git a/src/psp/os/bits.zig b/src/psp/os/bits.zig index 8439457..8cc1a50 100644 --- a/src/psp/os/bits.zig +++ b/src/psp/os/bits.zig @@ -8,6 +8,7 @@ pub const timespec = struct{ }; pub const fd_t = usize; +pub const ino_t = u64; pub const mode_t = u32; pub const PATH_MAX = 1024; @@ -167,6 +168,11 @@ pub const O_NOWAIT = 0x8000; pub const SEEK_SET = 0; pub const O_APPEND = 0x0100; pub const O_CLOEXEC = 0; //Don't do anything +pub const O_NOCTTY = 0; //Don't do anything +pub const R_OK = 1; +pub const W_OK = 1; +pub const F_OK = 1; +pub const X_OK = 1; pub const LOCK_SH = 1; pub const LOCK_EX = 2; @@ -206,3 +212,51 @@ pub const AT_STATX_DONT_SYNC = 0x4000; /// Apply to the entire subtree pub const AT_RECURSIVE = 0x8000; + +usingnamespace @import("../sdk/pspiofilemgr.zig"); +usingnamespace @import("../sdk/psptypes.zig"); +pub const Stat = struct { + mode: u32, + st_attr: c_uint, + size: u64, + st_ctime: ScePspDateTime, + st_atime: ScePspDateTime, + st_mtime: ScePspDateTime, + st_private: [6]c_uint, + ino: ino_t, + + pub fn atime(self: Stat) timespec { + return timespec{.tv_sec = self.st_atime.second, .tv_nsec = @bitCast(isize, self.st_atime.microsecond)*1000}; + } + pub fn mtime(self: Stat) timespec { + return timespec{.tv_sec = self.st_mtime.second, .tv_nsec = @bitCast(isize, self.st_mtime.microsecond)*1000}; + } + pub fn ctime(self: Stat) timespec { + return timespec{.tv_sec = self.st_ctime.second, .tv_nsec = @bitCast(isize, self.st_ctime.microsecond)*1000}; + } +}; + + +pub const S_IFBLK = 524288; +pub const S_IFCHR = 262144; +pub const S_IFIFO = 131072; +pub const S_IFSOCK = 65536; +pub const S_IFMT = 61440; +pub const S_IFLNK = 16384; +pub const S_IFDIR = 4096; +pub const S_IFREG = 8192; +pub const S_ISUID = 2048; +pub const S_ISGID = 1024; +pub const S_ISVTX = 512; +pub const S_IRWXU = 448; +pub const S_IRUSR = 256; +pub const S_IWUSR = 128; +pub const S_IXUSR = 64; +pub const S_IRWXG = 56; +pub const S_IRGRP = 32; +pub const S_IWGRP = 16; +pub const S_IXGRP = 8; +pub const S_IRWXO = 7; +pub const S_IROTH = 4; +pub const S_IWOTH = 2; +pub const S_IXOTH = 1; diff --git a/src/psp/os/system.zig b/src/psp/os/system.zig index 88900a9..fc83e68 100644 --- a/src/psp/os/system.zig +++ b/src/psp/os/system.zig @@ -3,12 +3,12 @@ usingnamespace @import("fdman.zig"); usingnamespace @import("cwd.zig"); pub var errno : u32 = 0; -fn pspErrToErrno(code: u32) i32{ +fn pspErrToErrno(code: u64) i32{ if ((code & 0x80010000) == 0x80010000) { - errno = code & 0xFFFF; + errno = @truncate(u32, code & 0xFFFF); return -1; } - return @bitCast(i32, code); + return @bitCast(i32, @truncate(u32, code)); } pub fn getErrno(r: c_int) usize { @@ -148,3 +148,128 @@ pub fn close(fd: fd_t) c_int { errno = EBADF; return -1; } + +pub fn unlinkat(dir: fd_t, path: [*:0]const u8, flags: u32) c_int{ + if(dir != AT_FDCWD){ + @panic("Non-FDCWD Not Supported"); + } + + var dest : [PATH_MAX + 1]u8 = undefined; + + var stat = __psp_path_absolute(path, dest[0..], PATH_MAX); + if(stat < 0) { + errno = ENAMETOOLONG; + return -1; + } + + var fdStat: SceIoStat = undefined; + _ = sceIoGetstat(dest[0..], &fdStat); + + if(fdStat.st_mode & @enumToInt(IOAccessModes.FIO_S_IFDIR) != 0){ + return pspErrToErrno(@bitCast(u32, sceIoRmdir(dest[0..]))); + }else{ + return pspErrToErrno(@bitCast(u32, sceIoRemove(dest[0..]))); + } + +} + +pub fn mkdirat(dir: fd_t, path: [*:0]const u8, mode: u32) c_int{ + if(dir != AT_FDCWD){ + @panic("Non-FDCWD Not Supported"); + } + + var dest : [PATH_MAX + 1]u8 = undefined; + var stat = __psp_path_absolute(path, dest[0..], PATH_MAX); + if(stat < 0) { + errno = ENAMETOOLONG; + return -1; + } + + return pspErrToErrno(@bitCast(u32, sceIoMkdir(dest[0..], mode))); +} + +pub fn fstat(fd: fd_t, stat: *Stat) c_int { + var psp_stat : SceIoStat = undefined; + var dest : [PATH_MAX + 1]u8 = undefined; + var ret : i32 = 0; + + var status = __psp_path_absolute(@ptrCast([*]const u8, &__psp_descriptormap[fd].?.filename.?), dest[0..], PATH_MAX); + if(status < 0) { + errno = ENAMETOOLONG; + return -1; + } + + @memset(@ptrCast([*]u8, stat), 0, @sizeOf(Stat)); + ret = sceIoGetstat(dest[0..], &psp_stat); + if (ret < 0) { + return pspErrToErrno(@bitCast(u32, ret)); + } + + stat.mode = @bitCast(u32, psp_stat.st_mode); + stat.st_attr = @as(u64, psp_stat.st_attr); + stat.size = @bitCast(u64, psp_stat.st_size); + stat.st_ctime = psp_stat.st_ctime; + stat.st_atime = psp_stat.st_atime; + stat.st_mtime = psp_stat.st_mtime; + stat.st_private = psp_stat.st_private; + + return 0; +} + +pub fn faccessat(dir: fd_t, path: [*:0]const u8, mode: u32, flags: u32) c_int{ + if(dir != AT_FDCWD){ + @panic("Non-FDCWD Not Supported"); + } + + var dest : [PATH_MAX + 1]u8 = undefined; + var stat = __psp_path_absolute(path, dest[0..], PATH_MAX); + if(stat < 0) { + errno = ENAMETOOLONG; + return -1; + } + + var fdStat: SceIoStat = undefined; + var v = sceIoGetstat(dest[0..], &fdStat); + if(v != 0){ + return pspErrToErrno(@bitCast(u32, v)); + } + + if(fdStat.st_mode & S_IFDIR != 0){ + return 0; + } + if (flags & W_OK == 0){ + return 0; + } + + errno = EACCES; + return -1; +} + +pub fn lseek(fd: fd_t, off: i64, whence: c_int) c_int{ + if(!__psp_fdman_fdValid(fd)){ + errno = EBADF; + return -1; + } + + switch(__psp_descriptormap[fd].?.ftype){ + .File => { + std.debug.warn("{}", .{whence}); + //If you need to seek past 4GB, you have a real problem. + return pspErrToErrno(@bitCast(u32, sceIoLseek32(__psp_descriptormap[fd].?.sce_descriptor, @truncate(c_int, off), whence))); + }, + + else => { + errno = EBADF; + return -1; + } + } +} + +pub fn isatty(fd: fd_t) c_int{ + if(!__psp_fdman_fdValid(fd)){ + errno = EBADF; + return -1; + } + + return @intCast(c_int, @boolToInt(__psp_fdman_fdType(fd, __psp_fdman_type.Tty))); +} diff --git a/src/psp/sdk/pspiofilemgr.zig b/src/psp/sdk/pspiofilemgr.zig index dad7423..90c015d 100644 --- a/src/psp/sdk/pspiofilemgr.zig +++ b/src/psp/sdk/pspiofilemgr.zig @@ -48,7 +48,7 @@ pub const PSP_O_NOWAIT = 0x8000; pub const PSP_SEEK_SET = 0; pub const PSP_O_APPEND = 0x0100; -pub const struct_SceIoStat = extern struct { +pub const SceIoStat = extern struct { st_mode: SceMode, st_attr: c_uint, st_size: SceOff, @@ -57,7 +57,7 @@ pub const struct_SceIoStat = extern struct { st_mtime: ScePspDateTime, st_private: [6]c_uint, }; -pub const SceIoStat = struct_SceIoStat; + pub const struct_SceIoDirent = extern struct { d_stat: SceIoStat, d_name: [256]u8, @@ -79,12 +79,12 @@ pub extern fn sceIoRead(fd: SceUID, data: ?*c_void, size: SceSize) c_int; pub extern fn sceIoReadAsync(fd: SceUID, data: ?*c_void, size: SceSize) c_int; pub extern fn sceIoWrite(fd: SceUID, data: ?*const c_void, size: SceSize) c_int; pub extern fn sceIoWriteAsync(fd: SceUID, data: ?*const c_void, size: SceSize) c_int; -pub extern fn sceIoLseek(fd: SceUID, offset: SceOff, whence: c_int) SceOff; +pub extern fn sceIoLseek(fd: SceUID, offset: SceOff, whence: c_int) i64; pub extern fn sceIoLseekAsync(fd: SceUID, offset: SceOff, whence: c_int) c_int; pub extern fn sceIoLseek32(fd: SceUID, offset: c_int, whence: c_int) c_int; pub extern fn sceIoLseek32Async(fd: SceUID, offset: c_int, whence: c_int) c_int; pub extern fn sceIoRemove(file: [*c]const u8) c_int; -pub extern fn sceIoMkdir(dir: [*c]const u8, mode: SceMode) c_int; +pub extern fn sceIoMkdir(dir: [*c]const u8, mode: u32) c_int; pub extern fn sceIoRmdir(path: [*c]const u8) c_int; pub extern fn sceIoChdir(path: [*c]const u8) c_int; pub extern fn sceIoRename(oldname: [*c]const u8, newname: [*c]const u8) c_int; diff --git a/src/psp/utils/module.zig b/src/psp/utils/module.zig index 4bc8ee8..26ac436 100644 --- a/src/psp/utils/module.zig +++ b/src/psp/utils/module.zig @@ -42,7 +42,7 @@ pub fn _module_main_thread(argc: SceSize, argv: ?*c_void) callconv(.C) c_int { print("ERROR CAUGHT: "); print(@errorName(err)); - print("Exiting in 10 seconds..."); + print("\nExiting in 10 seconds..."); exitErr(); return 1;