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