From 7b501b22bb5837d9c30379a973b149aba89a1a60 Mon Sep 17 00:00:00 2001 From: flysand7 Date: Thu, 18 Jul 2024 22:36:39 +1100 Subject: [PATCH] [os2]: Split file type from mode bits --- core/os/os2/file.odin | 76 +++++++++++++++++++++++++++------ core/os/os2/file_linux.odin | 9 ++-- core/os/os2/file_util.odin | 2 +- core/os/os2/file_windows.odin | 11 ++--- core/os/os2/path.odin | 9 ++-- core/os/os2/path_linux.odin | 22 +++------- core/os/os2/path_windows.odin | 16 +++---- core/os/os2/stat.odin | 5 ++- core/os/os2/stat_linux.odin | 17 ++++++-- core/os/os2/stat_windows.odin | 80 ++++++++++++----------------------- core/os/os2/temp_file.odin | 2 +- core/sys/linux/bits.odin | 2 +- core/sys/linux/constants.odin | 6 +-- 13 files changed, 137 insertions(+), 120 deletions(-) diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index be03155ff..c9490044b 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -4,20 +4,57 @@ import "core:io" import "core:time" import "base:runtime" +/* + Type representing a file handle. + + This struct represents an OS-specific file-handle, which can be one of + the following: + - File + - Directory + - Pipe + - Named pipe + - Block Device + - Character device + - Symlink + - Socket + + See `File_Type` enum for more information on file types. +*/ File :: struct { impl: rawptr, stream: io.Stream, fstat: Fstat_Callback, } -File_Mode :: distinct u32 -File_Mode_Dir :: File_Mode(1<<16) -File_Mode_Named_Pipe :: File_Mode(1<<17) -File_Mode_Device :: File_Mode(1<<18) -File_Mode_Char_Device :: File_Mode(1<<19) -File_Mode_Sym_Link :: File_Mode(1<<20) +/* + Type representing the type of a file handle. -File_Mode_Perm :: File_Mode(0o777) // Unix permision bits + **Note(windows)**: Socket handles can not be distinguished from + files, as they are just a normal file handle that is being treated by + a special driver. Windows also makes no distinction between block and + character devices. +*/ +File_Type :: enum { + // The type of a file could not be determined for the current platform. + Undetermined, + // Represents a regular file. + Regular, + // Represents a directory. + Directory, + // Represents a symbolic link. + Symlink, + // Represents a named pipe (FIFO). + Named_Pipe, + // Represents a socket. + // **Note(windows)**: Not returned on windows + Socket, + // Represents a block device. + // **Note(windows)**: On windows represents all devices. + Block_Device, + // Represents a character device. + // **Note(windows)**: Not returned on windows + Character_Device, +} File_Flags :: distinct bit_set[File_Flag; uint] File_Flag :: enum { @@ -51,11 +88,11 @@ stderr: ^File = nil // OS-Specific @(require_results) create :: proc(name: string) -> (^File, Error) { - return open(name, {.Read, .Write, .Create}, File_Mode(0o777)) + return open(name, {.Read, .Write, .Create}, 0o777) } @(require_results) -open :: proc(name: string, flags := File_Flags{.Read}, perm := File_Mode(0o777)) -> (^File, Error) { +open :: proc(name: string, flags := File_Flags{.Read}, perm := 0o777) -> (^File, Error) { return _open(name, flags, perm) } @@ -161,44 +198,56 @@ read_link :: proc(name: string, allocator: runtime.Allocator) -> (string, Error) chdir :: change_directory + change_directory :: proc(name: string) -> Error { return _chdir(name) } chmod :: change_mode -change_mode :: proc(name: string, mode: File_Mode) -> Error { + +change_mode :: proc(name: string, mode: int) -> Error { return _chmod(name, mode) } + chown :: change_owner + change_owner :: proc(name: string, uid, gid: int) -> Error { return _chown(name, uid, gid) } fchdir :: fchange_directory + fchange_directory :: proc(f: ^File) -> Error { return _fchdir(f) } + fchmod :: fchange_mode -fchange_mode :: proc(f: ^File, mode: File_Mode) -> Error { + +fchange_mode :: proc(f: ^File, mode: int) -> Error { return _fchmod(f, mode) } fchown :: fchange_owner + fchange_owner :: proc(f: ^File, uid, gid: int) -> Error { return _fchown(f, uid, gid) } lchown :: change_owner_do_not_follow_links + change_owner_do_not_follow_links :: proc(name: string, uid, gid: int) -> Error { return _lchown(name, uid, gid) } chtimes :: change_times + change_times :: proc(name: string, atime, mtime: time.Time) -> Error { return _chtimes(name, atime, mtime) } + fchtimes :: fchange_times + fchange_times :: proc(f: ^File, atime, mtime: time.Time) -> Error { return _fchtimes(f, atime, mtime) } @@ -214,6 +263,7 @@ is_file :: proc(path: string) -> bool { } is_dir :: is_directory + @(require_results) is_directory :: proc(path: string) -> bool { return _is_dir(path) @@ -226,11 +276,11 @@ copy_file :: proc(dst_path, src_path: string) -> Error { info := fstat(src, file_allocator()) or_return defer file_info_delete(info, file_allocator()) - if info.is_directory { + if info.type == .Directory { return .Invalid_File } - dst := open(dst_path, {.Read, .Write, .Create, .Trunc}, info.mode & File_Mode_Perm) or_return + dst := open(dst_path, {.Read, .Write, .Create, .Trunc}, info.mode & 0o777) or_return defer close(dst) _, err := io.copy(to_writer(dst), to_reader(src)) diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 482c9b5b4..f3b55a0f7 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -63,7 +63,7 @@ _file_allocator :: proc() -> runtime.Allocator { return heap_allocator() } -_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, err: Error) { +_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return @@ -76,7 +76,6 @@ _open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, er case O_WRONLY: sys_flags += {.WRONLY} case O_RDWR: sys_flags += {.RDWR} } - if .Append in flags { sys_flags += {.APPEND} } if .Create in flags { sys_flags += {.CREAT} } if .Excl in flags { sys_flags += {.EXCL} } @@ -84,7 +83,7 @@ _open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, er if .Trunc in flags { sys_flags += {.TRUNC} } if .Close_On_Exec in flags { sys_flags += {.CLOEXEC} } - fd, errno := linux.open(name_cstr, sys_flags, transmute(linux.Mode)(u32(perm))) + fd, errno := linux.open(name_cstr, sys_flags, transmute(linux.Mode)u32(perm)) if errno != .NONE { return nil, _get_platform_error(errno) } @@ -296,13 +295,13 @@ _fchdir :: proc(f: ^File) -> Error { return _get_platform_error(linux.fchdir(impl.fd)) } -_chmod :: proc(name: string, mode: File_Mode) -> Error { +_chmod :: proc(name: string, mode: int) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return return _get_platform_error(linux.chmod(name_cstr, transmute(linux.Mode)(u32(mode)))) } -_fchmod :: proc(f: ^File, mode: File_Mode) -> Error { +_fchmod :: proc(f: ^File, mode: int) -> Error { impl := (^File_Impl)(f.impl) return _get_platform_error(linux.fchmod(impl.fd, transmute(linux.Mode)(u32(mode)))) } diff --git a/core/os/os2/file_util.odin b/core/os/os2/file_util.odin index 977979bae..ca0e8c940 100644 --- a/core/os/os2/file_util.odin +++ b/core/os/os2/file_util.odin @@ -138,7 +138,7 @@ read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (d } @(require_results) -write_entire_file :: proc(name: string, data: []byte, perm: File_Mode, truncate := true) -> Error { +write_entire_file :: proc(name: string, data: []byte, perm: int, truncate := true) -> Error { flags := O_WRONLY|O_CREATE if truncate { flags |= O_TRUNC diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index b11e7745f..a441abbaa 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -55,7 +55,7 @@ _handle :: proc(f: ^File) -> win32.HANDLE { return win32.HANDLE(_fd(f)) } -_open_internal :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (handle: uintptr, err: Error) { +_open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: uintptr, err: Error) { if len(name) == 0 { err = .Not_Exist return @@ -122,7 +122,7 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (han } -_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, err: Error) { +_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { flags := flags if flags != nil else {.Read} handle := _open_internal(name, flags, perm) or_return return _new_file(handle, name), nil @@ -498,7 +498,6 @@ _rename :: proc(old_path, new_path: string) -> Error { } - _link :: proc(old_name, new_name: string) -> Error { o := _fix_long_path(old_name) n := _fix_long_path(new_name) @@ -635,7 +634,7 @@ _fchdir :: proc(f: ^File) -> Error { return nil } -_fchmod :: proc(f: ^File, mode: File_Mode) -> Error { +_fchmod :: proc(f: ^File, mode: int) -> Error { if f == nil || f.impl == nil { return nil } @@ -670,7 +669,7 @@ _chdir :: proc(name: string) -> Error { return nil } -_chmod :: proc(name: string, mode: File_Mode) -> Error { +_chmod :: proc(name: string, mode: int) -> Error { f := open(name, {.Write}) or_return defer close(f) return _fchmod(f, mode) @@ -718,8 +717,6 @@ _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error { return nil } - - _exists :: proc(path: string) -> bool { wpath := _fix_long_path(path) attribs := win32.GetFileAttributesW(wpath) diff --git a/core/os/os2/path.odin b/core/os/os2/path.odin index 27c3d6b0b..f3c662a70 100644 --- a/core/os/os2/path.odin +++ b/core/os/os2/path.odin @@ -12,12 +12,14 @@ is_path_separator :: proc(c: byte) -> bool { } mkdir :: make_directory -make_directory :: proc(name: string, perm: File_Mode) -> Error { + +make_directory :: proc(name: string, perm: int) -> Error { return _mkdir(name, perm) } mkdir_all :: make_directory_all -make_directory_all :: proc(path: string, perm: File_Mode) -> Error { + +make_directory_all :: proc(path: string, perm: int) -> Error { return _mkdir_all(path, perm) } @@ -25,14 +27,15 @@ remove_all :: proc(path: string) -> Error { return _remove_all(path) } - getwd :: get_working_directory + @(require_results) get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { return _getwd(allocator) } setwd :: set_working_directory + set_working_directory :: proc(dir: string) -> (err: Error) { return _setwd(dir) } diff --git a/core/os/os2/path_linux.odin b/core/os/os2/path_linux.odin index 3c08eedee..80d4d42d1 100644 --- a/core/os/os2/path_linux.odin +++ b/core/os/os2/path_linux.odin @@ -15,19 +15,13 @@ _is_path_separator :: proc(c: byte) -> bool { return c == '/' } -_mkdir :: proc(path: string, perm: File_Mode) -> Error { - // TODO: These modes would require mknod, however, that would also - // require additional arguments to this function.. - if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 { - return .Invalid_Argument - } - +_mkdir :: proc(path: string, perm: int) -> Error { TEMP_ALLOCATOR_GUARD() path_cstr := temp_cstring(path) or_return - return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)(u32(perm) & 0o777))) + return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)u32(perm))) } -_mkdir_all :: proc(path: string, perm: File_Mode) -> Error { +_mkdir_all :: proc(path: string, perm: int) -> Error { mkdirat :: proc(dfd: linux.Fd, path: []u8, perm: int, has_created: ^bool) -> Error { i: int for ; i < len(path) - 1 && path[i] != '/'; i += 1 {} @@ -38,7 +32,7 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { new_dfd, errno := linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS) #partial switch errno { case .ENOENT: - if errno = linux.mkdirat(dfd, cstring(&path[0]), transmute(linux.Mode)(u32(perm))); errno != .NONE { + if errno = linux.mkdirat(dfd, cstring(&path[0]), transmute(linux.Mode)u32(perm)); errno != .NONE { return _get_platform_error(errno) } has_created^ = true @@ -58,12 +52,6 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { } unreachable() } - - // TODO - if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 { - return .Invalid_Argument - } - TEMP_ALLOCATOR_GUARD() // need something we can edit, and use to generate cstrings path_bytes := make([]u8, len(path) + 1, temp_allocator()) @@ -85,7 +73,7 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { } has_created: bool - mkdirat(dfd, path_bytes, int(perm & 0o777), &has_created) or_return + mkdirat(dfd, path_bytes, perm, &has_created) or_return if has_created { return nil } diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin index fcd1e3321..ab680cc4c 100644 --- a/core/os/os2/path_windows.odin +++ b/core/os/os2/path_windows.odin @@ -12,14 +12,14 @@ _is_path_separator :: proc(c: byte) -> bool { return c == '\\' || c == '/' } -_mkdir :: proc(name: string, perm: File_Mode) -> Error { +_mkdir :: proc(name: string, perm: int) -> Error { if !win32.CreateDirectoryW(_fix_long_path(name), nil) { return _get_platform_error() } return nil } -_mkdir_all :: proc(path: string, perm: File_Mode) -> Error { +_mkdir_all :: proc(path: string, perm: int) -> Error { fix_root_directory :: proc(p: string) -> (s: string, allocated: bool, err: runtime.Allocator_Error) { if len(p) == len(`\\?\c:`) { if is_path_separator(p[0]) && is_path_separator(p[1]) && p[2] == '?' && is_path_separator(p[3]) && p[5] == ':' { @@ -33,9 +33,9 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { TEMP_ALLOCATOR_GUARD() - dir, err := stat(path, temp_allocator()) + dir_stat, err := stat(path, temp_allocator()) if err == nil { - if dir.is_directory { + if dir_stat.type == .Directory { return nil } return .Exist @@ -61,8 +61,8 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { err = mkdir(path, perm) if err != nil { - dir1, err1 := lstat(path, temp_allocator()) - if err1 == nil && dir1.is_directory { + new_dir_stat, err1 := lstat(path, temp_allocator()) + if err1 == nil && new_dir_stat.type == .Directory { return nil } return err @@ -85,7 +85,6 @@ _setwd :: proc(dir: string) -> (err: Error) { return nil } - can_use_long_paths: bool @(init) @@ -96,7 +95,6 @@ init_long_path_support :: proc() { can_use_long_paths = false } - _fix_long_path_slice :: proc(path: string) -> []u16 { return win32.utf8_to_utf16(_fix_long_path_internal(path)) } @@ -105,7 +103,6 @@ _fix_long_path :: proc(path: string) -> win32.wstring { return win32.utf8_to_wstring(_fix_long_path_internal(path)) } - _fix_long_path_internal :: proc(path: string) -> string { if can_use_long_paths { return path @@ -162,5 +159,4 @@ _fix_long_path_internal :: proc(path: string) -> string { } return string(path_buf[:w]) - } diff --git a/core/os/os2/stat.odin b/core/os/os2/stat.odin index 1e7f9d225..fad33da0a 100644 --- a/core/os/os2/stat.odin +++ b/core/os/os2/stat.odin @@ -9,8 +9,8 @@ File_Info :: struct { fullpath: string, name: string, size: i64, - mode: File_Mode, - is_directory: bool, + mode: int, + type: File_Type, creation_time: time.Time, modification_time: time.Time, access_time: time.Time, @@ -43,6 +43,7 @@ stat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { } lstat :: stat_do_not_follow_links + @(require_results) stat_do_not_follow_links :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { return _lstat(name, allocator) diff --git a/core/os/os2/stat_linux.odin b/core/os/os2/stat_linux.odin index ee4011f96..f194524a7 100644 --- a/core/os/os2/stat_linux.odin +++ b/core/os/os2/stat_linux.odin @@ -17,20 +17,29 @@ _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (File_Inf if errno != .NONE { return {}, _get_platform_error(errno) } - + type := File_Type.Regular + switch s.mode & linux.S_IFMT { + case linux.S_IFBLK: type = .Block_Device + case linux.S_IFCHR: type = .Character_Device + case linux.S_IFDIR: type = .Directory + case linux.S_IFIFO: type = .Named_Pipe + case linux.S_IFLNK: type = .Symlink + case linux.S_IFREG: type = .Regular + case linux.S_IFSOCK: type = .Socket + } + mode := int(s.mode) & 0o7777 // TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time fi := File_Info { fullpath = _get_full_path(fd, allocator), name = "", size = i64(s.size), - mode = 0, - is_directory = linux.S_ISDIR(s.mode), + mode = mode, + type = type, modification_time = time.Time {i64(s.mtime.time_sec) * i64(time.Second) + i64(s.mtime.time_nsec)}, access_time = time.Time {i64(s.atime.time_sec) * i64(time.Second) + i64(s.atime.time_nsec)}, creation_time = time.Time{i64(s.ctime.time_sec) * i64(time.Second) + i64(s.ctime.time_nsec)}, // regular stat does not provide this } fi.creation_time = fi.modification_time - fi.name = filepath.base(fi.fullpath) return fi, nil } diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index 0a18433c1..8915d187c 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -19,28 +19,29 @@ _fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) { h := _handle(f) switch win32.GetFileType(h) { case win32.FILE_TYPE_PIPE, win32.FILE_TYPE_CHAR: - fi: File_Info - fi.fullpath = path - fi.name = basename(path) - fi.mode |= file_type_mode(h) + fi := File_Info { + fullpath = path, + name = basename(path), + type = file_type(h), + } return fi, nil } return _file_info_from_get_file_information_by_handle(path, h, allocator) } + _stat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS, allocator) } + _lstat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS|win32.FILE_FLAG_OPEN_REPARSE_POINT, allocator) } + _same_file :: proc(fi1, fi2: File_Info) -> bool { return fi1.fullpath == fi2.fullpath } - - - full_path_from_name :: proc(name: string, allocator: runtime.Allocator) -> (path: string, err: Error) { name := name if name == "" { @@ -62,7 +63,6 @@ full_path_from_name :: proc(name: string, allocator: runtime.Allocator) -> (path return win32.utf16_to_utf8(buf[:n], allocator) } - internal_stat :: proc(name: string, create_file_attributes: u32, allocator: runtime.Allocator) -> (fi: File_Info, e: Error) { if len(name) == 0 { return {}, .Not_Exist @@ -99,7 +99,6 @@ internal_stat :: proc(name: string, create_file_attributes: u32, allocator: runt return _file_info_from_get_file_information_by_handle(name, h, allocator) } - _cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 { buf := buf N := 0 @@ -120,7 +119,6 @@ _cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 { return buf } - _cleanpath_from_handle :: proc(f: ^File, allocator: runtime.Allocator) -> (string, Error) { if f == nil { return "", nil @@ -159,7 +157,6 @@ _cleanpath_from_buf :: proc(buf: []u16, allocator: runtime.Allocator) -> (string return win32.utf16_to_utf8(buf, allocator) } - basename :: proc(name: string) -> (base: string) { name := name if len(name) > 3 && name[:3] == `\\?` { @@ -185,83 +182,67 @@ basename :: proc(name: string) -> (base: string) { return name } - -file_type_mode :: proc(h: win32.HANDLE) -> File_Mode { +file_type :: proc(h: win32.HANDLE) -> File_Type { switch win32.GetFileType(h) { - case win32.FILE_TYPE_PIPE: - return File_Mode_Named_Pipe - case win32.FILE_TYPE_CHAR: - return File_Mode_Device | File_Mode_Char_Device + case win32.FILE_TYPE_PIPE: return .Named_Pipe + case win32.FILE_TYPE_CHAR: return .Character_Device + case win32.FILE_TYPE_DISK: return .Regular } - return 0 + return .Undetermined } - - -_file_mode_from_file_attributes :: proc(file_attributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (mode: File_Mode) { +_file_type_mode_from_file_attributes :: proc(file_attributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (type: File_Type, mode: int) { if file_attributes & win32.FILE_ATTRIBUTE_READONLY != 0 { mode |= 0o444 } else { mode |= 0o666 } - is_sym := false if file_attributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 { is_sym = false } else { is_sym = ReparseTag == win32.IO_REPARSE_TAG_SYMLINK || ReparseTag == win32.IO_REPARSE_TAG_MOUNT_POINT } - if is_sym { - mode |= File_Mode_Sym_Link + type = .Symlink } else { if file_attributes & win32.FILE_ATTRIBUTE_DIRECTORY != 0 { - mode |= 0o111 | File_Mode_Dir + type = .Directory + mode |= 0o111 } - if h != nil { - mode |= file_type_mode(h) + type = file_type(h) } } - return } - _file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string, allocator: runtime.Allocator) -> (fi: File_Info, e: Error) { fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) - - fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0) - fi.is_directory = fi.mode & File_Mode_Dir != 0 - + type, mode := _file_type_mode_from_file_attributes(d.dwFileAttributes, nil, 0) + fi.type = type + fi.mode |= mode fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime)) fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime)) fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime)) - fi.fullpath, e = full_path_from_name(name, allocator) fi.name = basename(fi.fullpath) - return } - _file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string, allocator: runtime.Allocator) -> (fi: File_Info, e: Error) { fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) - - fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0) - fi.is_directory = fi.mode & File_Mode_Dir != 0 - + type, mode := _file_type_mode_from_file_attributes(d.dwFileAttributes, nil, 0) + fi.type = type + fi.mode |= mode fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime)) fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime)) fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime)) - fi.fullpath, e = full_path_from_name(name, allocator) fi.name = basename(fi.fullpath) - return } - _file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE, allocator: runtime.Allocator) -> (File_Info, Error) { d: win32.BY_HANDLE_FILE_INFORMATION if !win32.GetFileInformationByHandle(h, &d) { @@ -278,25 +259,19 @@ _file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HA // Indicate this is a symlink on FAT file systems ti.ReparseTag = 0 } - fi: File_Info - fi.fullpath = path fi.name = basename(path) fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) - - fi.mode |= _file_mode_from_file_attributes(ti.FileAttributes, h, ti.ReparseTag) - fi.is_directory = fi.mode & File_Mode_Dir != 0 - + type, mode := _file_type_mode_from_file_attributes(d.dwFileAttributes, nil, 0) + fi.type = type + fi.mode |= mode fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime)) fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime)) fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime)) - return fi, nil } - - reserved_names := [?]string{ "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", @@ -357,7 +332,6 @@ _volume_name_len :: proc(path: string) -> int { return 0 } - _is_abs :: proc(path: string) -> bool { if _is_reserved_name(path) { return true diff --git a/core/os/os2/temp_file.odin b/core/os/os2/temp_file.odin index 3b3dbdd57..467775e89 100644 --- a/core/os/os2/temp_file.odin +++ b/core/os/os2/temp_file.odin @@ -26,7 +26,7 @@ create_temp_file :: proc(dir, pattern: string) -> (f: ^File, err: Error) { attempts := 0 for { name := concatenate_strings_from_buffer(name_buf[:], prefix, random_string(rand_buf[:]), suffix) - f, err = open(name, {.Read, .Write, .Create, .Excl}, File_Mode(0o666)) + f, err = open(name, {.Read, .Write, .Create, .Excl}, 0o666) if err == .Exist { close(f) attempts += 1 diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index 1e9e5bbbd..96c3de18d 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -244,7 +244,7 @@ Mode_Bits :: enum { ISVTX = 9, // 0o0001000 ISGID = 10, // 0o0002000 ISUID = 11, // 0o0004000 - IFFIFO = 12, // 0o0010000 + IFIFO = 12, // 0o0010000 IFCHR = 13, // 0o0020000 IFDIR = 14, // 0o0040000 IFREG = 15, // 0o0100000 diff --git a/core/sys/linux/constants.odin b/core/sys/linux/constants.odin index 51f7db68f..f3e9f5ff9 100644 --- a/core/sys/linux/constants.odin +++ b/core/sys/linux/constants.odin @@ -39,11 +39,11 @@ PRIO_MIN :: -20 SIGRTMIN :: Signal(32) SIGRTMAX :: Signal(64) -S_IFMT :: Mode{.IFREG, .IFDIR, .IFCHR, .IFFIFO} +S_IFMT :: Mode{.IFREG, .IFDIR, .IFCHR, .IFIFO} S_IFSOCK :: Mode{.IFREG, .IFDIR} S_IFLNK :: Mode{.IFREG, .IFCHR} S_IFBLK :: Mode{.IFDIR, .IFCHR} -S_IFFIFO :: Mode{.IFFIFO} +S_IFIFO :: Mode{.IFIFO} S_IFCHR :: Mode{.IFCHR} S_IFDIR :: Mode{.IFDIR} S_IFREG :: Mode{.IFREG} @@ -51,7 +51,7 @@ S_IFREG :: Mode{.IFREG} /* Checks the Mode bits to see if the file is a named pipe (FIFO). */ -S_ISFIFO :: #force_inline proc "contextless" (m: Mode) -> bool {return (S_IFFIFO == (m & S_IFMT))} +S_ISFIFO :: #force_inline proc "contextless" (m: Mode) -> bool {return (S_IFIFO == (m & S_IFMT))} /* Check the Mode bits to see if the file is a character device.