unix: add Statvfs and Fstatvfs on NetBSD

NetBSD replaced statfs with statvfs in NetBSD 3.0. statfs is derived
from BSD4.4, while NetBSD (and Solaris) implement statvfs from POSIX
instead.

Generated and tested on NetBSD 8.0 (amd64). Also tested on NetBSD 7.0 (amd64).

Change-Id: I53738b77815d04c7774a6455b4a31cd4e9571f7b
Reviewed-on: https://go-review.googlesource.com/c/sys/+/209637
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
diff --git a/unix/mkpost.go b/unix/mkpost.go
index eb43320..5ee1a16 100644
--- a/unix/mkpost.go
+++ b/unix/mkpost.go
@@ -76,6 +76,11 @@
 	convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
 	b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
 
+	// Convert [n]int8 to [n]byte in Statvfs_t members to simplify
+	// conversion to string.
+	convertStatvfsRegex := regexp.MustCompile(`((Fstype|Mnton|Mntfrom)name)(\s+)\[(\d+)\]int8`)
+	b = convertStatvfsRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
+
 	// Convert [1024]int8 to [1024]byte in Ptmget members
 	convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
 	b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
diff --git a/unix/syscall_netbsd.go b/unix/syscall_netbsd.go
index 211131d..6135d38 100644
--- a/unix/syscall_netbsd.go
+++ b/unix/syscall_netbsd.go
@@ -249,6 +249,14 @@
 	return sendfile(outfd, infd, offset, count)
 }
 
+func Fstatvfs(fd int, buf *Statvfs_t) (err error) {
+	return Fstatvfs1(fd, buf, ST_WAIT)
+}
+
+func Statvfs(path string, buf *Statvfs_t) (err error) {
+	return Statvfs1(path, buf, ST_WAIT)
+}
+
 /*
  * Exposed directly
  */
@@ -287,6 +295,7 @@
 //sys	Fpathconf(fd int, name int) (val 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	Fstatvfs1(fd int, buf *Statvfs_t) (err error) = SYS_FSTATVFS1
 //sys	Fsync(fd int) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
 //sysnb	Getegid() (egid int)
@@ -343,6 +352,7 @@
 //sysnb	Settimeofday(tp *Timeval) (err error)
 //sysnb	Setuid(uid int) (err error)
 //sys	Stat(path string, stat *Stat_t) (err error)
+//sys	Statvfs1(path string, buf *Statvfs_t) (err error) = SYS_STATVFS1
 //sys	Symlink(path string, link string) (err error)
 //sys	Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
 //sys	Sync() (err error)
diff --git a/unix/syscall_netbsd_test.go b/unix/syscall_netbsd_test.go
index 41141f9..3292cbd 100644
--- a/unix/syscall_netbsd_test.go
+++ b/unix/syscall_netbsd_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"os"
 	"testing"
 
 	"golang.org/x/sys/unix"
@@ -49,3 +50,35 @@
 
 	t.Logf("sfd = %v, ptsname = %v", ptm.Sfd, string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]))
 }
+
+func TestStatvfs(t *testing.T) {
+	defer chtmpdir(t)()
+	touch(t, "file1")
+
+	var statvfs1, statvfs2 unix.Statvfs_t
+	err := unix.Statvfs("file1", &statvfs1)
+	if err != nil {
+		t.Fatalf("Statvfs: %v", err)
+	}
+
+	f, err := os.Open("file1")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+
+	err = unix.Fstatvfs(int(f.Fd()), &statvfs2)
+	if err != nil {
+		t.Fatalf("Fstatvfs: %v", err)
+	}
+
+	if statvfs2.Fsid != statvfs1.Fsid {
+		t.Errorf("Fstatvfs: got fsid %v, expected %v", statvfs2.Fsid, statvfs1.Fsid)
+	}
+	if statvfs2.Owner != statvfs1.Owner {
+		t.Errorf("Fstatvfs: got owner %v, expected %v", statvfs2.Owner, statvfs1.Owner)
+	}
+	if statvfs2.Fstypename != statvfs1.Fstypename {
+		t.Errorf("Fstatvfs: got fstypename %s, expected %s", statvfs2.Fstypename, statvfs1.Fstypename)
+	}
+}
diff --git a/unix/types_netbsd.go b/unix/types_netbsd.go
index 4a96d72..0a81aad 100644
--- a/unix/types_netbsd.go
+++ b/unix/types_netbsd.go
@@ -33,6 +33,7 @@
 #include <sys/signal.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/statvfs.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
 #include <sys/uio.h>
