| ... | @@ -294,14 +294,17 @@ pub const File = struct { | ... | @@ -294,14 +294,17 @@ pub const File = struct { |
| 294 | } | 294 | } |
| 295 | | 295 | |
| 296 | pub const Stat = struct { | 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 | 297 | /// A number that the system uses to point to the file metadata. This |
| 298 | /// unique across time, as some file systems may reuse an inode after its file has been deleted. | 298 | /// number is not guaranteed to be unique across time, as some file |
| 299 | /// Some systems may change the inode of a file over time. | 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 | /// On Linux, the inode is a structure that stores the metadata, and |
| 302 | /// you see here: the index number of the inode. | 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 | inode: INode, | 308 | inode: INode, |
| 306 | size: u64, | 309 | size: u64, |
| 307 | mode: Mode, | 310 | mode: Mode, |
| ... | @@ -314,18 +317,19 @@ pub const File = struct { | ... | @@ -314,18 +317,19 @@ pub const File = struct { |
| 314 | /// Creation time in nanoseconds, relative to UTC 1970-01-01. | 317 | /// Creation time in nanoseconds, relative to UTC 1970-01-01. |
| 315 | ctime: i128, | 318 | ctime: i128, |
| 316 | | 319 | |
| 317 | pub fn systemStatKindToFsKind(st: os.system.Stat) Kind { | 320 | pub fn fromSystem(st: os.system.Stat) Stat { |
| 318 | const kind: File.Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) | 321 | const atime = st.atime(); |
| 319 | switch (st.filetype) { | 322 | const mtime = st.mtime(); |
| 320 | .BLOCK_DEVICE => Kind.BlockDevice, | 323 | const ctime = st.ctime(); |
| 321 | .CHARACTER_DEVICE => Kind.CharacterDevice, | 324 | const kind: Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) { |
| 322 | .DIRECTORY => Kind.Directory, | 325 | .BLOCK_DEVICE => Kind.BlockDevice, |
| 323 | .SYMBOLIC_LINK => Kind.SymLink, | 326 | .CHARACTER_DEVICE => Kind.CharacterDevice, |
| 324 | .REGULAR_FILE => Kind.File, | 327 | .DIRECTORY => Kind.Directory, |
| 325 | .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket, | 328 | .SYMBOLIC_LINK => Kind.SymLink, |
| 326 | else => Kind.Unknown, | 329 | .REGULAR_FILE => Kind.File, |
| 327 | } | 330 | .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket, |
| 328 | else blk: { | 331 | else => Kind.Unknown, |
| | 332 | } else blk: { |
| 329 | const m = st.mode & os.S.IFMT; | 333 | const m = st.mode & os.S.IFMT; |
| 330 | switch (m) { | 334 | switch (m) { |
| 331 | os.S.IFBLK => break :blk Kind.BlockDevice, | 335 | os.S.IFBLK => break :blk Kind.BlockDevice, |
| ... | @@ -345,14 +349,6 @@ pub const File = struct { | ... | @@ -345,14 +349,6 @@ pub const File = struct { |
| 345 | | 349 | |
| 346 | break :blk .Unknown; | 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 | return Stat{ | 353 | return Stat{ |
| 358 | .inode = st.ino, | 354 | .inode = st.ino, |
| ... | @@ -393,47 +389,7 @@ pub const File = struct { | ... | @@ -393,47 +389,7 @@ pub const File = struct { |
| 393 | } | 389 | } |
| 394 | | 390 | |
| 395 | const st = try os.fstat(self.handle); | 391 | const st = try os.fstat(self.handle); |
| 396 | const atime = st.atime(); | 392 | return Stat.fromSystem(st); |
| 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 | }; | | |
| 437 | } | 393 | } |
| 438 | | 394 | |
| 439 | pub const ChmodError = std.os.FChmodError; | 395 | pub const ChmodError = std.os.FChmodError; |