| author | |
| committer | |
| log | 03bec631bd493dc157d0c071363c967caf7f57ac |
| tree | 79690b762f7ab14d6f9da6fc76be474e62d33a9f |
| parent | b946982e90c88d0c23cfb2e819f58ce8ff9af617 |
7 files changed, 77 insertions(+), 6 deletions(-)
src-self-hosted/main.zig+1-1| ... | @@ -175,7 +175,7 @@ fn cmdBuild(allocator: &Allocator, args: []const []const u8) !void { | ... | @@ -175,7 +175,7 @@ fn cmdBuild(allocator: &Allocator, args: []const []const u8) !void { |
| 175 | const build_file_abs = try os.path.resolve(allocator, ".", build_file); | 175 | const build_file_abs = try os.path.resolve(allocator, ".", build_file); |
| 176 | defer allocator.free(build_file_abs); | 176 | defer allocator.free(build_file_abs); |
| 177 | 177 | ||
| 178 | const build_file_exists = os.File.exists(allocator, build_file_abs); | 178 | const build_file_exists = os.File.access(allocator, build_file_abs, os.default_file_mode) catch false; |
| 179 | 179 | ||
| 180 | if (flags.present("init")) { | 180 | if (flags.present("init")) { |
| 181 | if (build_file_exists) { | 181 | if (build_file_exists) { |
std/c/index.zig+1| ... | @@ -28,6 +28,7 @@ pub extern "c" fn unlink(path: &const u8) c_int; | ... | @@ -28,6 +28,7 @@ pub extern "c" fn unlink(path: &const u8) c_int; |
| 28 | pub extern "c" fn getcwd(buf: &u8, size: usize) ?&u8; | 28 | pub extern "c" fn getcwd(buf: &u8, size: usize) ?&u8; |
| 29 | pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) c_int; | 29 | pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) c_int; |
| 30 | pub extern "c" fn fork() c_int; | 30 | pub extern "c" fn fork() c_int; |
| 31 | pub extern "c" fn access(path: &const u8, mode: c_uint) c_int; | ||
| 31 | pub extern "c" fn pipe(fds: &c_int) c_int; | 32 | pub extern "c" fn pipe(fds: &c_int) c_int; |
| 32 | pub extern "c" fn mkdir(path: &const u8, mode: c_uint) c_int; | 33 | pub extern "c" fn mkdir(path: &const u8, mode: c_uint) c_int; |
| 33 | pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int; | 34 | pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int; |
std/os/darwin.zig+9| ... | @@ -41,6 +41,11 @@ pub const SA_64REGSET = 0x0200; /// signal handler with SA_SIGINFO args with 64 | ... | @@ -41,6 +41,11 @@ pub const SA_64REGSET = 0x0200; /// signal handler with SA_SIGINFO args with 64 |
| 41 | pub const O_LARGEFILE = 0x0000; | 41 | pub const O_LARGEFILE = 0x0000; |
| 42 | pub const O_PATH = 0x0000; | 42 | pub const O_PATH = 0x0000; |
| 43 | 43 | ||
| 44 | pub const F_OK = 0; | ||
| 45 | pub const X_OK = 1; | ||
| 46 | pub const W_OK = 2; | ||
| 47 | pub const R_OK = 4; | ||
| 48 | |||
| 44 | pub const O_RDONLY = 0x0000; /// open for reading only | 49 | pub const O_RDONLY = 0x0000; /// open for reading only |
| 45 | pub const O_WRONLY = 0x0001; /// open for writing only | 50 | pub const O_WRONLY = 0x0001; /// open for writing only |
| 46 | pub const O_RDWR = 0x0002; /// open for reading and writing | 51 | pub const O_RDWR = 0x0002; /// open for reading and writing |
| ... | @@ -209,6 +214,10 @@ pub fn fork() usize { | ... | @@ -209,6 +214,10 @@ pub fn fork() usize { |
| 209 | return errnoWrap(c.fork()); | 214 | return errnoWrap(c.fork()); |
| 210 | } | 215 | } |
| 211 | 216 | ||
| 217 | pub fn access(path: &const u8, mode: u32) usize { | ||
| 218 | return errnoWrap(c.access(path, mode)); | ||
| 219 | } | ||
| 220 | |||
| 212 | pub fn pipe(fds: &[2]i32) usize { | 221 | pub fn pipe(fds: &[2]i32) usize { |
| 213 | comptime assert(i32.bit_count == c_int.bit_count); | 222 | comptime assert(i32.bit_count == c_int.bit_count); |
| 214 | return errnoWrap(c.pipe(@ptrCast(&c_int, fds))); | 223 | return errnoWrap(c.pipe(@ptrCast(&c_int, fds))); |
std/os/file.zig+38-5| ... | @@ -85,12 +85,45 @@ pub const File = struct { | ... | @@ -85,12 +85,45 @@ pub const File = struct { |
| 85 | }; | 85 | }; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | pub fn exists(allocator: &mem.Allocator, path: []const u8) bool { | 88 | pub fn access(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) !bool { |
| 89 | if (openRead(allocator, path)) |*file| { | 89 | const path_with_null = try std.cstr.addNullByte(allocator, path); |
| 90 | file.close(); | 90 | defer allocator.free(path_with_null); |
| 91 | |||
| 92 | if (is_posix) { | ||
| 93 | // mode is ignored and is always F_OK for now | ||
| 94 | const result = posix.access(path_with_null.ptr, posix.F_OK); | ||
| 95 | const err = posix.getErrno(result); | ||
| 96 | if (err > 0) { | ||
| 97 | return switch (err) { | ||
| 98 | posix.EACCES => error.PermissionDenied, | ||
| 99 | posix.EROFS => error.PermissionDenied, | ||
| 100 | posix.ELOOP => error.PermissionDenied, | ||
| 101 | posix.ETXTBSY => error.PermissionDenied, | ||
| 102 | posix.ENOTDIR => error.NotFound, | ||
| 103 | posix.ENOENT => error.NotFound, | ||
| 104 | |||
| 105 | posix.ENAMETOOLONG => error.NameTooLong, | ||
| 106 | posix.EINVAL => error.BadMode, | ||
| 107 | posix.EFAULT => error.BadPathName, | ||
| 108 | posix.EIO => error.Io, | ||
| 109 | posix.ENOMEM => error.SystemResources, | ||
| 110 | else => os.unexpectedErrorPosix(err), | ||
| 111 | }; | ||
| 112 | } | ||
| 91 | return true; | 113 | return true; |
| 92 | } else |_| { | 114 | } else if (is_windows) { |
| 93 | return false; | 115 | if (os.windows.PathFileExists(path_with_null.ptr)) { |
| 116 | return true; | ||
| 117 | } | ||
| 118 | |||
| 119 | const err = windows.GetLastError(); | ||
| 120 | return switch (err) { | ||
| 121 | windows.ERROR.FILE_NOT_FOUND => error.NotFound, | ||
| 122 | windows.ERROR.ACCESS_DENIED => error.PermissionDenied, | ||
| 123 | else => os.unexpectedErrorWindows(err), | ||
| 124 | }; | ||
| 125 | } else { | ||
| 126 | @compileError("TODO implement access for this OS"); | ||
| 94 | } | 127 | } |
| 95 | } | 128 | } |
| 96 | 129 |
std/os/linux/index.zig+9| ... | @@ -38,6 +38,11 @@ pub const MAP_STACK = 0x20000; | ... | @@ -38,6 +38,11 @@ pub const MAP_STACK = 0x20000; |
| 38 | pub const MAP_HUGETLB = 0x40000; | 38 | pub const MAP_HUGETLB = 0x40000; |
| 39 | pub const MAP_FILE = 0; | 39 | pub const MAP_FILE = 0; |
| 40 | 40 | ||
| 41 | pub const F_OK = 0; | ||
| 42 | pub const X_OK = 1; | ||
| 43 | pub const W_OK = 2; | ||
| 44 | pub const R_OK = 4; | ||
| 45 | |||
| 41 | pub const WNOHANG = 1; | 46 | pub const WNOHANG = 1; |
| 42 | pub const WUNTRACED = 2; | 47 | pub const WUNTRACED = 2; |
| 43 | pub const WSTOPPED = 2; | 48 | pub const WSTOPPED = 2; |
| ... | @@ -705,6 +710,10 @@ pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) usize { | ... | @@ -705,6 +710,10 @@ pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) usize { |
| 705 | return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset); | 710 | return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset); |
| 706 | } | 711 | } |
| 707 | 712 | ||
| 713 | pub fn access(path: &const u8, mode: u32) usize { | ||
| 714 | return syscall2(SYS_access, @ptrToInt(path), mode); | ||
| 715 | } | ||
| 716 | |||
| 708 | pub fn pipe(fd: &[2]i32) usize { | 717 | pub fn pipe(fd: &[2]i32) usize { |
| 709 | return pipe2(fd, 0); | 718 | return pipe2(fd, 0); |
| 710 | } | 719 | } |
std/os/test.zig+17| ... | @@ -23,3 +23,20 @@ test "makePath, put some files in it, deleteTree" { | ... | @@ -23,3 +23,20 @@ test "makePath, put some files in it, deleteTree" { |
| 23 | assert(err == error.PathNotFound); | 23 | assert(err == error.PathNotFound); |
| 24 | } | 24 | } |
| 25 | } | 25 | } |
| 26 | |||
| 27 | test "access file" { | ||
| 28 | if (builtin.os == builtin.Os.windows) { | ||
| 29 | return; | ||
| 30 | } | ||
| 31 | |||
| 32 | try os.makePath(a, "os_test_tmp"); | ||
| 33 | if (os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) |ok| { | ||
| 34 | unreachable; | ||
| 35 | } else |err| { | ||
| 36 | assert(err == error.NotFound); | ||
| 37 | } | ||
| 38 | |||
| 39 | try io.writeFile(a, "os_test_tmp/file.txt", ""); | ||
| 40 | assert((try os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) == true); | ||
| 41 | try os.deleteTree(a, "os_test_tmp"); | ||
| 42 | } |
std/os/windows/index.zig+2| ... | @@ -78,6 +78,8 @@ pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem | ... | @@ -78,6 +78,8 @@ pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem |
| 78 | pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, | 78 | pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, |
| 79 | dwFlags: DWORD) BOOL; | 79 | dwFlags: DWORD) BOOL; |
| 80 | 80 | ||
| 81 | pub extern "kernel32" stdcallcc fn PathFileExists(pszPath: ?LPCTSTR) BOOL; | ||
| 82 | |||
| 81 | pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: &c_void, | 83 | pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: &c_void, |
| 82 | in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD, | 84 | in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD, |
| 83 | in_out_lpOverlapped: ?&OVERLAPPED) BOOL; | 85 | in_out_lpOverlapped: ?&OVERLAPPED) BOOL; |