@@ -106,6 +107,8 @@
 
 type Statfs_t C.struct_statfs
 
+type Statvfs_t C.struct_statvfs
+
 type Flock_t C.struct_flock
 
 type Dirent C.struct_dirent
@@ -118,6 +121,13 @@
 	PathMax = C.PATH_MAX
 )
 
+// Fstatvfs/Statvfs flags
+
+const (
+	ST_WAIT   = C.ST_WAIT
+	ST_NOWAIT = C.ST_NOWAIT
+)
+
 // Advice to Fadvise
 
 const (
diff --git a/unix/zsyscall_netbsd_386.go b/unix/zsyscall_netbsd_386.go
index 5ade42c..0fa4c37 100644
--- a/unix/zsyscall_netbsd_386.go
+++ b/unix/zsyscall_netbsd_386.go
@@ -926,6 +926,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fstatvfs1(fd int, buf *Statvfs_t, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATVFS1, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1635,6 +1645,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statvfs1(path string, buf *Statvfs_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATVFS1, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/unix/zsyscall_netbsd_amd64.go b/unix/zsyscall_netbsd_amd64.go
index 3e0bbc5..43da753 100644
--- a/unix/zsyscall_netbsd_amd64.go
+++ b/unix/zsyscall_netbsd_amd64.go
@@ -926,6 +926,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fstatvfs1(fd int, buf *Statvfs_t, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATVFS1, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1635,6 +1645,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statvfs1(path string, buf *Statvfs_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATVFS1, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/unix/zsyscall_netbsd_arm.go b/unix/zsyscall_netbsd_arm.go
index cb0af13..b8b3404 100644
--- a/unix/zsyscall_netbsd_arm.go
+++ b/unix/zsyscall_netbsd_arm.go
@@ -926,6 +926,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fstatvfs1(fd int, buf *Statvfs_t, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATVFS1, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1635,6 +1645,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statvfs1(path string, buf *Statvfs_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATVFS1, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/unix/zsyscall_netbsd_arm64.go b/unix/zsyscall_netbsd_arm64.go
index 6fd48d3..f6243da 100644
--- a/unix/zsyscall_netbsd_arm64.go
+++ b/unix/zsyscall_netbsd_arm64.go
@@ -926,6 +926,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fstatvfs1(fd int, buf *Statvfs_t, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATVFS1, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1635,6 +1645,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statvfs1(path string, buf *Statvfs_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATVFS1, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/unix/ztypes_netbsd_386.go b/unix/ztypes_netbsd_386.go
index 86736ab..a89100c 100644
--- a/unix/ztypes_netbsd_386.go
+++ b/unix/ztypes_netbsd_386.go
@@ -78,6 +78,33 @@
 
 type Statfs_t [0]byte
 
+type Statvfs_t struct {
+	Flag        uint32
+	Bsize       uint32
+	Frsize      uint32
+	Iosize      uint32
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      uint64
+	Bresvd      uint64
+	Files       uint64
+	Ffree       uint64
+	Favail      uint64
+	Fresvd      uint64
+	Syncreads   uint64
+	Syncwrites  uint64
+	Asyncreads  uint64
+	Asyncwrites uint64
+	Fsidx       Fsid
+	Fsid        uint32
+	Namemax     uint32
+	Owner       uint32
+	Spare       [4]uint32
+	Fstypename  [32]byte
+	Mntonname   [1024]byte
+	Mntfromname [1024]byte
+}
+
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -104,6 +131,11 @@
 )
 
 const (
+	ST_WAIT   = 0x1
+	ST_NOWAIT = 0x2
+)
+
+const (
 	FADV_NORMAL     = 0x0
 	FADV_RANDOM     = 0x1
 	FADV_SEQUENTIAL = 0x2
diff --git a/unix/ztypes_netbsd_amd64.go b/unix/ztypes_netbsd_amd64.go
index 3427811..289184e 100644
--- a/unix/ztypes_netbsd_amd64.go
+++ b/unix/ztypes_netbsd_amd64.go
@@ -82,6 +82,34 @@
 
 type Statfs_t [0]byte
 
+type Statvfs_t struct {
+	Flag        uint64
+	Bsize       uint64
+	Frsize      uint64
+	Iosize      uint64
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      uint64
+	Bresvd      uint64
+	Files       uint64
+	Ffree       uint64
+	Favail      uint64
+	Fresvd      uint64
+	Syncreads   uint64
+	Syncwrites  uint64
+	Asyncreads  uint64
+	Asyncwrites uint64
+	Fsidx       Fsid
+	Fsid        uint64
+	Namemax     uint64
+	Owner       uint32
+	Spare       [4]uint32
+	Fstypename  [32]byte
+	Mntonname   [1024]byte
+	Mntfromname [1024]byte
+	_           [4]byte
+}
+
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -108,6 +136,11 @@
 )
 
 const (
+	ST_WAIT   = 0x1
+	ST_NOWAIT = 0x2
+)
+
+const (
 	FADV_NORMAL     = 0x0
 	FADV_RANDOM     = 0x1
 	FADV_SEQUENTIAL = 0x2
diff --git a/unix/ztypes_netbsd_arm.go b/unix/ztypes_netbsd_arm.go
index 399f37a..428c450 100644
--- a/unix/ztypes_netbsd_arm.go
+++ b/unix/ztypes_netbsd_arm.go
@@ -83,6 +83,33 @@
 
 type Statfs_t [0]byte
 
+type Statvfs_t struct {
+	Flag        uint32
+	Bsize       uint32
+	Frsize      uint32
+	Iosize      uint32
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      uint64
+	Bresvd      uint64
+	Files       uint64
+	Ffree       uint64
+	Favail      uint64
+	Fresvd      uint64
+	Syncreads   uint64
+	Syncwrites  uint64
+	Asyncreads  uint64
+	Asyncwrites uint64
+	Fsidx       Fsid
+	Fsid        uint32
+	Namemax     uint32
+	Owner       uint32
+	Spare       [4]uint32
+	Fstypename  [32]byte
+	Mntonname   [1024]byte
+	Mntfromname [1024]byte
+}
+
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -109,6 +136,11 @@
 )
 
 const (
+	ST_WAIT   = 0x1
+	ST_NOWAIT = 0x2
+)
+
+const (
 	FADV_NORMAL     = 0x0
 	FADV_RANDOM     = 0x1
 	FADV_SEQUENTIAL = 0x2
diff --git a/unix/ztypes_netbsd_arm64.go b/unix/ztypes_netbsd_arm64.go
index 32f0c15..6f1f284 100644
--- a/unix/ztypes_netbsd_arm64.go
+++ b/unix/ztypes_netbsd_arm64.go
@@ -82,6 +82,34 @@
 
 type Statfs_t [0]byte
 
+type Statvfs_t struct {
+	Flag        uint64
+	Bsize       uint64
+	Frsize      uint64
+	Iosize      uint64
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      uint64
+	Bresvd      uint64
+	Files       uint64
+	Ffree       uint64
+	Favail      uint64
+	Fresvd      uint64
+	Syncreads   uint64
+	Syncwrites  uint64
+	Asyncreads  uint64
+	Asyncwrites uint64
+	Fsidx       Fsid
+	Fsid        uint64
+	Namemax     uint64
+	Owner       uint32
+	Spare       [4]uint32
+	Fstypename  [32]byte
+	Mntonname   [1024]byte
+	Mntfromname [1024]byte
+	_           [4]byte
+}
+
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -108,6 +136,11 @@
 )
 
 const (
+	ST_WAIT   = 0x1
+	ST_NOWAIT = 0x2
+)
+
+const (
 	FADV_NORMAL     = 0x0
 	FADV_RANDOM     = 0x1
 	FADV_SEQUENTIAL = 0x2