1// Copyright 2009,2010 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// Darwin 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 unix
14
15import (
16	errorspkg "errors"
17	"syscall"
18	"unsafe"
19)
20
21const ImplementsGetwd = true
22
23func Getwd() (string, error) {
24	buf := make([]byte, 2048)
25	attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0)
26	if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 {
27		wd := string(attrs[0])
28		// Sanity check that it's an absolute path and ends
29		// in a null byte, which we then strip.
30		if wd[0] == '/' && wd[len(wd)-1] == 0 {
31			return wd[:len(wd)-1], nil
32		}
33	}
34	// If pkg/os/getwd.go gets ENOTSUP, it will fall back to the
35	// slow algorithm.
36	return "", ENOTSUP
37}
38
39type SockaddrDatalink struct {
40	Len    uint8
41	Family uint8
42	Index  uint16
43	Type   uint8
44	Nlen   uint8
45	Alen   uint8
46	Slen   uint8
47	Data   [12]int8
48	raw    RawSockaddrDatalink
49}
50
51// Translate "kern.hostname" to []_C_int{0,1,2,3}.
52func nametomib(name string) (mib []_C_int, err error) {
53	const siz = unsafe.Sizeof(mib[0])
54
55	// NOTE(rsc): It seems strange to set the buffer to have
56	// size CTL_MAXNAME+2 but use only CTL_MAXNAME
57	// as the size.  I don't know why the +2 is here, but the
58	// kernel uses +2 for its own implementation of this function.
59	// I am scared that if we don't include the +2 here, the kernel
60	// will silently write 2 words farther than we specify
61	// and we'll get memory corruption.
62	var buf [CTL_MAXNAME + 2]_C_int
63	n := uintptr(CTL_MAXNAME) * siz
64
65	p := (*byte)(unsafe.Pointer(&buf[0]))
66	bytes, err := ByteSliceFromString(name)
67	if err != nil {
68		return nil, err
69	}
70
71	// Magic sysctl: "setting" 0.3 to a string name
72	// lets you read back the array of integers form.
73	if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
74		return nil, err
75	}
76	return buf[0 : n/siz], nil
77}
78
79func direntIno(buf []byte) (uint64, bool) {
80	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
81}
82
83func direntReclen(buf []byte) (uint64, bool) {
84	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
85}
86
87func direntNamlen(buf []byte) (uint64, bool) {
88	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
89}
90
91//sys   ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
92func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
93func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
94
95const (
96	attrBitMapCount = 5
97	attrCmnFullpath = 0x08000000
98)
99
100type attrList struct {
101	bitmapCount uint16
102	_           uint16
103	CommonAttr  uint32
104	VolAttr     uint32
105	DirAttr     uint32
106	FileAttr    uint32
107	Forkattr    uint32
108}
109
110func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
111	if len(attrBuf) < 4 {
112		return nil, errorspkg.New("attrBuf too small")
113	}
114	attrList.bitmapCount = attrBitMapCount
115
116	var _p0 *byte
117	_p0, err = BytePtrFromString(path)
118	if err != nil {
119		return nil, err
120	}
121
122	_, _, e1 := Syscall6(
123		SYS_GETATTRLIST,
124		uintptr(unsafe.Pointer(_p0)),
125		uintptr(unsafe.Pointer(&attrList)),
126		uintptr(unsafe.Pointer(&attrBuf[0])),
127		uintptr(len(attrBuf)),
128		uintptr(options),
129		0,
130	)
131	if e1 != 0 {
132		return nil, e1
133	}
134	size := *(*uint32)(unsafe.Pointer(&attrBuf[0]))
135
136	// dat is the section of attrBuf that contains valid data,
137	// without the 4 byte length header. All attribute offsets
138	// are relative to dat.
139	dat := attrBuf
140	if int(size) < len(attrBuf) {
141		dat = dat[:size]
142	}
143	dat = dat[4:] // remove length prefix
144
145	for i := uint32(0); int(i) < len(dat); {
146		header := dat[i:]
147		if len(header) < 8 {
148			return attrs, errorspkg.New("truncated attribute header")
149		}
150		datOff := *(*int32)(unsafe.Pointer(&header[0]))
151		attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
152		if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
153			return attrs, errorspkg.New("truncated results; attrBuf too small")
154		}
155		end := uint32(datOff) + attrLen
156		attrs = append(attrs, dat[datOff:end])
157		i = end
158		if r := i % 4; r != 0 {
159			i += (4 - r)
160		}
161	}
162	return
163}
164
165//sysnb pipe() (r int, w int, err error)
166
167func Pipe(p []int) (err error) {
168	if len(p) != 2 {
169		return EINVAL
170	}
171	p[0], p[1], err = pipe()
172	return
173}
174
175func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
176	var _p0 unsafe.Pointer
177	var bufsize uintptr
178	if len(buf) > 0 {
179		_p0 = unsafe.Pointer(&buf[0])
180		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
181	}
182	r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
183	n = int(r0)
184	if e1 != 0 {
185		err = e1
186	}
187	return
188}
189
190/*
191 * Wrapped
192 */
193
194//sys	kill(pid int, signum int, posix int) (err error)
195
196func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
197
198/*
199 * Exposed directly
200 */
201//sys	Access(path string, mode uint32) (err error)
202//sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
203//sys	Chdir(path string) (err error)
204//sys	Chflags(path string, flags int) (err error)
205//sys	Chmod(path string, mode uint32) (err error)
206//sys	Chown(path string, uid int, gid int) (err error)
207//sys	Chroot(path string) (err error)
208//sys	Close(fd int) (err error)
209//sys	Dup(fd int) (nfd int, err error)
210//sys	Dup2(from int, to int) (err error)
211//sys	Exchangedata(path1 string, path2 string, options int) (err error)
212//sys	Exit(code int)
213//sys	Fchdir(fd int) (err error)
214//sys	Fchflags(fd int, flags int) (err error)
215//sys	Fchmod(fd int, mode uint32) (err error)
216//sys	Fchown(fd int, uid int, gid int) (err error)
217//sys	Flock(fd int, how int) (err error)
218//sys	Fpathconf(fd int, name int) (val int, err error)
219//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
220//sys	Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
221//sys	Fsync(fd int) (err error)
222//sys	Ftruncate(fd int, length int64) (err error)
223//sys	Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
224//sys	Getdtablesize() (size int)
225//sysnb	Getegid() (egid int)
226//sysnb	Geteuid() (uid int)
227//sysnb	Getgid() (gid int)
228//sysnb	Getpgid(pid int) (pgid int, err error)
229//sysnb	Getpgrp() (pgrp int)
230//sysnb	Getpid() (pid int)
231//sysnb	Getppid() (ppid int)
232//sys	Getpriority(which int, who int) (prio int, err error)
233//sysnb	Getrlimit(which int, lim *Rlimit) (err error)
234//sysnb	Getrusage(who int, rusage *Rusage) (err error)
235//sysnb	Getsid(pid int) (sid int, err error)
236//sysnb	Getuid() (uid int)
237//sysnb	Issetugid() (tainted bool)
238//sys	Kqueue() (fd int, err error)
239//sys	Lchown(path string, uid int, gid int) (err error)
240//sys	Link(path string, link string) (err error)
241//sys	Listen(s int, backlog int) (err error)
242//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
243//sys	Mkdir(path string, mode uint32) (err error)
244//sys	Mkfifo(path string, mode uint32) (err error)
245//sys	Mknod(path string, mode uint32, dev int) (err error)
246//sys	Mlock(b []byte) (err error)
247//sys	Mlockall(flags int) (err error)
248//sys	Mprotect(b []byte, prot int) (err error)
249//sys	Munlock(b []byte) (err error)
250//sys	Munlockall() (err error)
251//sys	Open(path string, mode int, perm uint32) (fd int, err error)
252//sys	Pathconf(path string, name int) (val int, err error)
253//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
254//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
255//sys	read(fd int, p []byte) (n int, err error)
256//sys	Readlink(path string, buf []byte) (n int, err error)
257//sys	Rename(from string, to string) (err error)
258//sys	Revoke(path string) (err error)
259//sys	Rmdir(path string) (err error)
260//sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
261//sys	Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
262//sys	Setegid(egid int) (err error)
263//sysnb	Seteuid(euid int) (err error)
264//sysnb	Setgid(gid int) (err error)
265//sys	Setlogin(name string) (err error)
266//sysnb	Setpgid(pid int, pgid int) (err error)
267//sys	Setpriority(which int, who int, prio int) (err error)
268//sys	Setprivexec(flag int) (err error)
269//sysnb	Setregid(rgid int, egid int) (err error)
270//sysnb	Setreuid(ruid int, euid int) (err error)
271//sysnb	Setrlimit(which int, lim *Rlimit) (err error)
272//sysnb	Setsid() (pid int, err error)
273//sysnb	Settimeofday(tp *Timeval) (err error)
274//sysnb	Setuid(uid int) (err error)
275//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
276//sys	Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
277//sys	Symlink(path string, link string) (err error)
278//sys	Sync() (err error)
279//sys	Truncate(path string, length int64) (err error)
280//sys	Umask(newmask int) (oldmask int)
281//sys	Undelete(path string) (err error)
282//sys	Unlink(path string) (err error)
283//sys	Unmount(path string, flags int) (err error)
284//sys	write(fd int, p []byte) (n int, err error)
285//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
286//sys   munmap(addr uintptr, length uintptr) (err error)
287//sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
288//sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
289
290/*
291 * Unimplemented
292 */
293// Profil
294// Sigaction
295// Sigprocmask
296// Getlogin
297// Sigpending
298// Sigaltstack
299// Ioctl
300// Reboot
301// Execve
302// Vfork
303// Sbrk
304// Sstk
305// Ovadvise
306// Mincore
307// Setitimer
308// Swapon
309// Select
310// Sigsuspend
311// Readv
312// Writev
313// Nfssvc
314// Getfh
315// Quotactl
316// Mount
317// Csops
318// Waitid
319// Add_profil
320// Kdebug_trace
321// Sigreturn
322// Mmap
323// Mlock
324// Munlock
325// Atsocket
326// Kqueue_from_portset_np
327// Kqueue_portset
328// Getattrlist
329// Setattrlist
330// Getdirentriesattr
331// Searchfs
332// Delete
333// Copyfile
334// Poll
335// Watchevent
336// Waitevent
337// Modwatch
338// Getxattr
339// Fgetxattr
340// Setxattr
341// Fsetxattr
342// Removexattr
343// Fremovexattr
344// Listxattr
345// Flistxattr
346// Fsctl
347// Initgroups
348// Posix_spawn
349// Nfsclnt
350// Fhopen
351// Minherit
352// Semsys
353// Msgsys
354// Shmsys
355// Semctl
356// Semget
357// Semop
358// Msgctl
359// Msgget
360// Msgsnd
361// Msgrcv
362// Shmat
363// Shmctl
364// Shmdt
365// Shmget
366// Shm_open
367// Shm_unlink
368// Sem_open
369// Sem_close
370// Sem_unlink
371// Sem_wait
372// Sem_trywait
373// Sem_post
374// Sem_getvalue
375// Sem_init
376// Sem_destroy
377// Open_extended
378// Umask_extended
379// Stat_extended
380// Lstat_extended
381// Fstat_extended
382// Chmod_extended
383// Fchmod_extended
384// Access_extended
385// Settid
386// Gettid
387// Setsgroups
388// Getsgroups
389// Setwgroups
390// Getwgroups
391// Mkfifo_extended
392// Mkdir_extended
393// Identitysvc
394// Shared_region_check_np
395// Shared_region_map_np
396// __pthread_mutex_destroy
397// __pthread_mutex_init
398// __pthread_mutex_lock
399// __pthread_mutex_trylock
400// __pthread_mutex_unlock
401// __pthread_cond_init
402// __pthread_cond_destroy
403// __pthread_cond_broadcast
404// __pthread_cond_signal
405// Setsid_with_pid
406// __pthread_cond_timedwait
407// Aio_fsync
408// Aio_return
409// Aio_suspend
410// Aio_cancel
411// Aio_error
412// Aio_read
413// Aio_write
414// Lio_listio
415// __pthread_cond_wait
416// Iopolicysys
417// Mlockall
418// Munlockall
419// __pthread_kill
420// __pthread_sigmask
421// __sigwait
422// __disable_threadsignal
423// __pthread_markcancel
424// __pthread_canceled
425// __semwait_signal
426// Proc_info
427// sendfile
428// Stat64_extended
429// Lstat64_extended
430// Fstat64_extended
431// __pthread_chdir
432// __pthread_fchdir
433// Audit
434// Auditon
435// Getauid
436// Setauid
437// Getaudit
438// Setaudit
439// Getaudit_addr
440// Setaudit_addr
441// Auditctl
442// Bsdthread_create
443// Bsdthread_terminate
444// Stack_snapshot
445// Bsdthread_register
446// Workq_open
447// Workq_ops
448// __mac_execve
449// __mac_syscall
450// __mac_get_file
451// __mac_set_file
452// __mac_get_link
453// __mac_set_link
454// __mac_get_proc
455// __mac_set_proc
456// __mac_get_fd
457// __mac_set_fd
458// __mac_get_pid
459// __mac_get_lcid
460// __mac_get_lctx
461// __mac_set_lctx
462// Setlcid
463// Read_nocancel
464// Write_nocancel
465// Open_nocancel
466// Close_nocancel
467// Wait4_nocancel
468// Recvmsg_nocancel
469// Sendmsg_nocancel
470// Recvfrom_nocancel
471// Accept_nocancel
472// Msync_nocancel
473// Fcntl_nocancel
474// Select_nocancel
475// Fsync_nocancel
476// Connect_nocancel
477// Sigsuspend_nocancel
478// Readv_nocancel
479// Writev_nocancel
480// Sendto_nocancel
481// Pread_nocancel
482// Pwrite_nocancel
483// Waitid_nocancel
484// Poll_nocancel
485// Msgsnd_nocancel
486// Msgrcv_nocancel
487// Sem_wait_nocancel
488// Aio_suspend_nocancel
489// __sigwait_nocancel
490// __semwait_signal_nocancel
491// __mac_mount
492// __mac_get_mount
493// __mac_getfsstat
494