Skip to content

Commit c970b18

Browse files
Linux: Use the 64-bit Stat and move it up a level
Stat has been moved into the `linux` module since the fields are so similar between the architectures. Each architecture now uses the proper 64-bit stat structure, and each field has been audited to match the kernel headers. This effectively reverts #ea38009 in doing so.
1 parent a3bec0b commit c970b18

File tree

13 files changed

+343
-408
lines changed

13 files changed

+343
-408
lines changed

lib/std/os/linux.zig

Lines changed: 341 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ pub const HWCAP = arch_bits.HWCAP;
9696
pub const MMAP2_UNIT = arch_bits.MMAP2_UNIT;
9797
pub const REG = arch_bits.REG;
9898
pub const SC = arch_bits.SC;
99-
pub const Stat = arch_bits.Stat;
10099
pub const VDSO = arch_bits.VDSO;
101100
pub const blkcnt_t = arch_bits.blkcnt_t;
102101
pub const blksize_t = arch_bits.blksize_t;
@@ -470,6 +469,347 @@ pub const O = switch (native_arch) {
470469
else => @compileError("missing std.os.linux.O constants for this architecture"),
471470
};
472471

472+
// The 64-bit `stat` definition used by the Linux kernel,
473+
// which is one of the following choices:
474+
// - struct stat on 64-bit target.
475+
// - struct stat64 on a 32-bit target.
476+
// - struct stat64 on a 64-bit target.
477+
pub const Stat = switch (native_arch) {
478+
.x86 => extern struct { // stat64
479+
dev: dev_t,
480+
__pad0: [4]u8 = .{ 0, 0, 0, 0 },
481+
__ino: u32 = 0,
482+
mode: mode_t,
483+
nlink: nlink_t,
484+
uid: uid_t,
485+
gid: gid_t,
486+
rdev: dev_t,
487+
__pad3: [4]u8 = .{ 0, 0, 0, 0 },
488+
size: off_t,
489+
blksize: blksize_t,
490+
blocks: blkcnt_t,
491+
atim: u32,
492+
atim_nsec: u32,
493+
mtim: u32,
494+
mtim_nsec: u32,
495+
ctim: u32,
496+
ctim_nsec: u32,
497+
ino: ino_t,
498+
499+
pub fn atime(self: @This()) timespec {
500+
return timespec.makeTimespec(self.atim, self.atim_nsec);
501+
}
502+
503+
pub fn mtime(self: @This()) timespec {
504+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
505+
}
506+
507+
pub fn ctime(self: @This()) timespec {
508+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
509+
}
510+
},
511+
.x86_64 => extern struct { // stat
512+
dev: dev_t,
513+
ino: ino_t,
514+
nlink: nlink_t,
515+
mode: mode_t,
516+
uid: uid_t,
517+
gid: gid_t,
518+
__pad0: u32 = 0,
519+
rdev: dev_t,
520+
size: off_t,
521+
blksize: blksize_t,
522+
blocks: blkcnt_t,
523+
atim: u64,
524+
atim_nsec: u64,
525+
mtim: u64,
526+
mtim_nsec: u64,
527+
ctim: u64,
528+
ctim_nsec: u64,
529+
__unused: [3]isize = .{ 0, 0, 0 },
530+
531+
pub fn atime(self: @This()) timespec {
532+
return timespec.makeTimespec(self.atim, self.atim_nsec);
533+
}
534+
535+
pub fn mtime(self: @This()) timespec {
536+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
537+
}
538+
539+
pub fn ctime(self: @This()) timespec {
540+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
541+
}
542+
},
543+
.arm, .armeb, .thumb, .thumbeb => extern struct { // stat64
544+
dev: dev_t,
545+
__dev_padding: [4]u8 = .{ 0, 0, 0, 0 },
546+
__ino: u32 = 0,
547+
mode: mode_t,
548+
nlink: nlink_t,
549+
uid: uid_t,
550+
gid: gid_t,
551+
rdev: dev_t,
552+
__rdev_padding: [4]u8 = .{ 0, 0, 0, 0 },
553+
size: off_t,
554+
blksize: blksize_t,
555+
blocks: blkcnt_t,
556+
atim: usize,
557+
atim_nsec: usize,
558+
mtim: usize,
559+
mtim_nsec: usize,
560+
ctim: usize,
561+
ctim_nsec: usize,
562+
ino: ino_t,
563+
564+
pub fn atime(self: @This()) timespec {
565+
return timespec.makeTimespec(self.atim, self.atim_nsec);
566+
}
567+
568+
pub fn mtime(self: @This()) timespec {
569+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
570+
}
571+
572+
pub fn ctime(self: @This()) timespec {
573+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
574+
}
575+
},
576+
.sparc64 => extern struct { // stat64
577+
dev: dev_t,
578+
ino: ino_t,
579+
nlink: u64,
580+
mode: mode_t,
581+
uid: uid_t,
582+
gid: gid_t,
583+
__pad0: u32 = 0,
584+
rdev: dev_t,
585+
size: off_t,
586+
blksize: blksize_t,
587+
blocks: blkcnt_t,
588+
atim: usize,
589+
atim_nsec: usize,
590+
mtim: usize,
591+
mtim_nsec: usize,
592+
ctim: usize,
593+
ctim_nsec: usize,
594+
__unused: [3]isize = .{ 0, 0, 0 },
595+
596+
pub fn atime(self: @This()) timespec {
597+
return timespec.makeTimespec(self.atim, self.atim_nsec);
598+
}
599+
600+
pub fn mtime(self: @This()) timespec {
601+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
602+
}
603+
604+
pub fn ctime(self: @This()) timespec {
605+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
606+
}
607+
},
608+
.mips, .mipsel => extern struct { // stat64
609+
dev: usize,
610+
__pad0: [3]u32 = .{ 0, 0, 0 },
611+
ino: ino_t,
612+
mode: mode_t,
613+
nlink: nlink_t,
614+
uid: uid_t,
615+
gid: gid_t,
616+
rdev: usize,
617+
__pad1: [3]u32 = .{ 0, 0, 0 },
618+
size: off_t,
619+
atim: isize,
620+
atim_nsec: usize,
621+
mtim: isize,
622+
mtim_nsec: usize,
623+
ctim: isize,
624+
ctim_nsec: usize,
625+
blksize: blksize_t,
626+
__pad2: u32 = 0,
627+
blocks: blkcnt_t,
628+
629+
pub fn atime(self: @This()) timespec {
630+
return timespec.makeTimespec(self.atim, self.atim_nsec);
631+
}
632+
633+
pub fn mtime(self: @This()) timespec {
634+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
635+
}
636+
637+
pub fn ctime(self: @This()) timespec {
638+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
639+
}
640+
},
641+
.mips64, .mips64el => extern struct { // stat
642+
dev: u32,
643+
__pad0: [3]u32 = .{ 0, 0, 0 },
644+
ino: ino_t,
645+
mode: mode_t,
646+
nlink: nlink_t,
647+
uid: uid_t,
648+
gid: gid_t,
649+
rdev: u32,
650+
__pad1: [3]u32 = .{ 0, 0, 0 },
651+
size: off_t,
652+
atim: u32,
653+
atim_nsec: u32,
654+
mtim: u32,
655+
mtim_nsec: u32,
656+
ctim: u32,
657+
ctim_nsec: u32,
658+
blksize: blksize_t,
659+
__pad2: u32 = 0,
660+
blocks: blkcnt_t,
661+
662+
pub fn atime(self: @This()) timespec {
663+
return timespec.makeTimespec(self.atim, self.atim_nsec);
664+
}
665+
666+
pub fn mtime(self: @This()) timespec {
667+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
668+
}
669+
670+
pub fn ctime(self: @This()) timespec {
671+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
672+
}
673+
},
674+
.powerpc, .powerpcle => extern struct { // stat64
675+
dev: dev_t,
676+
ino: ino_t,
677+
mode: mode_t,
678+
nlink: nlink_t,
679+
uid: uid_t,
680+
gid: gid_t,
681+
rdev: dev_t,
682+
__pad2: u16 = 0,
683+
size: off_t,
684+
blksize: blksize_t,
685+
blocks: blkcnt_t,
686+
atim: i32,
687+
atim_nsec: u32,
688+
mtim: i32,
689+
mtim_nsec: u32,
690+
ctim: i32,
691+
ctim_nsec: u32,
692+
__unused: [2]u32 = .{ 0, 0 },
693+
694+
pub fn atime(self: @This()) timespec {
695+
return timespec.makeTimespec(self.atim, self.atim_nsec);
696+
}
697+
698+
pub fn mtime(self: @This()) timespec {
699+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
700+
}
701+
702+
pub fn ctime(self: @This()) timespec {
703+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
704+
}
705+
},
706+
.powerpc64, .powerpc64le => extern struct { // stat64
707+
dev: dev_t,
708+
ino: ino_t,
709+
mode: mode_t,
710+
nlink: nlink_t,
711+
uid: uid_t,
712+
gid: gid_t,
713+
rdev: dev_t,
714+
__pad2: u16 = 0,
715+
size: off_t,
716+
blksize: i32,
717+
blocks: blkcnt_t,
718+
atim: i32,
719+
atim_nsec: u32,
720+
mtim: i32,
721+
mtim_nsec: u32,
722+
ctim: i32,
723+
ctim_nsec: u32,
724+
__unused: [2]u32 = .{ 0, 0 },
725+
726+
pub fn atime(self: @This()) timespec {
727+
return timespec.makeTimespec(self.atim, self.atim_nsec);
728+
}
729+
730+
pub fn mtime(self: @This()) timespec {
731+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
732+
}
733+
734+
pub fn ctime(self: @This()) timespec {
735+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
736+
}
737+
},
738+
.s390x => extern struct {
739+
dev: dev_t,
740+
ino: ino_t,
741+
nlink: nlink_t,
742+
mode: mode_t,
743+
uid: uid_t,
744+
gid: gid_t,
745+
__pad1: u32 = 0,
746+
rdev: dev_t,
747+
size: off_t,
748+
atim: usize,
749+
atim_nsec: usize,
750+
mtim: usize,
751+
mtim_nsec: usize,
752+
ctim: usize,
753+
ctim_nsec: usize,
754+
blksize: blksize_t,
755+
blocks: blkcnt_t,
756+
__unused: [3]usize = .{ 0, 0, 0 },
757+
758+
pub fn atime(self: @This()) timespec {
759+
return timespec.makeTimespec(self.atim, self.atim_nsec);
760+
}
761+
762+
pub fn mtime(self: @This()) timespec {
763+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
764+
}
765+
766+
pub fn ctime(self: @This()) timespec {
767+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
768+
}
769+
},
770+
.aarch64,
771+
.aarch64_be,
772+
.riscv32,
773+
.riscv64,
774+
.loongarch64,
775+
=> extern struct { // generic stat/stat64
776+
dev: u64,
777+
ino: u64,
778+
mode: u32,
779+
nlink: u32,
780+
uid: uid_t,
781+
gid: gid_t,
782+
rdev: u64,
783+
__pad1: u64 = 0,
784+
size: i64,
785+
blksize: i32,
786+
__pad2: i32 = 0,
787+
blocks: i64,
788+
// Yes, the second fields will be 32-bit on 32-bit targets.
789+
// Presumably this is due to statx being preferred - hence newer arch's not implementing the *stat family
790+
atim: isize,
791+
atim_nsec: usize,
792+
mtim: isize,
793+
mtim_nsec: usize,
794+
ctim: isize,
795+
ctim_nsec: usize,
796+
__unused: [2]u32 = .{ 0, 0 },
797+
798+
pub fn atime(self: @This()) timespec {
799+
return timespec.makeTimespec(self.atim, self.atim_nsec);
800+
}
801+
802+
pub fn mtime(self: @This()) timespec {
803+
return timespec.makeTimespec(self.mtim, self.mtim_nsec);
804+
}
805+
806+
pub fn ctime(self: @This()) timespec {
807+
return timespec.makeTimespec(self.ctim, self.ctim_nsec);
808+
}
809+
},
810+
else => @compileError("missing std.linux.Stat definition for this architecture"),
811+
};
812+
473813
/// Set by startup code, used by `getauxval`.
474814
pub var elf_aux_maybe: ?[*]std.elf.Auxv = null;
475815

lib/std/os/linux/arm-eabi.zig

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -263,38 +263,6 @@ pub const ino_t = u64;
263263
pub const dev_t = u64;
264264
pub const blkcnt_t = i64;
265265

266-
// The `stat` definition used by the Linux kernel.
267-
pub const Stat = extern struct {
268-
dev: dev_t,
269-
__dev_padding: u32,
270-
__ino_truncated: u32,
271-
mode: mode_t,
272-
nlink: nlink_t,
273-
uid: uid_t,
274-
gid: gid_t,
275-
rdev: dev_t,
276-
__rdev_padding: u32,
277-
size: off_t,
278-
blksize: blksize_t,
279-
blocks: blkcnt_t,
280-
atim: timespec,
281-
mtim: timespec,
282-
ctim: timespec,
283-
ino: ino_t,
284-
285-
pub fn atime(self: @This()) timespec {
286-
return self.atim;
287-
}
288-
289-
pub fn mtime(self: @This()) timespec {
290-
return self.mtim;
291-
}
292-
293-
pub fn ctime(self: @This()) timespec {
294-
return self.ctim;
295-
}
296-
};
297-
298266
pub const timeval = extern struct {
299267
sec: i32,
300268
usec: i32,

0 commit comments

Comments
 (0)