diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-04-13 11:16:06 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-13 11:16:06 -0400 |
| commit | 30c5f3c441e6090f29c0540b1fa8a20d6bd2fc0d (patch) | |
| tree | 420a68427efe9c2e3f95f50f3f56ebc9ca7aa14d /std | |
| parent | 1999f0daad505f414f97845ecde0a56b3c2fedfd (diff) | |
| parent | fe9489ad63ea8231bb0366d7608e52d0d30bfefb (diff) | |
| download | zig-30c5f3c441e6090f29c0540b1fa8a20d6bd2fc0d.tar.gz zig-30c5f3c441e6090f29c0540b1fa8a20d6bd2fc0d.zip | |
Merge pull request #915 from zig-lang/self-hosted-cli
Revise self-hosted command line interface
Diffstat (limited to 'std')
| -rw-r--r-- | std/c/index.zig | 1 | ||||
| -rw-r--r-- | std/os/darwin.zig | 9 | ||||
| -rw-r--r-- | std/os/file.zig | 45 | ||||
| -rw-r--r-- | std/os/linux/index.zig | 9 | ||||
| -rw-r--r-- | std/os/test.zig | 17 | ||||
| -rw-r--r-- | std/os/windows/index.zig | 2 |
6 files changed, 82 insertions, 1 deletions
diff --git a/std/c/index.zig b/std/c/index.zig index 369ea2b358..02321f1f34 100644 --- a/std/c/index.zig +++ b/std/c/index.zig @@ -28,6 +28,7 @@ pub extern "c" fn unlink(path: &const u8) c_int; pub extern "c" fn getcwd(buf: &u8, size: usize) ?&u8; pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) c_int; pub extern "c" fn fork() c_int; +pub extern "c" fn access(path: &const u8, mode: c_uint) c_int; pub extern "c" fn pipe(fds: &c_int) c_int; pub extern "c" fn mkdir(path: &const u8, mode: c_uint) c_int; pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int; diff --git a/std/os/darwin.zig b/std/os/darwin.zig index 40da55315c..42b9917210 100644 --- a/std/os/darwin.zig +++ b/std/os/darwin.zig @@ -41,6 +41,11 @@ pub const SA_64REGSET = 0x0200; /// signal handler with SA_SIGINFO args with 64 pub const O_LARGEFILE = 0x0000; pub const O_PATH = 0x0000; +pub const F_OK = 0; +pub const X_OK = 1; +pub const W_OK = 2; +pub const R_OK = 4; + pub const O_RDONLY = 0x0000; /// open for reading only pub const O_WRONLY = 0x0001; /// open for writing only pub const O_RDWR = 0x0002; /// open for reading and writing @@ -209,6 +214,10 @@ pub fn fork() usize { return errnoWrap(c.fork()); } +pub fn access(path: &const u8, mode: u32) usize { + return errnoWrap(c.access(path, mode)); +} + pub fn pipe(fds: &[2]i32) usize { comptime assert(i32.bit_count == c_int.bit_count); return errnoWrap(c.pipe(@ptrCast(&c_int, fds))); diff --git a/std/os/file.zig b/std/os/file.zig index eed3a443b9..61fc2b1455 100644 --- a/std/os/file.zig +++ b/std/os/file.zig @@ -85,6 +85,47 @@ pub const File = struct { }; } + pub fn access(allocator: &mem.Allocator, path: []const u8, file_mode: os.FileMode) !bool { + const path_with_null = try std.cstr.addNullByte(allocator, path); + defer allocator.free(path_with_null); + + if (is_posix) { + // mode is ignored and is always F_OK for now + const result = posix.access(path_with_null.ptr, posix.F_OK); + const err = posix.getErrno(result); + if (err > 0) { + return switch (err) { + posix.EACCES => error.PermissionDenied, + posix.EROFS => error.PermissionDenied, + posix.ELOOP => error.PermissionDenied, + posix.ETXTBSY => error.PermissionDenied, + posix.ENOTDIR => error.NotFound, + posix.ENOENT => error.NotFound, + + posix.ENAMETOOLONG => error.NameTooLong, + posix.EINVAL => error.BadMode, + posix.EFAULT => error.BadPathName, + posix.EIO => error.Io, + posix.ENOMEM => error.SystemResources, + else => os.unexpectedErrorPosix(err), + }; + } + return true; + } else if (is_windows) { + if (os.windows.PathFileExists(path_with_null.ptr) == os.windows.TRUE) { + return true; + } + + const err = windows.GetLastError(); + return switch (err) { + windows.ERROR.FILE_NOT_FOUND => error.NotFound, + windows.ERROR.ACCESS_DENIED => error.PermissionDenied, + else => os.unexpectedErrorWindows(err), + }; + } else { + @compileError("TODO implement access for this OS"); + } + } /// Upon success, the stream is in an uninitialized state. To continue using it, /// you must use the open() function. @@ -245,7 +286,9 @@ pub const File = struct { }; } - return stat.mode; + // TODO: we should be able to cast u16 to ModeError!u32, making this + // explicit cast not necessary + return os.FileMode(stat.mode); } else if (is_windows) { return {}; } else { diff --git a/std/os/linux/index.zig b/std/os/linux/index.zig index aa2a6d85da..e100af7733 100644 --- a/std/os/linux/index.zig +++ b/std/os/linux/index.zig @@ -38,6 +38,11 @@ pub const MAP_STACK = 0x20000; pub const MAP_HUGETLB = 0x40000; pub const MAP_FILE = 0; +pub const F_OK = 0; +pub const X_OK = 1; +pub const W_OK = 2; +pub const R_OK = 4; + pub const WNOHANG = 1; pub const WUNTRACED = 2; pub const WSTOPPED = 2; @@ -705,6 +710,10 @@ pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) usize { return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset); } +pub fn access(path: &const u8, mode: u32) usize { + return syscall2(SYS_access, @ptrToInt(path), mode); +} + pub fn pipe(fd: &[2]i32) usize { return pipe2(fd, 0); } diff --git a/std/os/test.zig b/std/os/test.zig index 9c718d5b6b..718d1ce2c8 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -23,3 +23,20 @@ test "makePath, put some files in it, deleteTree" { assert(err == error.PathNotFound); } } + +test "access file" { + if (builtin.os == builtin.Os.windows) { + return; + } + + try os.makePath(a, "os_test_tmp"); + if (os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) |ok| { + unreachable; + } else |err| { + assert(err == error.NotFound); + } + + try io.writeFile(a, "os_test_tmp/file.txt", ""); + assert((try os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) == true); + try os.deleteTree(a, "os_test_tmp"); +} diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig index 2709cf2a78..aa02c27f39 100644 --- a/std/os/windows/index.zig +++ b/std/os/windows/index.zig @@ -78,6 +78,8 @@ pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, dwFlags: DWORD) BOOL; +pub extern "kernel32" stdcallcc fn PathFileExists(pszPath: ?LPCTSTR) BOOL; + pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: &c_void, in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD, in_out_lpOverlapped: ?&OVERLAPPED) BOOL; |
