]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: support Faccessat flags argument
authorIan Lance Taylor <iant@golang.org>
Fri, 27 Jul 2018 17:48:18 +0000 (10:48 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 27 Jul 2018 21:13:43 +0000 (21:13 +0000)
The Linux kernel faccessat system call does not take a flags parameter.
The flag parameter to the C library faccessat function is implemented in C.
The syscall.Faccessat function takes a flags parameter. In older releases
we have passed the flags parameter to the kernel, which ignored it.
In CL 120015 we started returning an error if any flags were set.
That seems clearly better than ignoring them, but it turns out that some
code was using the flags. The code was previously subtly broken.
Now it is obviously broken. That is better, but we can do better still:
we can implement the flags as the C library does. That is what this CL does.

Change-Id: I259bd6f240c3951e939b81c3032dead3d9c567b4
Reviewed-on: https://go-review.googlesource.com/126415
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
19 files changed:
src/syscall/syscall_linux.go
src/syscall/syscall_linux_386.go
src/syscall/syscall_linux_arm.go
src/syscall/syscall_linux_arm64.go
src/syscall/syscall_linux_mips64x.go
src/syscall/syscall_linux_mipsx.go
src/syscall/syscall_linux_ppc64x.go
src/syscall/syscall_linux_s390x.go
src/syscall/syscall_linux_test.go
src/syscall/zsyscall_linux_386.go
src/syscall/zsyscall_linux_arm.go
src/syscall/zsyscall_linux_arm64.go
src/syscall/zsyscall_linux_mips.go
src/syscall/zsyscall_linux_mips64.go
src/syscall/zsyscall_linux_mips64le.go
src/syscall/zsyscall_linux_mipsle.go
src/syscall/zsyscall_linux_ppc64.go
src/syscall/zsyscall_linux_ppc64le.go
src/syscall/zsyscall_linux_s390x.go

index 1a304c4966308191b9411caef1aadaa4fa59f40b..21c509f8d4c0b4dda711fdd2a44d395adec8fb7d 100644 (file)
@@ -40,10 +40,70 @@ func Creat(path string, mode uint32) (fd int, err error) {
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
        if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
                return EINVAL
-       } else if flags&(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
-               return EOPNOTSUPP
        }
-       return faccessat(dirfd, path, mode)
+
+       // The Linux kernel faccessat system call does not take any flags.
+       // The glibc faccessat implements the flags itself; see
+       // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
+       // Because people naturally expect syscall.Faccessat to act
+       // like C faccessat, we do the same.
+
+       if flags == 0 {
+               return faccessat(dirfd, path, mode)
+       }
+
+       var st Stat_t
+       if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil {
+               return err
+       }
+
+       mode &= 7
+       if mode == 0 {
+               return nil
+       }
+
+       var uid int
+       if flags&_AT_EACCESS != 0 {
+               uid = Geteuid()
+       } else {
+               uid = Getuid()
+       }
+
+       if uid == 0 {
+               if mode&1 == 0 {
+                       // Root can read and write any file.
+                       return nil
+               }
+               if st.Mode&0111 != 0 {
+                       // Root can execute any file that anybody can execute.
+                       return nil
+               }
+               return EACCES
+       }
+
+       var fmode uint32
+       if uint32(uid) == st.Uid {
+               fmode = (st.Mode >> 6) & 7
+       } else {
+               var gid int
+               if flags&_AT_EACCESS != 0 {
+                       gid = Getegid()
+               } else {
+                       gid = Getgid()
+               }
+
+               if uint32(gid) == st.Gid {
+                       fmode = (st.Mode >> 3) & 7
+               } else {
+                       fmode = st.Mode & 7
+               }
+       }
+
+       if fmode&mode == mode {
+               return nil
+       }
+
+       return EACCES
 }
 
 //sys  fchmodat(dirfd int, path string, mode uint32) (err error)
