| // Copyright 2020 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| //go:build zos && s390x |
| // +build zos,s390x |
| |
| // This test is based on mmap_unix_test, but tweaked for z/OS, which does not support memadvise |
| // or anonymous mmapping. |
| |
| package unix_test |
| |
| import ( |
| "fmt" |
| "io/ioutil" |
| "os" |
| "path/filepath" |
| "testing" |
| |
| "golang.org/x/sys/unix" |
| ) |
| |
| func TestMmap(t *testing.T) { |
| tmpdir := mktmpdir(t) |
| filename := filepath.Join(filepath.Join(tmpdir, "testdata"), "memmapped_file") |
| destination, err := os.Create(filename) |
| if err != nil { |
| t.Fatal("os.Create:", err) |
| return |
| } |
| defer os.RemoveAll(tmpdir) |
| |
| fmt.Fprintf(destination, "%s\n", "0 <- Flipped between 0 and 1 when test runs successfully") |
| fmt.Fprintf(destination, "%s\n", "//Do not change contents - mmap test relies on this") |
| destination.Close() |
| fd, err := unix.Open(filename, unix.O_RDWR, 0777) |
| if err != nil { |
| t.Fatalf("Open: %v", err) |
| } |
| |
| b, err := unix.Mmap(fd, 0, 8, unix.PROT_READ, unix.MAP_SHARED) |
| if err != nil { |
| t.Fatalf("Mmap: %v", err) |
| } |
| |
| if err := unix.Mprotect(b, unix.PROT_READ|unix.PROT_WRITE); err != nil { |
| t.Fatalf("Mprotect: %v", err) |
| } |
| |
| // Flip flag in test file via mapped memory |
| flagWasZero := true |
| if b[0] == '0' { |
| b[0] = '1' |
| } else if b[0] == '1' { |
| b[0] = '0' |
| flagWasZero = false |
| } |
| |
| if err := unix.Msync(b, unix.MS_SYNC); err != nil { |
| t.Fatalf("Msync: %v", err) |
| } |
| |
| // Read file from FS to ensure flag flipped after msync |
| buf, err := ioutil.ReadFile(filename) |
| if err != nil { |
| t.Fatalf("Could not read mmapped file from disc for test: %v", err) |
| } |
| if flagWasZero && buf[0] != '1' || !flagWasZero && buf[0] != '0' { |
| t.Error("Flag flip in MAP_SHARED mmapped file not visible") |
| } |
| |
| if err := unix.Munmap(b); err != nil { |
| t.Fatalf("Munmap: %v", err) |
| } |
| } |
| |
| func mktmpdir(t *testing.T) string { |
| tmpdir, err := ioutil.TempDir("", "memmapped_file") |
| if err != nil { |
| t.Fatal("mktmpdir:", err) |
| } |
| if err := os.Mkdir(filepath.Join(tmpdir, "testdata"), 0700); err != nil { |
| os.RemoveAll(tmpdir) |
| t.Fatal("mktmpdir:", err) |
| } |
| return tmpdir |
| } |