syscall, internal/syscall/unix: fix fstatat on linux/mips64

On linux/mips64, the syscall.Stat_t struct does not match the
kernel version of the struct. Functions that operate on a Stat_t
translate between it and the kernel struct.

The fstatat function was not doing this translation.
Make it do so.

Export a syscall.Fstatat on mips64 for usage by
internal/syscall/unix. Perhaps we should just do this on all
architectures, but this is the smaller change for now.

Fixes #70659

Change-Id: I38e36473689be25861953b418c9abc5b270a7bcf
Reviewed-on: https://go-review.googlesource.com/c/go/+/633280
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Damien Neil 2024-12-03 12:22:49 -08:00
parent 236a0b4ffb
commit 4ac8f552e9
5 changed files with 44 additions and 33 deletions

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build dragonfly || (linux && !loong64) || netbsd || (openbsd && mips64) //go:build dragonfly || (linux && !(loong64 || mips64)) || netbsd || (openbsd && mips64)
package unix package unix

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build freebsd || (linux && loong64) //go:build freebsd || (linux && (loong64 || mips64))
package unix package unix

View file

@ -16,7 +16,6 @@ const (
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (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) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int) //sysnb Geteuid() (euid int)
@ -126,10 +125,22 @@ type stat_t struct {
Blocks int64 Blocks int64
} }
//sys fstatatInternal(dirfd int, path string, stat *stat_t, flags int) (err error) = SYS_NEWFSTATAT
//sys fstat(fd int, st *stat_t) (err error) //sys fstat(fd int, st *stat_t) (err error)
//sys lstat(path string, st *stat_t) (err error) //sys lstat(path string, st *stat_t) (err error)
//sys stat(path string, st *stat_t) (err error) //sys stat(path string, st *stat_t) (err error)
func fstatat(fd int, path string, s *Stat_t, flags int) (err error) {
st := &stat_t{}
err = fstatatInternal(fd, path, st, flags)
fillStat_t(s, st)
return
}
func Fstatat(fd int, path string, s *Stat_t, flags int) (err error) {
return fstatat(fd, path, s, flags)
}
func Fstat(fd int, s *Stat_t) (err error) { func Fstat(fd int, s *Stat_t) (err error) {
st := &stat_t{} st := &stat_t{}
err = fstat(fd, st) err = fstat(fd, st)

View file

@ -1116,21 +1116,6 @@ func Fstatfs(fd int, buf *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Ftruncate(fd int, length int64) (err error) {
_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
if e1 != 0 { if e1 != 0 {
@ -1638,6 +1623,21 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fstatatInternal(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 fstat(fd int, st *stat_t) (err error) { func fstat(fd int, st *stat_t) (err error) {
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(st)), 0) _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(st)), 0)
if e1 != 0 { if e1 != 0 {

View file

@ -1116,21 +1116,6 @@ func Fstatfs(fd int, buf *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Ftruncate(fd int, length int64) (err error) {
_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
if e1 != 0 { if e1 != 0 {
@ -1638,6 +1623,21 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fstatatInternal(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 fstat(fd int, st *stat_t) (err error) { func fstat(fd int, st *stat_t) (err error) {
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(st)), 0) _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(st)), 0)
if e1 != 0 { if e1 != 0 {