@@ -294,14 +294,17 @@ pub const File = struct {
294294 }
295295
296296 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.
300301 ///
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.
303305 ///
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.
305308 inode : INode ,
306309 size : u64 ,
307310 mode : Mode ,
@@ -313,6 +316,50 @@ pub const File = struct {
313316 mtime : i128 ,
314317 /// Creation time in nanoseconds, relative to UTC 1970-01-01.
315318 ctime : i128 ,
319+
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 : {
333+ const m = st .mode & os .S .IFMT ;
334+ switch (m ) {
335+ os .S .IFBLK = > break :blk Kind .BlockDevice ,
336+ os .S .IFCHR = > break :blk Kind .CharacterDevice ,
337+ os .S .IFDIR = > break :blk Kind .Directory ,
338+ os .S .IFIFO = > break :blk Kind .NamedPipe ,
339+ os .S .IFLNK = > break :blk Kind .SymLink ,
340+ os .S .IFREG = > break :blk Kind .File ,
341+ os .S .IFSOCK = > break :blk Kind .UnixDomainSocket ,
342+ else = > {},
343+ }
344+ if (builtin .os .tag == .solaris ) switch (m ) {
345+ os .S .IFDOOR = > break :blk Kind .Door ,
346+ os .S .IFPORT = > break :blk Kind .EventPort ,
347+ else = > {},
348+ };
349+
350+ break :blk .Unknown ;
351+ };
352+
353+ return Stat {
354+ .inode = st .ino ,
355+ .size = @bitCast (u64 , st .size ),
356+ .mode = st .mode ,
357+ .kind = kind ,
358+ .atime = @as (i128 , atime .tv_sec ) * std .time .ns_per_s + atime .tv_nsec ,
359+ .mtime = @as (i128 , mtime .tv_sec ) * std .time .ns_per_s + mtime .tv_nsec ,
360+ .ctime = @as (i128 , ctime .tv_sec ) * std .time .ns_per_s + ctime .tv_nsec ,
361+ };
362+ }
316363 };
317364
318365 pub const StatError = os .FStatError ;
@@ -342,47 +389,7 @@ pub const File = struct {
342389 }
343390
344391 const st = try os .fstat (self .handle );
345- const atime = st .atime ();
346- const mtime = st .mtime ();
347- const ctime = st .ctime ();
348- const kind : Kind = if (builtin .os .tag == .wasi and ! builtin .link_libc ) switch (st .filetype ) {
349- .BLOCK_DEVICE = > Kind .BlockDevice ,
350- .CHARACTER_DEVICE = > Kind .CharacterDevice ,
351- .DIRECTORY = > Kind .Directory ,
352- .SYMBOLIC_LINK = > Kind .SymLink ,
353- .REGULAR_FILE = > Kind .File ,
354- .SOCKET_STREAM , .SOCKET_DGRAM = > Kind .UnixDomainSocket ,
355- else = > Kind .Unknown ,
356- } else blk : {
357- const m = st .mode & os .S .IFMT ;
358- switch (m ) {
359- os .S .IFBLK = > break :blk Kind .BlockDevice ,
360- os .S .IFCHR = > break :blk Kind .CharacterDevice ,
361- os .S .IFDIR = > break :blk Kind .Directory ,
362- os .S .IFIFO = > break :blk Kind .NamedPipe ,
363- os .S .IFLNK = > break :blk Kind .SymLink ,
364- os .S .IFREG = > break :blk Kind .File ,
365- os .S .IFSOCK = > break :blk Kind .UnixDomainSocket ,
366- else = > {},
367- }
368- if (builtin .os .tag == .solaris ) switch (m ) {
369- os .S .IFDOOR = > break :blk Kind .Door ,
370- os .S .IFPORT = > break :blk Kind .EventPort ,
371- else = > {},
372- };
373-
374- break :blk .Unknown ;
375- };
376-
377- return Stat {
378- .inode = st .ino ,
379- .size = @bitCast (u64 , st .size ),
380- .mode = st .mode ,
381- .kind = kind ,
382- .atime = @as (i128 , atime .tv_sec ) * std .time .ns_per_s + atime .tv_nsec ,
383- .mtime = @as (i128 , mtime .tv_sec ) * std .time .ns_per_s + mtime .tv_nsec ,
384- .ctime = @as (i128 , ctime .tv_sec ) * std .time .ns_per_s + ctime .tv_nsec ,
385- };
392+ return Stat .fromSystem (st );
386393 }
387394
388395 pub const ChmodError = std .os .FChmodError ;
0 commit comments