| ... | ... | @@ -294,14 +294,17 @@ pub const File = struct { |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | 296 | pub const Stat = struct { |
| 297 | | /// A number that the system uses to point to the file metadata. This number is not guaranteed to be |
| 298 | | /// unique across time, as some file systems may reuse an inode after its file has been deleted. |
| 299 | | /// Some systems may change the inode of a file over time. |
| 297 | /// A number that the system uses to point to the file metadata. This |
| 298 | /// number is not guaranteed to be unique across time, as some file |
| 299 | /// systems may reuse an inode after its file has been deleted. Some |
| 300 | /// systems may change the inode of a file over time. |
| 300 | 301 | /// |
| 301 | | /// On Linux, the inode is a structure that stores the metadata, and the inode _number_ is what |
| 302 | | /// you see here: the index number of the inode. |
| 302 | /// On Linux, the inode is a structure that stores the metadata, and |
| 303 | /// the inode _number_ is what you see here: the index number of the |
| 304 | /// inode. |
| 303 | 305 | /// |
| 304 | | /// The FileIndex on Windows is similar. It is a number for a file that is unique to each filesystem. |
| 306 | /// The FileIndex on Windows is similar. It is a number for a file that |
| 307 | /// is unique to each filesystem. |
| 305 | 308 | inode: INode, |
| 306 | 309 | size: u64, |
| 307 | 310 | mode: Mode, |
| ... | ... | @@ -314,18 +317,19 @@ pub const File = struct { |
| 314 | 317 | /// Creation time in nanoseconds, relative to UTC 1970-01-01. |
| 315 | 318 | ctime: i128, |
| 316 | 319 | |
| 317 | | pub fn systemStatKindToFsKind(st: os.system.Stat) Kind { |
| 318 | | const kind: File.Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) |
| 319 | | switch (st.filetype) { |
| 320 | | .BLOCK_DEVICE => Kind.BlockDevice, |
| 321 | | .CHARACTER_DEVICE => Kind.CharacterDevice, |
| 322 | | .DIRECTORY => Kind.Directory, |
| 323 | | .SYMBOLIC_LINK => Kind.SymLink, |
| 324 | | .REGULAR_FILE => Kind.File, |
| 325 | | .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket, |
| 326 | | else => Kind.Unknown, |
| 327 | | } |
| 328 | | else blk: { |
| 320 | pub fn fromSystem(st: os.system.Stat) Stat { |
| 321 | const atime = st.atime(); |
| 322 | const mtime = st.mtime(); |
| 323 | const ctime = st.ctime(); |
| 324 | const kind: Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) { |
| 325 | .BLOCK_DEVICE => Kind.BlockDevice, |
| 326 | .CHARACTER_DEVICE => Kind.CharacterDevice, |
| 327 | .DIRECTORY => Kind.Directory, |
| 328 | .SYMBOLIC_LINK => Kind.SymLink, |
| 329 | .REGULAR_FILE => Kind.File, |
| 330 | .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket, |
| 331 | else => Kind.Unknown, |
| 332 | } else blk: { |
| 329 | 333 | const m = st.mode & os.S.IFMT; |
| 330 | 334 | switch (m) { |
| 331 | 335 | os.S.IFBLK => break :blk Kind.BlockDevice, |
| ... | ... | @@ -345,14 +349,6 @@ pub const File = struct { |
| 345 | 349 | |
| 346 | 350 | break :blk .Unknown; |
| 347 | 351 | }; |
| 348 | | return kind; |
| 349 | | } |
| 350 | | |
| 351 | | pub fn fromSystemStat(st: os.system.Stat) File.StatError!Stat { |
| 352 | | const atime = st.atime(); |
| 353 | | const mtime = st.mtime(); |
| 354 | | const ctime = st.ctime(); |
| 355 | | const kind = systemStatKindToFsKind(st); |
| 356 | 352 | |
| 357 | 353 | return Stat{ |
| 358 | 354 | .inode = st.ino, |
| ... | ... | @@ -393,47 +389,7 @@ pub const File = struct { |
| 393 | 389 | } |
| 394 | 390 | |
| 395 | 391 | const st = try os.fstat(self.handle); |
| 396 | | const atime = st.atime(); |
| 397 | | const mtime = st.mtime(); |
| 398 | | const ctime = st.ctime(); |
| 399 | | const kind: Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) { |
| 400 | | .BLOCK_DEVICE => Kind.BlockDevice, |
| 401 | | .CHARACTER_DEVICE => Kind.CharacterDevice, |
| 402 | | .DIRECTORY => Kind.Directory, |
| 403 | | .SYMBOLIC_LINK => Kind.SymLink, |
| 404 | | .REGULAR_FILE => Kind.File, |
| 405 | | .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket, |
| 406 | | else => Kind.Unknown, |
| 407 | | } else blk: { |
| 408 | | const m = st.mode & os.S.IFMT; |
| 409 | | switch (m) { |
| 410 | | os.S.IFBLK => break :blk Kind.BlockDevice, |
| 411 | | os.S.IFCHR => break :blk Kind.CharacterDevice, |
| 412 | | os.S.IFDIR => break :blk Kind.Directory, |
| 413 | | os.S.IFIFO => break :blk Kind.NamedPipe, |
| 414 | | os.S.IFLNK => break :blk Kind.SymLink, |
| 415 | | os.S.IFREG => break :blk Kind.File, |
| 416 | | os.S.IFSOCK => break :blk Kind.UnixDomainSocket, |
| 417 | | else => {}, |
| 418 | | } |
| 419 | | if (builtin.os.tag == .solaris) switch (m) { |
| 420 | | os.S.IFDOOR => break :blk Kind.Door, |
| 421 | | os.S.IFPORT => break :blk Kind.EventPort, |
| 422 | | else => {}, |
| 423 | | }; |
| 424 | | |
| 425 | | break :blk .Unknown; |
| 426 | | }; |
| 427 | | |
| 428 | | return Stat{ |
| 429 | | .inode = st.ino, |
| 430 | | .size = @bitCast(u64, st.size), |
| 431 | | .mode = st.mode, |
| 432 | | .kind = kind, |
| 433 | | .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec, |
| 434 | | .mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec, |
| 435 | | .ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec, |
| 436 | | }; |
| 392 | return Stat.fromSystem(st); |
| 437 | 393 | } |
| 438 | 394 | |
| 439 | 395 | pub const ChmodError = std.os.FChmodError; |