1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// DragonFly BSD system calls.
6// This file is compiled as ordinary Go code,
7// but it is also input to mksyscall,
8// which parses the //sys lines and generates system call stubs.
9// Note that sometimes we use a lowercase //sys name and wrap
10// it in our own nicer implementation, either here or in
11// syscall_bsd.go or syscall_unix.go.
12
13package syscall
14
15import (
16	"sync"
17	"unsafe"
18)
19
20func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
21func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
22func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
23func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
24
25const (
26	_SYS_DUP3         = 0
27	_F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
28)
29
30// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
31var (
32	osreldateOnce sync.Once
33	osreldate     uint32
34)
35
36// First __DragonFly_version after September 2019 ABI changes
37// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html
38const _dragonflyABIChangeVersion = 500705
39
40func supportsABI(ver uint32) bool {
41	osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
42	return osreldate >= ver
43}
44
45type SockaddrDatalink struct {
46	Len    uint8
47	Family uint8
48	Index  uint16
49	Type   uint8
50	Nlen   uint8
51	Alen   uint8
52	Slen   uint8
53	Data   [12]int8
54	Rcf    uint16
55	Route  [16]uint16
56	raw    RawSockaddrDatalink
57}
58
59// Translate "kern.hostname" to []_C_int{0,1,2,3}.
60func nametomib(name string) (mib []_C_int, err error) {
61	const siz = unsafe.Sizeof(mib[0])
62
63	// NOTE(rsc): It seems strange to set the buffer to have
64	// size CTL_MAXNAME+2 but use only CTL_MAXNAME
65	// as the size. I don't know why the +2 is here, but the
66	// kernel uses +2 for its own implementation of this function.
67	// I am scared that if we don't include the +2 here, the kernel
68	// will silently write 2 words farther than we specify
69	// and we'll get memory corruption.
70	var buf [CTL_MAXNAME + 2]_C_int
71	n := uintptr(CTL_MAXNAME) * siz
72
73	p := (*byte)(unsafe.Pointer(&buf[0]))
74	bytes, err := ByteSliceFromString(name)
75	if err != nil {
76		return nil, err
77	}
78
79	// Magic sysctl: "setting" 0.3 to a string name
80	// lets you read back the array of integers form.
81	if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
82		return nil, err
83	}
84	return buf[0 : n/siz], nil
85}
86
87func direntIno(buf []byte) (uint64, bool) {
88	return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
89}
90
91func direntReclen(buf []byte) (uint64, bool) {
92	namlen, ok := direntNamlen(buf)
93	if !ok {
94		return 0, false
95	}
96	return (16 + namlen + 1 + 7) &^ 7, true
97}
98
99func direntNamlen(buf []byte) (uint64, bool) {
100	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
101}
102
103//sysnb pipe() (r int, w int, err error)
104
105func Pipe(p []int) (err error) {
106	if len(p) != 2 {
107		return EINVAL
108	}
109	r, w, err := pipe()
110	if err == nil {
111		p[0], p[1] = r, w
112	}
113	return err
114}
115
116//sysnb	pipe2(p *[2]_C_int, flags int) (r int, w int, err error)
117
118func Pipe2(p []int, flags int) (err error) {
119	if len(p) != 2 {
120		return EINVAL
121	}
122	var pp [2]_C_int
123	// pipe2 on dragonfly takes an fds array as an argument, but still
124	// returns the file descriptors.
125	r, w, err := pipe2(&pp, flags)
126	if err == nil {
127		p[0], p[1] = r, w
128	}
129	return err
130}
131
132//sys	extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
133
134func pread(fd int, p []byte, offset int64) (n int, err error) {
135	return extpread(fd, p, 0, offset)
136}
137
138//sys	extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error)
139
140func pwrite(fd int, p []byte, offset int64) (n int, err error) {
141	return extpwrite(fd, p, 0, offset)
142}
143
144func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
145	var rsa RawSockaddrAny
146	var len _Socklen = SizeofSockaddrAny
147	nfd, err = accept4(fd, &rsa, &len, flags)
148	if err != nil {
149		return
150	}
151	if len > SizeofSockaddrAny {
152		panic("RawSockaddrAny too small")
153	}
154	sa, err = anyToSockaddr(&rsa)
155	if err != nil {
156		Close(nfd)
157		nfd = 0
158	}
159	return
160}
161
162func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
163	var _p0 unsafe.Pointer
164	var bufsize uintptr
165	if len(buf) > 0 {
166		_p0 = unsafe.Pointer(&buf[0])
167		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
168	}
169	r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
170	n = int(r0)
171	if e1 != 0 {
172		err = e1
173	}
174	return
175}
176
177/*
178 * Exposed directly
179 */
180//sys	Access(path string, mode uint32) (err error)
181//sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
182//sys	Chdir(path string) (err error)
183//sys	Chflags(path string, flags int) (err error)
184//sys	Chmod(path string, mode uint32) (err error)
185//sys	Chown(path string, uid int, gid int) (err error)
186//sys	Chroot(path string) (err error)
187//sys	Close(fd int) (err error)
188//sys	Dup(fd int) (nfd int, err error)
189//sys	Dup2(from int, to int) (err error)
190//sys	Fchdir(fd int) (err error)
191//sys	Fchflags(fd int, flags int) (err error)
192//sys	Fchmod(fd int, mode uint32) (err error)
193//sys	Fchown(fd int, uid int, gid int) (err error)
194//sys	Flock(fd int, how int) (err error)
195//sys	Fpathconf(fd int, name int) (val int, err error)
196//sys	Fstat(fd int, stat *Stat_t) (err error)
197//sys	Fstatfs(fd int, stat *Statfs_t) (err error)
198//sys	Fsync(fd int) (err error)
199//sys	Ftruncate(fd int, length int64) (err error)
200//sys	Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
201//sys	Getdtablesize() (size int)
202//sysnb	Getegid() (egid int)
203//sysnb	Geteuid() (uid int)
204//sysnb	Getgid() (gid int)
205//sysnb	Getpgid(pid int) (pgid int, err error)
206//sysnb	Getpgrp() (pgrp int)
207//sysnb	Getpid() (pid int)
208//sysnb	Getppid() (ppid int)
209//sys	Getpriority(which int, who int) (prio int, err error)
210//sysnb	Getrlimit(which int, lim *Rlimit) (err error)
211//sysnb	Getrusage(who int, rusage *Rusage) (err error)
212//sysnb	Getsid(pid int) (sid int, err error)
213//sysnb	Gettimeofday(tv *Timeval) (err error)
214//sysnb	Getuid() (uid int)
215//sys	Issetugid() (tainted bool)
216//sys	Kill(pid int, signum Signal) (err error)
217//sys	Kqueue() (fd int, err error)
218//sys	Lchown(path string, uid int, gid int) (err error)
219//sys	Link(path string, link string) (err error)
220//sys	Listen(s int, backlog int) (err error)
221//sys	Lstat(path string, stat *Stat_t) (err error)
222//sys	Mkdir(path string, mode uint32) (err error)
223//sys	Mkfifo(path string, mode uint32) (err error)
224//sys	Mknod(path string, mode uint32, dev int) (err error)
225//sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
226//sys	Open(path string, mode int, perm uint32) (fd int, err error)
227//sys	Pathconf(path string, name int) (val int, err error)
228//sys	read(fd int, p []byte) (n int, err error)
229//sys	Readlink(path string, buf []byte) (n int, err error)
230//sys	Rename(from string, to string) (err error)
231//sys	Revoke(path string) (err error)
232//sys	Rmdir(path string) (err error)
233//sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
234//sys	Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
235//sysnb	Setegid(egid int) (err error)
236//sysnb	Seteuid(euid int) (err error)
237//sysnb	Setgid(gid int) (err error)
238//sys	Setlogin(name string) (err error)
239//sysnb	Setpgid(pid int, pgid int) (err error)
240//sys	Setpriority(which int, who int, prio int) (err error)
241//sysnb	Setregid(rgid int, egid int) (err error)
242//sysnb	Setreuid(ruid int, euid int) (err error)
243//sysnb	setrlimit(which int, lim *Rlimit) (err error)
244//sysnb	Setsid() (pid int, err error)
245//sysnb	Settimeofday(tp *Timeval) (err error)
246//sysnb	Setuid(uid int) (err error)
247//sys	Stat(path string, stat *Stat_t) (err error)
248//sys	Statfs(path string, stat *Statfs_t) (err error)
249//sys	Symlink(path string, link string) (err error)
250//sys	Sync() (err error)
251//sys	Truncate(path string, length int64) (err error)
252//sys	Umask(newmask int) (oldmask int)
253//sys	Undelete(path string) (err error)
254//sys	Unlink(path string) (err error)
255//sys	Unmount(path string, flags int) (err error)
256//sys	write(fd int, p []byte) (n int, err error)
257//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
258//sys   munmap(addr uintptr, length uintptr) (err error)
259//sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
260//sys	accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
261//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
262//sys	getcwd(buf []byte) (n int, err error) = SYS___GETCWD
263//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
264