1// SPDX-License-Identifier: MIT
2
3//go:build linux && (amd64 || arm64)
4
5package git
6
7import (
8 "syscall"
9 "unsafe"
10)
11
12const atSymlinkNoFollow = 0x100
13
14// statNul is syscall.Stat and syscall.Lstat without their allocation: package
15// syscall copies the path into a new NUL-terminated byte slice at each call,
16// here the caller built it once. It makes the system call they make on this
17// platform, fstatat(AT_FDCWD, path, &stat, flags), into the same Stat_t.
18func statNul(nul []byte, lstat bool, st *fileStat) error {
19 var sys syscall.Stat_t
20 var flags uintptr
21 if lstat {
22 flags = atSymlinkNoFollow
23 }
24 atFDCWD := -100
25 var errno syscall.Errno
26 for {
27 _, _, errno = syscall.Syscall6(sysFstatat, uintptr(atFDCWD), uintptr(unsafe.Pointer(&nul[0])), uintptr(unsafe.Pointer(&sys)), flags, 0, 0)
28 if errno != syscall.EINTR {
29 break
30 }
31 }
32 var err error
33 if errno != 0 {
34 err = errno
35 }
36 return fillStat(st, &sys, nul, err)
37}
38
39const (
40 oRdonly = 0
41 oCloexec = 0x80000
42)
43
44// openNul opens the file read-only with openat(AT_FDCWD, path, flags), the
45// system call syscall.Open makes, from a path that is already NUL-terminated.
46func openNul(nul []byte) (rawFile, error) {
47 atFDCWD := -100
48 for {
49 fd, _, errno := syscall.Syscall6(sysOpenat, uintptr(atFDCWD), uintptr(unsafe.Pointer(&nul[0])), oRdonly|oCloexec, 0, 0, 0)
50 if errno == syscall.EINTR {
51 continue
52 }
53 if errno != 0 {
54 return rawFile{}, errno
55 }
56 return rawFile{int(fd)}, nil
57 }
58}