From af09f7315aff1cbc48fb21d21aa55d67b4f914c5 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Sep 2020 12:13:43 +0200 Subject: [PATCH] unix: add FcntlFstore on darwin This allows to perform a fcntl syscall with the F_PREALLOCATE command. See man fcntl(2) on macOS for details. Change-Id: I21f95b91269513064859425ab7adc42a73d6adb5 Reviewed-on: https://go-review.googlesource.com/c/sys/+/255917 Trust: Tobias Klauser Run-TryBot: Tobias Klauser TryBot-Result: Go Bot Reviewed-by: Ian Lance Taylor --- unix/fcntl_darwin.go | 6 ++++++ unix/syscall_darwin_test.go | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/unix/fcntl_darwin.go b/unix/fcntl_darwin.go index 5868a4a4..a9911c7c 100644 --- a/unix/fcntl_darwin.go +++ b/unix/fcntl_darwin.go @@ -16,3 +16,9 @@ func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { _, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk)))) return err } + +// FcntlFstore performs a fcntl syscall for the F_PREALLOCATE command. +func FcntlFstore(fd uintptr, cmd int, fstore *Fstore_t) error { + _, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(fstore)))) + return err +} diff --git a/unix/syscall_darwin_test.go b/unix/syscall_darwin_test.go index e7f6bdde..d9f10139 100644 --- a/unix/syscall_darwin_test.go +++ b/unix/syscall_darwin_test.go @@ -31,7 +31,7 @@ func stringsFromByteSlice(buf []byte) []string { } func createTestFile(t *testing.T, dir string) (f *os.File, cleanup func() error) { - file, err := ioutil.TempFile(dir, "TestClonefile") + file, err := ioutil.TempFile(dir, t.Name()) if err != nil { t.Fatal(err) } @@ -185,3 +185,35 @@ func TestFclonefileat(t *testing.T) { t.Errorf("Fclonefileat: got %q, expected %q", clonedData, testData) } } + +func TestFcntlFstore(t *testing.T) { + f, err := ioutil.TempFile("", t.Name()) + if err != nil { + t.Fatal(err) + } + defer os.Remove(f.Name()) + defer f.Close() + + fstore := &unix.Fstore_t{ + Flags: unix.F_ALLOCATEALL, + Posmode: unix.F_PEOFPOSMODE, + Offset: 0, + Length: 1 << 10, + } + err = unix.FcntlFstore(f.Fd(), unix.F_PREALLOCATE, fstore) + if err == unix.EOPNOTSUPP { + t.Skipf("fcntl with F_PREALLOCATE not supported, skipping test") + } else if err != nil { + t.Fatalf("FcntlFstore: %v", err) + } + + st, err := f.Stat() + if err != nil { + t.Fatal(err) + } + + if st.Size() != 0 { + t.Errorf("FcntlFstore: got size = %d, want %d", st.Size(), 0) + } + +}