github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/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  }