Bladeren bron

unix: remove StTimespec type on AIX

On AIX, Stat_t's fields dealing with time are of type StTimespec while
all other GOOS are using Timespec.
StTimespec and Timespec are the same on ppc but not in ppc64. Therefore,
values returned by ppc64 syscalls need to be adjusted in order to
allow the use of Timespec instead of StTimespec.

Fixes golang/go#32073

Change-Id: I0c212bf1741a27c49e995bf928d4941b6d583e54
Reviewed-on: https://go-review.googlesource.com/c/sys/+/177838
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Clément Chigot 6 jaren geleden
bovenliggende
commit
ad400b1274

+ 7 - 0
unix/mkpost.go

@@ -42,6 +42,13 @@ func main() {
 		log.Fatal(err)
 	}
 
+	if goos == "aix" {
+		// Replace type of Atim, Mtim and Ctim by Timespec in Stat_t
+		// to avoid having both StTimespec and Timespec.
+		sttimespec := regexp.MustCompile(`_Ctype_struct_st_timespec`)
+		b = sttimespec.ReplaceAll(b, []byte("Timespec"))
+	}
+
 	// Intentionally export __val fields in Fsid and Sigset_t
 	valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`)
 	b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}"))

+ 4 - 4
unix/syscall_aix.go

@@ -454,8 +454,8 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 //sys	Dup2(oldfd int, newfd int) (err error)
 //sys	Fadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64
 //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) = fstatat
+//sys	fstat(fd int, stat *Stat_t) (err error)
+//sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat
 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
 //sysnb	Getegid() (egid int)
@@ -464,7 +464,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 //sysnb	Getuid() (uid int)
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Listen(s int, n int) (err error)
-//sys	Lstat(path string, stat *Stat_t) (err error)
+//sys	lstat(path string, stat *Stat_t) (err error)
 //sys	Pause() (err error)
 //sys	Pread(fd int, p []byte, offset int64) (n int, err error) = pread64
 //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
@@ -474,7 +474,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 //sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
-//sys	Stat(path string, stat *Stat_t) (err error)
+//sys	stat(path string, statptr *Stat_t) (err error)
 //sys	Statfs(path string, buf *Statfs_t) (err error)
 //sys	Truncate(path string, length int64) (err error)
 

+ 16 - 0
unix/syscall_aix_ppc.go

@@ -32,3 +32,19 @@ func (msghdr *Msghdr) SetControllen(length int) {
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint32(length)
 }
+
+func Fstat(fd int, stat *Stat_t) error {
+	return fstat(fd, stat)
+}
+
+func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {
+	return fstatat(dirfd, path, stat, flags)
+}
+
+func Lstat(path string, stat *Stat_t) error {
+	return lstat(path, stat)
+}
+
+func Stat(path string, statptr *Stat_t) error {
+	return stat(path, statptr)
+}

+ 47 - 0
unix/syscall_aix_ppc64.go

@@ -32,3 +32,50 @@ func (msghdr *Msghdr) SetControllen(length int) {
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint32(length)
 }
+
+// In order to only have Timespec structure, type of Stat_t's fields
+// Atim, Mtim and Ctim is changed from StTimespec to Timespec during
+// ztypes generation.
+// On ppc64, Timespec.Nsec is an int64 while StTimespec.Nsec is an
+// int32, so the fields' value must be modified.
+func fixStatTimFields(stat *Stat_t) {
+	stat.Atim.Nsec >>= 32
+	stat.Mtim.Nsec >>= 32
+	stat.Ctim.Nsec >>= 32
+}
+
+func Fstat(fd int, stat *Stat_t) error {
+	err := fstat(fd, stat)
+	if err != nil {
+		return err
+	}
+	fixStatTimFields(stat)
+	return nil
+}
+
+func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {
+	err := fstatat(dirfd, path, stat, flags)
+	if err != nil {
+		return err
+	}
+	fixStatTimFields(stat)
+	return nil
+}
+
+func Lstat(path string, stat *Stat_t) error {
+	err := lstat(path, stat)
+	if err != nil {
+		return err
+	}
+	fixStatTimFields(stat)
+	return nil
+}
+
+func Stat(path string, statptr *Stat_t) error {
+	err := stat(path, statptr)
+	if err != nil {
+		return err
+	}
+	fixStatTimFields(statptr)
+	return nil
+}

+ 2 - 2
unix/syscall_aix_test.go

@@ -107,10 +107,10 @@ func TestUtimesNanoAt(t *testing.T) {
 		t.Fatalf("Lstat: %v", err)
 	}
 	if runtime.GOARCH == "ppc64" {
-		if int64(st.Atim.Sec) != int64(ts[0].Sec) || st.Atim.Nsec != int32(ts[0].Nsec) {
+		if int64(st.Atim.Sec) != int64(ts[0].Sec) || st.Atim.Nsec != ts[0].Nsec {
 			t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
 		}
-		if int64(st.Mtim.Sec) != int64(ts[1].Sec) || st.Mtim.Nsec != int32(ts[1].Nsec) {
+		if int64(st.Mtim.Sec) != int64(ts[1].Sec) || st.Mtim.Nsec != ts[1].Nsec {
 			t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
 		}
 	} else {

+ 1 - 1
unix/syscall_test.go

@@ -62,7 +62,7 @@ func TestUname(t *testing.T) {
 // Test that this compiles. (Issue #31735)
 func TestStatFieldNames(t *testing.T) {
 	var st unix.Stat_t
-	var ts interface{} // either *unix.Timespec or *unix.StTimespec on GOOS==aix
+	var ts *unix.Timespec
 	ts = &st.Atim
 	ts = &st.Mtim
 	ts = &st.Ctim

+ 0 - 2
unix/types_aix.go

@@ -87,8 +87,6 @@ type Mode_t C.mode_t
 
 type Timespec C.struct_timespec
 
-type StTimespec C.struct_st_timespec
-
 type Timeval C.struct_timeval
 
 type Timeval32 C.struct_timeval32

+ 5 - 5
unix/zsyscall_aix_ppc.go

@@ -859,7 +859,7 @@ func Fchown(fd int, uid int, gid int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fstat(fd int, stat *Stat_t) (err error) {
+func fstat(fd int, stat *Stat_t) (err error) {
 	r0, er := C.fstat(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
 	if r0 == -1 && er != nil {
 		err = er
@@ -869,7 +869,7 @@ 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) {
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
 	_p0 := uintptr(unsafe.Pointer(C.CString(path)))
 	r0, er := C.fstatat(C.int(dirfd), C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))), C.int(flags))
 	if r0 == -1 && er != nil {
@@ -953,7 +953,7 @@ func Listen(s int, n int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Lstat(path string, stat *Stat_t) (err error) {
+func lstat(path string, stat *Stat_t) (err error) {
 	_p0 := uintptr(unsafe.Pointer(C.CString(path)))
 	r0, er := C.lstat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
 	if r0 == -1 && er != nil {
@@ -1071,9 +1071,9 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Stat(path string, stat *Stat_t) (err error) {
+func stat(path string, statptr *Stat_t) (err error) {
 	_p0 := uintptr(unsafe.Pointer(C.CString(path)))
-	r0, er := C.stat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
+	r0, er := C.stat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(statptr))))
 	if r0 == -1 && er != nil {
 		err = er
 	}

+ 5 - 5
unix/zsyscall_aix_ppc64.go

@@ -803,7 +803,7 @@ func Fchown(fd int, uid int, gid int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fstat(fd int, stat *Stat_t) (err error) {
+func fstat(fd int, stat *Stat_t) (err error) {
 	_, e1 := callfstat(fd, uintptr(unsafe.Pointer(stat)))
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -813,7 +813,7 @@ 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) {
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -905,7 +905,7 @@ func Listen(s int, n int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Lstat(path string, stat *Stat_t) (err error) {
+func lstat(path string, stat *Stat_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1023,13 +1023,13 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Stat(path string, stat *Stat_t) (err error) {
+func stat(path string, statptr *Stat_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, e1 := callstat(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)))
+	_, e1 := callstat(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(statptr)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}

+ 2 - 2
unix/zsyscall_aix_ppc64_gc.go

@@ -941,8 +941,8 @@ func callsplice(rfd int, roff uintptr, wfd int, woff uintptr, len int, flags int
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func callstat(_p0 uintptr, stat uintptr) (r1 uintptr, e1 Errno) {
-	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_stat)), 2, _p0, stat, 0, 0, 0, 0)
+func callstat(_p0 uintptr, statptr uintptr) (r1 uintptr, e1 Errno) {
+	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_stat)), 2, _p0, statptr, 0, 0, 0, 0)
 	return
 }
 

+ 2 - 2
unix/zsyscall_aix_ppc64_gccgo.go

@@ -783,8 +783,8 @@ func callsplice(rfd int, roff uintptr, wfd int, woff uintptr, len int, flags int
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func callstat(_p0 uintptr, stat uintptr) (r1 uintptr, e1 Errno) {
-	r1 = uintptr(C.stat(C.uintptr_t(_p0), C.uintptr_t(stat)))
+func callstat(_p0 uintptr, statptr uintptr) (r1 uintptr, e1 Errno) {
+	r1 = uintptr(C.stat(C.uintptr_t(_p0), C.uintptr_t(statptr)))
 	e1 = syscall.GetErrno()
 	return
 }

+ 3 - 8
unix/ztypes_aix_ppc.go

@@ -30,11 +30,6 @@ type Timespec struct {
 	Nsec int32
 }
 
-type StTimespec struct {
-	Sec  int32
-	Nsec int32
-}
-
 type Timeval struct {
 	Sec  int32
 	Usec int32
@@ -101,9 +96,9 @@ type Stat_t struct {
 	Gid      uint32
 	Rdev     uint32
 	Size     int32
-	Atim     StTimespec
-	Mtim     StTimespec
-	Ctim     StTimespec
+	Atim     Timespec
+	Mtim     Timespec
+	Ctim     Timespec
 	Blksize  int32
 	Blocks   int32
 	Vfstype  int32

+ 3 - 9
unix/ztypes_aix_ppc64.go

@@ -30,12 +30,6 @@ type Timespec struct {
 	Nsec int64
 }
 
-type StTimespec struct {
-	Sec  int64
-	Nsec int32
-	_    [4]byte
-}
-
 type Timeval struct {
 	Sec  int64
 	Usec int32
@@ -103,9 +97,9 @@ type Stat_t struct {
 	Gid      uint32
 	Rdev     uint64
 	Ssize    int32
-	Atim     StTimespec
-	Mtim     StTimespec
-	Ctim     StTimespec
+	Atim     Timespec
+	Mtim     Timespec
+	Ctim     Timespec
 	Blksize  int64
 	Blocks   int64
 	Vfstype  int32