github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/sys/stat.go (about) 1 package sys 2 3 import "io/fs" 4 5 // Inode is the file serial number, or zero if unknown. 6 // 7 // Any constant value will invalidate functions that use this for 8 // equivalence, such as os.SameFile (Stat_t.Ino). 9 // 10 // When zero is returned by a `readdir`, some compilers will attempt to 11 // get a non-zero value with `lstat`. Those using this for darwin's definition 12 // of `getdirentries` conflate zero `d_fileno` with a deleted file, so skip the 13 // entry. See /RATIONALE.md for more on this. 14 type Inode = uint64 15 16 // ^-- Inode is a type alias to consolidate documentation and aid in reference 17 // searches. While only Stat_t is exposed publicly at the moment, this is used 18 // internally for Dirent and several function return values. 19 20 // EpochNanos is a timestamp in epoch nanoseconds, or zero if unknown. 21 // 22 // This defines epoch time the same way as Walltime, except this value is 23 // packed into an int64. Common conversions are detailed in the examples. 24 type EpochNanos = int64 25 26 // Stat_t is similar to syscall.Stat_t, except available on all operating 27 // systems, including Windows. 28 // 29 // # Notes 30 // 31 // - This is used for WebAssembly ABI emulating the POSIX `stat` system call. 32 // Fields included are required for WebAssembly ABI including wasip1 33 // (a.k.a. wasix) and wasi-filesystem (a.k.a. wasip2). See 34 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html 35 // - Fields here are required for WebAssembly ABI including wasip1 36 // (a.k.a. wasix) and wasi-filesystem (a.k.a. wasip2). 37 // - This isn't the same as syscall.Stat_t because wazero supports Windows, 38 // which doesn't have that type. runtime.GOOS that has this already also 39 // have inconsistent field lengths, which complicates wasm binding. 40 // - Use NewStat_t to create this from an existing fs.FileInfo. 41 // - For portability, numeric fields are 64-bit when at least one platform 42 // defines it that large. 43 type Stat_t struct { 44 // Dev is the device ID of device containing the file. 45 Dev uint64 46 47 // Ino is the file serial number, or zero if not available. See Inode for 48 // more details including impact returning a zero value. 49 Ino Inode 50 51 // Mode is the same as Mode on fs.FileInfo containing bits to identify the 52 // type of the file (fs.ModeType) and its permissions (fs.ModePerm). 53 Mode fs.FileMode 54 55 // Nlink is the number of hard links to the file. 56 // 57 // Note: This value is platform-specific and often at least one. Linux will 58 // return 1+N for a directory, where BSD (like Darwin) return 2+N, which 59 // includes the dot entry. 60 Nlink uint64 61 62 // Size is the length in bytes for regular files. For symbolic links, this 63 // is length in bytes of the pathname contained in the symbolic link. 64 Size int64 65 66 // Atim is the last data access timestamp in epoch nanoseconds. 67 Atim EpochNanos 68 69 // Mtim is the last data modification timestamp in epoch nanoseconds. 70 Mtim EpochNanos 71 72 // Ctim is the last file status change timestamp in epoch nanoseconds. 73 Ctim EpochNanos 74 } 75 76 // NewStat_t fills a new Stat_t from `info`, including any runtime.GOOS-specific 77 // details from fs.FileInfo `Sys`. When `Sys` is already a *Stat_t, it is 78 // returned as-is. 79 // 80 // # Notes 81 // 82 // - When already in fs.FileInfo `Sys`, Stat_t must be a pointer. 83 // - When runtime.GOOS is "windows" Stat_t.Ino will be zero. 84 // - When fs.FileInfo `Sys` is nil or unknown, some fields not in fs.FileInfo 85 // are defaulted: Stat_t.Atim and Stat_t.Ctim are set to `ModTime`, and 86 // are set to ModTime and Stat_t.Nlink is set to 1. 87 func NewStat_t(info fs.FileInfo) Stat_t { 88 // Note: Pointer, not val, for parity with Go, which sets *syscall.Stat_t 89 if st, ok := info.Sys().(*Stat_t); ok { 90 return *st 91 } 92 return statFromFileInfo(info) 93 } 94 95 func defaultStatFromFileInfo(info fs.FileInfo) Stat_t { 96 st := Stat_t{} 97 st.Ino = 0 98 st.Dev = 0 99 st.Mode = info.Mode() 100 st.Nlink = 1 101 st.Size = info.Size() 102 mtim := info.ModTime().UnixNano() // Set all times to the mod time 103 st.Atim = mtim 104 st.Mtim = mtim 105 st.Ctim = mtim 106 return st 107 }