@@ -1944,62 +1944,90 @@ pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flag
19441944 return syscall4 (.accept4 , @as (usize , @bitCast (@as (isize , fd ))), @intFromPtr (addr ), @intFromPtr (len ), flags );
19451945}
19461946
1947- pub fn fstat (fd : i32 , stat_buf : * Stat ) usize {
1948- if (native_arch == .riscv32 ) {
1949- // riscv32 has made the interesting decision to not implement some of
1950- // the older stat syscalls, including this one.
1951- @compileError ("No fstat syscall on this architecture." );
1952- } else if (@hasField (SYS , "fstat64" )) {
1953- return syscall2 (.fstat64 , @as (usize , @bitCast (@as (isize , fd ))), @intFromPtr (stat_buf ));
1954- } else {
1955- return syscall2 (.fstat , @as (usize , @bitCast (@as (isize , fd ))), @intFromPtr (stat_buf ));
1956- }
1947+ pub fn fstat (fd : fd_t , statbuf : * Stat ) usize {
1948+ if (fd < 0 )
1949+ return @bitCast (@as (isize , - @intFromEnum (E .BADF )));
1950+ return fstatat (fd , "" , statbuf , AT .EMPTY_PATH );
19571951}
19581952
1959- pub fn stat (pathname : [* :0 ]const u8 , statbuf : * Stat ) usize {
1960- if (native_arch == .riscv32 ) {
1961- // riscv32 has made the interesting decision to not implement some of
1962- // the older stat syscalls, including this one.
1963- @compileError ("No stat syscall on this architecture." );
1964- } else if (@hasField (SYS , "stat64" )) {
1965- return syscall2 (.stat64 , @intFromPtr (pathname ), @intFromPtr (statbuf ));
1966- } else {
1967- return syscall2 (.stat , @intFromPtr (pathname ), @intFromPtr (statbuf ));
1968- }
1953+ pub fn stat (noalias pathname : [* :0 ]const u8 , noalias statbuf : * Stat ) usize {
1954+ return fstatat (AT .FDCWD , pathname , statbuf , 0 );
19691955}
19701956
1971- pub fn lstat (pathname : [* :0 ]const u8 , statbuf : * Stat ) usize {
1972- if (native_arch == .riscv32 ) {
1973- // riscv32 has made the interesting decision to not implement some of
1974- // the older stat syscalls, including this one.
1975- @compileError ("No lstat syscall on this architecture." );
1976- } else if (@hasField (SYS , "lstat64" )) {
1977- return syscall2 (.lstat64 , @intFromPtr (pathname ), @intFromPtr (statbuf ));
1978- } else {
1979- return syscall2 (.lstat , @intFromPtr (pathname ), @intFromPtr (statbuf ));
1980- }
1957+ pub fn lstat (noalias pathname : [* :0 ]const u8 , noalias statbuf : * Stat ) usize {
1958+ return fstatat (AT .FDCWD , pathname , statbuf , AT .SYMLINK_NOFOLLOW );
19811959}
19821960
1983- pub fn fstatat (dirfd : i32 , path : [* :0 ]const u8 , stat_buf : * Stat , flags : u32 ) usize {
1984- if (native_arch == .riscv32 ) {
1985- // riscv32 has made the interesting decision to not implement some of
1986- // the older stat syscalls, including this one.
1987- @compileError ("No fstatat syscall on this architecture." );
1988- } else if (@hasField (SYS , "fstatat64" )) {
1989- return syscall4 (.fstatat64 , @as (usize , @bitCast (@as (isize , dirfd ))), @intFromPtr (path ), @intFromPtr (stat_buf ), flags );
1990- } else {
1991- return syscall4 (.fstatat , @as (usize , @bitCast (@as (isize , dirfd ))), @intFromPtr (path ), @intFromPtr (stat_buf ), flags );
1992- }
1961+ pub fn fstatat (
1962+ dirfd : i32 ,
1963+ noalias pathname : [* :0 ]const u8 ,
1964+ noalias statbuf : * Stat ,
1965+ flags : u32 ,
1966+ ) usize {
1967+ var stx : Statx = undefined ;
1968+ const rc = statx (dirfd , pathname , flags | AT .NO_AUTOMOUNT , 0x7ff , & stx );
1969+ if (rc != 0 ) return rc ;
1970+ statbuf .* = .{
1971+ .dev = makedev (stx .dev_major , stx .dev_minor ),
1972+ .ino = stx .ino ,
1973+ .mode = stx .mode ,
1974+ .nlink = stx .nlink ,
1975+ .uid = stx .uid ,
1976+ .gid = stx .gid ,
1977+ .rdev = makedev (stx .rdev_major , stx .rdev_minor ),
1978+ .size = stx .size ,
1979+ .blksize = stx .blksize ,
1980+ .blocks = stx .blocks ,
1981+ .atim = .{
1982+ .sec = stx .atime .sec ,
1983+ .nsec = stx .atime .nsec ,
1984+ },
1985+ .mtim = .{
1986+ .sec = stx .atime .sec ,
1987+ .nsec = stx .atime .nsec ,
1988+ },
1989+ .ctim = .{
1990+ .sec = stx .atime .sec ,
1991+ .nsec = stx .atime .nsec ,
1992+ },
1993+ };
1994+ return 0 ;
1995+ }
1996+
1997+ /// Returns the major number from a device number.
1998+ pub fn major (dev : dev_t ) u32 {
1999+ return ((dev >> 8 ) & 0xfff ) | ((dev >> 32 ) & ~ 0xfff );
19932000}
19942001
1995- pub fn statx (dirfd : i32 , path : [* :0 ]const u8 , flags : u32 , mask : u32 , statx_buf : * Statx ) usize {
2002+ /// Returns the minor number from a device number
2003+ pub fn minor (dev : dev_t ) u32 {
2004+ return (dev & 0xff ) | ((dev >> 12 ) & ~ 0xff );
2005+ }
2006+
2007+ /// Create a device number from a major/minor pair.
2008+ fn makedev (x : u32 , y : u32 ) dev_t {
2009+ const xx : u64 = x ;
2010+ const yy : u64 = y ;
2011+ return ((yy & 0xff ) << 0 ) |
2012+ ((xx & 0xfff ) << 8 ) |
2013+ ((yy & ~ 0xff ) << 12 ) |
2014+ ((xx & ~ 0xfff ) << 32 );
2015+ }
2016+
2017+ pub fn statx (
2018+ dirfd : i32 ,
2019+ noalias path : [* :0 ]const u8 ,
2020+ flags : u32 ,
2021+ mask : u32 ,
2022+ noalias buf : * Statx ,
2023+ ) usize {
19962024 return syscall5 (
19972025 .statx ,
19982026 @as (usize , @bitCast (@as (isize , dirfd ))),
19992027 @intFromPtr (path ),
20002028 flags ,
20012029 mask ,
2002- @intFromPtr (statx_buf ),
2030+ @intFromPtr (buf ),
20032031 );
20042032}
20052033
0 commit comments