index 66152650294ade6501f1eb9b389a504e4268311b..49db72450fbb7d47d0c0e4dcd378a36d8897d775 100644 (file)
@@ -53,6 +53,7 @@ func Pipe2(p []int, flags int) (err error) {
 //sys  Dup2(oldfd int, newfd int) (err error)
 //sys  Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
 //sys  Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+//sys  fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
 //sys  Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
 //sysnb        Getegid() (egid int) = SYS_GETEGID32
 //sysnb        Geteuid() (euid int) = SYS_GETEUID32
index c8f5c8eff625bdaf9c375fbbd202a1e3919ebf71..b0c0ac7c4fae66ad79d2af7cb73f307f5d857d31 100644 (file)
@@ -77,6 +77,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
 //sys  Dup2(oldfd int, newfd int) (err error)
 //sys  Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
 //sys  Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+//sys  fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
 //sysnb        Getegid() (egid int) = SYS_GETEGID32
 //sysnb        Geteuid() (euid int) = SYS_GETEUID32
 //sysnb        Getgid() (gid int) = SYS_GETGID32
index 64210847386e5f792c979086314fcb74b048cdd5..48ad0bb292c0c1acfa03c0894559f706f34d450f 100644 (file)
@@ -13,6 +13,7 @@ const (
 //sys  Fchown(fd int, uid int, gid int) (err error)
 //sys  Fstat(fd int, stat *Stat_t) (err error)
 //sys  Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
+//sys  fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error)
 //sys  Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys  Ftruncate(fd int, length int64) (err error)
 //sysnb        Getegid() (egid int)
index 0e9018e0967e451fc4c2e0da0b3a9d94a2451084..a8e3a6907f8dc80d54590463fcba3803c6af095a 100644 (file)
@@ -15,6 +15,7 @@ const (
 //sys  Dup2(oldfd int, newfd int) (err error)
 //sys  Fchown(fd int, uid int, gid int) (err error)
 //sys  Fstatfs(fd int, buf *Statfs_t) (err error)
+//sys  fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
 //sys  Ftruncate(fd int, length int64) (err error)
 //sysnb        Getegid() (egid int)
 //sysnb        Geteuid() (euid int)
index e5ca30db54a99b91ac8d514f07dafda38080c309..a76107ffa0866f1e5273f5df4c8fa11c3f119b4e 100644 (file)
@@ -18,6 +18,7 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
 
 //sys  Dup2(oldfd int, newfd int) (err error)
 //sys  Fchown(fd int, uid int, gid int) (err error)
+//sys  fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
 //sys  Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
 //sysnb        Getegid() (egid int)
 //sysnb        Geteuid() (euid int)
index c3ba32df6fe5d56f4825dbf8d602f7ce9598f9ae..88a520e3fd6134ff6bc5932d71f03313dfb41efc 100644 (file)
@@ -15,6 +15,7 @@ const (
 //sys  Dup2(oldfd int, newfd int) (err error)
 //sys  Fchown(fd int, uid int, gid int) (err error)
 //sys  Fstat(fd int, stat *Stat_t) (err error)
+//sys  fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
 //sys  Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys  Ftruncate(fd int, length int64) (err error)
 //sysnb        Getegid() (egid int)
index 55de7b3e1331367999b2a20d2c9f698408d02198..e53b63c6a406ea8f4be2d22a699ec522a36295ce 100644 (file)
@@ -14,6 +14,7 @@ const (
 //sys  Dup2(oldfd int, newfd int) (err error)
 //sys  Fchown(fd int, uid int, gid int) (err error)
 //sys  Fstat(fd int, stat *Stat_t) (err error)
+//sys  fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
 //sys  Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys  Ftruncate(fd int, length int64) (err error)
 //sysnb        Getegid() (egid int)
index 24158bb8b88a05c96de27f652946d2d23b3189ab..99de6ebaf2fcb14645e55f865df9d4524a00eff1 100644 (file)
@@ -57,25 +57,27 @@ const (
        _AT_SYMLINK_NOFOLLOW = 0x100
        _AT_FDCWD            = -0x64
        _AT_EACCESS          = 0x200
+       _F_OK                = 0
+       _R_OK                = 4
 )
 
 func TestFaccessat(t *testing.T) {
        defer chtmpdir(t)()
        touch(t, "file1")
 
-       err := syscall.Faccessat(_AT_FDCWD, "file1", syscall.O_RDONLY, 0)
+       err := syscall.Faccessat(_AT_FDCWD, "file1", _R_OK, 0)
        if err != nil {
                t.Errorf("Faccessat: unexpected error: %v", err)
        }
 
-       err = syscall.Faccessat(_AT_FDCWD, "file1", syscall.O_RDONLY, 2)
+       err = syscall.Faccessat(_AT_FDCWD, "file1", _R_OK, 2)
        if err != syscall.EINVAL {
                t.Errorf("Faccessat: unexpected error: %v, want EINVAL", err)
        }
 
-       err = syscall.Faccessat(_AT_FDCWD, "file1", syscall.O_RDONLY, _AT_EACCESS)
-       if err != syscall.EOPNOTSUPP {
-               t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err)
+       err = syscall.Faccessat(_AT_FDCWD, "file1", _R_OK, _AT_EACCESS)
+       if err != nil {
+               t.Errorf("Faccessat: unexpected error: %v", err)
        }
 
        err = os.Symlink("file1", "symlink1")
@@ -83,9 +85,31 @@ func TestFaccessat(t *testing.T) {
                t.Fatal(err)
        }
 
-       err = syscall.Faccessat(_AT_FDCWD, "symlink1", syscall.O_RDONLY, _AT_SYMLINK_NOFOLLOW)
-       if err != syscall.EOPNOTSUPP {
-               t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err)
+       err = syscall.Faccessat(_AT_FDCWD, "symlink1", _R_OK, _AT_SYMLINK_NOFOLLOW)
+       if err != nil {
+               t.Errorf("Faccessat SYMLINK_NOFOLLOW: unexpected error %v", err)
+       }
+
+       // We can't really test _AT_SYMLINK_NOFOLLOW, because there
+       // doesn't seem to be any way to change the mode of a symlink.
+       // We don't test _AT_EACCESS because such tests are only
+       // meaningful if run as root.
+
+       err = syscall.Fchmodat(_AT_FDCWD, "file1", 0, 0)
+       if err != nil {
+               t.Errorf("Fchmodat: unexpected error %v", err)
+       }
+
+       err = syscall.Faccessat(_AT_FDCWD, "file1", _F_OK, _AT_SYMLINK_NOFOLLOW)
+       if err != nil {
+               t.Errorf("Faccessat: unexpected error: %v", err)
+       }
+
+       err = syscall.Faccessat(_AT_FDCWD, "file1", _R_OK, _AT_SYMLINK_NOFOLLOW)
+       if err != syscall.EACCES {
+               if syscall.Getuid() != 0 {
+                       t.Errorf("Faccessat: unexpected error: %v, want EACCES", err)
+               }
        }
 }
 
index ef79b3e3e24f899e429a168a4ba520b374f5b774..62827f16dc34683dde8f4ebc84f53c86183f9faa 100644 (file)
@@ -1188,6 +1188,21 @@ func Fstat(fd int, stat *Stat_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Ftruncate(fd int, length int64) (err error) {
        _, _, e1 := Syscall(SYS_FTRUNCATE64, uintptr(fd), uintptr(length), uintptr(length>>32))
        if e1 != 0 {
index 216924ff2037cacb761d796da53de5db3b8f94f8..bb20d6e9463ea4feb7717bc8edf326a3a9c11209 100644 (file)
@@ -1357,6 +1357,21 @@ func Fstat(fd int, stat *Stat_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getegid() (egid int) {
        r0, _ := rawSyscallNoError(SYS_GETEGID32, 0, 0, 0)
        egid = int(r0)
index f2dffa4bacc0e5e99e0eadc86cc3ba99a675ae49..28d7f16f70a37e73ed2ab7c2ac6ecd4f944f2e91 100644 (file)
@@ -1190,6 +1190,21 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fstatfs(fd int, buf *Statfs_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
        if e1 != 0 {
index db0f3bb65d177e346501bacd819c8ac465357e98..420c34986754535ff743408fdec54dbd9c27b75e 100644 (file)
@@ -1158,6 +1158,21 @@ func Fchown(fd int, uid int, gid int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Ftruncate(fd int, length int64) (err error) {
        _, _, e1 := Syscall6(SYS_FTRUNCATE64, uintptr(fd), 0, uintptr(length>>32), uintptr(length), 0, 0)
        if e1 != 0 {
index 4180ed1908c61ee82ada91785a4e9ef0199f2ea1..049e64eb3f8b6e6c660bfab7680d460fc2c8b4b0 100644 (file)
@@ -1168,6 +1168,21 @@ func Fstatfs(fd int, buf *Statfs_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Ftruncate(fd int, length int64) (err error) {
        _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
        if e1 != 0 {
index 3b4b5da5397012139943961ca7d520d851218768..73ff68bc7309c98e1540f03830d6e5fc05771573 100644 (file)
@@ -1168,6 +1168,21 @@ func Fstatfs(fd int, buf *Statfs_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Ftruncate(fd int, length int64) (err error) {
        _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
        if e1 != 0 {
index 7f045b77c58d20419cff5935b654118c1047d897..4b69b85c97c84b628af6cbc2167c0c354c1c71f8 100644 (file)
@@ -1158,6 +1158,21 @@ func Fchown(fd int, uid int, gid int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Ftruncate(fd int, length int64) (err error) {
        _, _, e1 := Syscall6(SYS_FTRUNCATE64, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
        if e1 != 0 {
index b76944e96cde447597226adfd69d7d090a53e89b..20c78ef2d285cabd4edce6dee7e385c3a523b500 100644 (file)
@@ -1168,6 +1168,21 @@ func Fstat(fd int, stat *Stat_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fstatfs(fd int, buf *Statfs_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
        if e1 != 0 {
index 613793b0bf310c9e9c972383f9ee1d2fbee01a6e..592934399374fd25361f634cb4e254ddce23ae56 100644 (file)
@@ -1168,6 +1168,21 @@ func Fstat(fd int, stat *Stat_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fstatfs(fd int, buf *Statfs_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
        if e1 != 0 {
index 7c63c3db5832fd93526357e76d66a486d7adf6ce..81c6d19c919d1956140aaebc56d8b2cacddcebd7 100644 (file)
@@ -1168,6 +1168,21 @@ func Fstat(fd int, stat *Stat_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fstatfs(fd int, buf *Statfs_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
        if e1 != 0 {