File: test_freebsd.go

package info (click to toggle)
golang-github-hanwen-go-fuse 2.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,584 kB
  • sloc: cpp: 78; sh: 47; makefile: 16
file content (40 lines) | stat: -rw-r--r-- 1,310 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package posixtest

import (
	"syscall"
	"unsafe"
)

// Since FreeBSD doesn't implement the F_OFD_GETLK, to mimic its behaviour,
// we here first fork the process via syscall, and execute fcntl(2) in the child
// process to get the lock info. Then we send the lock info via pipe back to
// the parent test process.

func sysFcntlFlockGetOFDLock(fd uintptr, lk *syscall.Flock_t) error {
	pipefd := make([]int, 2)
	err := syscall.Pipe(pipefd)
	if err != nil {
		return err
	}
	pid, _, err := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
	if pid == 0 { // child process
		syscall.Close(pipefd[0]) // close read end
		var clk syscall.Flock_t
		// Here we must give a vaild lock type, or fcntl(2) will return
		// EINVAL. And it should be different from what we set earlier
		// in the test. Here we set to F_RDLOCK.
		clk.Type = syscall.F_RDLCK
		syscall.FcntlFlock(fd, syscall.F_GETLK, &clk)
		syscall.Syscall(syscall.SYS_WRITE, uintptr(pipefd[1]), uintptr(unsafe.Pointer(&clk)), unsafe.Sizeof(clk))
		syscall.Exit(0)
	} else if pid > 0 { // parent process
		syscall.Close(pipefd[1]) // close write end
		buf := make([]byte, unsafe.Sizeof(*lk))
		syscall.Read(pipefd[0], buf)
		*lk = *((*syscall.Flock_t)(unsafe.Pointer(&buf[0])))
		syscall.Close(pipefd[0]) // close read end
	} else {
		return err
	}
	return nil
}