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 "runtime" 17 "syscall" 18 "unsafe" 19) 20 21// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. 22type SockaddrDatalink struct { 23 Len uint8 24 Family uint8 25 Index uint16 26 Type uint8 27 Nlen uint8 28 Alen uint8 29 Slen uint8 30 Data [12]int8 31 raw RawSockaddrDatalink 32} 33 34// Some external packages rely on SYS___SYSCTL being defined to implement their 35// own sysctl wrappers. Provide it here, even though direct syscalls are no 36// longer supported on darwin. 37const SYS___SYSCTL = 202 38 39// Translate "kern.hostname" to []_C_int{0,1,2,3}. 40func nametomib(name string) (mib []_C_int, err error) { 41 const siz = unsafe.Sizeof(mib[0]) 42 43 // NOTE(rsc): It seems strange to set the buffer to have 44 // size CTL_MAXNAME+2 but use only CTL_MAXNAME 45 // as the size. I don't know why the +2 is here, but the 46 // kernel uses +2 for its own implementation of this function. 47 // I am scared that if we don't include the +2 here, the kernel 48 // will silently write 2 words farther than we specify 49 // and we'll get memory corruption. 50 var buf [CTL_MAXNAME + 2]_C_int 51 n := uintptr(CTL_MAXNAME) * siz 52 53 p := (*byte)(unsafe.Pointer(&buf[0])) 54 bytes, err := ByteSliceFromString(name) 55 if err != nil { 56 return nil, err 57 } 58 59 // Magic sysctl: "setting" 0.3 to a string name 60 // lets you read back the array of integers form. 61 if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil { 62 return nil, err 63 } 64 return buf[0 : n/siz], nil 65} 66 67func direntIno(buf []byte) (uint64, bool) { 68 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 69} 70 71func direntReclen(buf []byte) (uint64, bool) { 72 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 73} 74 75func direntNamlen(buf []byte) (uint64, bool) { 76 return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) 77} 78 79func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } 80func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } 81 82type attrList struct { 83 bitmapCount uint16 84 _ uint16 85 CommonAttr uint32 86 VolAttr uint32 87 DirAttr uint32 88 FileAttr uint32 89 Forkattr uint32 90} 91 92//sysnb pipe() (r int, w int, err error) 93 94func Pipe(p []int) (err error) { 95 if len(p) != 2 { 96 return EINVAL 97 } 98 p[0], p[1], err = pipe() 99 return 100} 101 102func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { 103 var _p0 unsafe.Pointer 104 var bufsize uintptr 105 if len(buf) > 0 { 106 _p0 = unsafe.Pointer(&buf[0]) 107 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) 108 } 109 return getfsstat(_p0, bufsize, flags) 110} 111 112func xattrPointer(dest []byte) *byte { 113 // It's only when dest is set to NULL that the OS X implementations of 114 // getxattr() and listxattr() return the current sizes of the named attributes. 115 // An empty byte array is not sufficient. To maintain the same behaviour as the 116 // linux implementation, we wrap around the system calls and pass in NULL when 117 // dest is empty. 118 var destp *byte 119 if len(dest) > 0 { 120 destp = &dest[0] 121 } 122 return destp 123} 124 125//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) 126 127func Getxattr(path string, attr string, dest []byte) (sz int, err error) { 128 return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0) 129} 130 131func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) { 132 return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW) 133} 134 135//sys fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) 136 137func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { 138 return fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0) 139} 140 141//sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) 142 143func Setxattr(path string, attr string, data []byte, flags int) (err error) { 144 // The parameters for the OS X implementation vary slightly compared to the 145 // linux system call, specifically the position parameter: 146 // 147 // linux: 148 // int setxattr( 149 // const char *path, 150 // const char *name, 151 // const void *value, 152 // size_t size, 153 // int flags 154 // ); 155 // 156 // darwin: 157 // int setxattr( 158 // const char *path, 159 // const char *name, 160 // void *value, 161 // size_t size, 162 // u_int32_t position, 163 // int options 164 // ); 165 // 166 // position specifies the offset within the extended attribute. In the 167 // current implementation, only the resource fork extended attribute makes 168 // use of this argument. For all others, position is reserved. We simply 169 // default to setting it to zero. 170 return setxattr(path, attr, xattrPointer(data), len(data), 0, flags) 171} 172 173func Lsetxattr(link string, attr string, data []byte, flags int) (err error) { 174 return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW) 175} 176 177//sys fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) 178 179func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) { 180 return fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0) 181} 182 183//sys removexattr(path string, attr string, options int) (err error) 184 185func Removexattr(path string, attr string) (err error) { 186 // We wrap around and explicitly zero out the options provided to the OS X 187 // implementation of removexattr, we do so for interoperability with the 188 // linux variant. 189 return removexattr(path, attr, 0) 190} 191 192func Lremovexattr(link string, attr string) (err error) { 193 return removexattr(link, attr, XATTR_NOFOLLOW) 194} 195 196//sys fremovexattr(fd int, attr string, options int) (err error) 197 198func Fremovexattr(fd int, attr string) (err error) { 199 return fremovexattr(fd, attr, 0) 200} 201 202//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error) 203 204func Listxattr(path string, dest []byte) (sz int, err error) { 205 return listxattr(path, xattrPointer(dest), len(dest), 0) 206} 207 208func Llistxattr(link string, dest []byte) (sz int, err error) { 209 return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW) 210} 211 212//sys flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) 213 214func Flistxattr(fd int, dest []byte) (sz int, err error) { 215 return flistxattr(fd, xattrPointer(dest), len(dest), 0) 216} 217 218func setattrlistTimes(path string, times []Timespec, flags int) error { 219 _p0, err := BytePtrFromString(path) 220 if err != nil { 221 return err 222 } 223 224 var attrList attrList 225 attrList.bitmapCount = ATTR_BIT_MAP_COUNT 226 attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME 227 228 // order is mtime, atime: the opposite of Chtimes 229 attributes := [2]Timespec{times[1], times[0]} 230 options := 0 231 if flags&AT_SYMLINK_NOFOLLOW != 0 { 232 options |= FSOPT_NOFOLLOW 233 } 234 return setattrlist( 235 _p0, 236 unsafe.Pointer(&attrList), 237 unsafe.Pointer(&attributes), 238 unsafe.Sizeof(attributes), 239 options) 240} 241 242//sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) 243 244func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error { 245 // Darwin doesn't support SYS_UTIMENSAT 246 return ENOSYS 247} 248 249/* 250 * Wrapped 251 */ 252 253//sys fcntl(fd int, cmd int, arg int) (val int, err error) 254 255//sys kill(pid int, signum int, posix int) (err error) 256 257func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) } 258 259//sys ioctl(fd int, req uint, arg uintptr) (err error) 260 261func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error { 262 err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo))) 263 runtime.KeepAlive(ctlInfo) 264 return err 265} 266 267//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL 268 269func Uname(uname *Utsname) error { 270 mib := []_C_int{CTL_KERN, KERN_OSTYPE} 271 n := unsafe.Sizeof(uname.Sysname) 272 if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { 273 return err 274 } 275 276 mib = []_C_int{CTL_KERN, KERN_HOSTNAME} 277 n = unsafe.Sizeof(uname.Nodename) 278 if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { 279 return err 280 } 281 282 mib = []_C_int{CTL_KERN, KERN_OSRELEASE} 283 n = unsafe.Sizeof(uname.Release) 284 if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { 285 return err 286 } 287 288 mib = []_C_int{CTL_KERN, KERN_VERSION} 289 n = unsafe.Sizeof(uname.Version) 290 if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { 291 return err 292 } 293 294 // The version might have newlines or tabs in it, convert them to 295 // spaces. 296 for i, b := range uname.Version { 297 if b == '\n' || b == '\t' { 298 if i == len(uname.Version)-1 { 299 uname.Version[i] = 0 300 } else { 301 uname.Version[i] = ' ' 302 } 303 } 304 } 305 306 mib = []_C_int{CTL_HW, HW_MACHINE} 307 n = unsafe.Sizeof(uname.Machine) 308 if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { 309 return err 310 } 311 312 return nil 313} 314 315func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 316 if raceenabled { 317 raceReleaseMerge(unsafe.Pointer(&ioSync)) 318 } 319 var length = int64(count) 320 err = sendfile(infd, outfd, *offset, &length, nil, 0) 321 written = int(length) 322 return 323} 324 325//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) 326 327/* 328 * Exposed directly 329 */ 330//sys Access(path string, mode uint32) (err error) 331//sys Adjtime(delta *Timeval, olddelta *Timeval) (err error) 332//sys Chdir(path string) (err error) 333//sys Chflags(path string, flags int) (err error) 334//sys Chmod(path string, mode uint32) (err error) 335//sys Chown(path string, uid int, gid int) (err error) 336//sys Chroot(path string) (err error) 337//sys ClockGettime(clockid int32, time *Timespec) (err error) 338//sys Close(fd int) (err error) 339//sys Clonefile(src string, dst string, flags int) (err error) 340//sys Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) 341//sys Dup(fd int) (nfd int, err error) 342//sys Dup2(from int, to int) (err error) 343//sys Exchangedata(path1 string, path2 string, options int) (err error) 344//sys Exit(code int) 345//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) 346//sys Fchdir(fd int) (err error) 347//sys Fchflags(fd int, flags int) (err error) 348//sys Fchmod(fd int, mode uint32) (err error) 349//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) 350//sys Fchown(fd int, uid int, gid int) (err error) 351//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 352//sys Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) 353//sys Flock(fd int, how int) (err error) 354//sys Fpathconf(fd int, name int) (val int, err error) 355//sys Fsync(fd int) (err error) 356//sys Ftruncate(fd int, length int64) (err error) 357//sys Getcwd(buf []byte) (n int, err error) 358//sys Getdtablesize() (size int) 359//sysnb Getegid() (egid int) 360//sysnb Geteuid() (uid int) 361//sysnb Getgid() (gid int) 362//sysnb Getpgid(pid int) (pgid int, err error) 363//sysnb Getpgrp() (pgrp int) 364//sysnb Getpid() (pid int) 365//sysnb Getppid() (ppid int) 366//sys Getpriority(which int, who int) (prio int, err error) 367//sysnb Getrlimit(which int, lim *Rlimit) (err error) 368//sysnb Getrusage(who int, rusage *Rusage) (err error) 369//sysnb Getsid(pid int) (sid int, err error) 370//sysnb Gettimeofday(tp *Timeval) (err error) 371//sysnb Getuid() (uid int) 372//sysnb Issetugid() (tainted bool) 373//sys Kqueue() (fd int, err error) 374//sys Lchown(path string, uid int, gid int) (err error) 375//sys Link(path string, link string) (err error) 376//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) 377//sys Listen(s int, backlog int) (err error) 378//sys Mkdir(path string, mode uint32) (err error) 379//sys Mkdirat(dirfd int, path string, mode uint32) (err error) 380//sys Mkfifo(path string, mode uint32) (err error) 381//sys Mknod(path string, mode uint32, dev int) (err error) 382//sys Open(path string, mode int, perm uint32) (fd int, err error) 383//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) 384//sys Pathconf(path string, name int) (val int, err error) 385//sys Pread(fd int, p []byte, offset int64) (n int, err error) 386//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) 387//sys read(fd int, p []byte) (n int, err error) 388//sys Readlink(path string, buf []byte) (n int, err error) 389//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) 390//sys Rename(from string, to string) (err error) 391//sys Renameat(fromfd int, from string, tofd int, to string) (err error) 392//sys Revoke(path string) (err error) 393//sys Rmdir(path string) (err error) 394//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK 395//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) 396//sys Setegid(egid int) (err error) 397//sysnb Seteuid(euid int) (err error) 398//sysnb Setgid(gid int) (err error) 399//sys Setlogin(name string) (err error) 400//sysnb Setpgid(pid int, pgid int) (err error) 401//sys Setpriority(which int, who int, prio int) (err error) 402//sys Setprivexec(flag int) (err error) 403//sysnb Setregid(rgid int, egid int) (err error) 404//sysnb Setreuid(ruid int, euid int) (err error) 405//sysnb Setrlimit(which int, lim *Rlimit) (err error) 406//sysnb Setsid() (pid int, err error) 407//sysnb Settimeofday(tp *Timeval) (err error) 408//sysnb Setuid(uid int) (err error) 409//sys Symlink(path string, link string) (err error) 410//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) 411//sys Sync() (err error) 412//sys Truncate(path string, length int64) (err error) 413//sys Umask(newmask int) (oldmask int) 414//sys Undelete(path string) (err error) 415//sys Unlink(path string) (err error) 416//sys Unlinkat(dirfd int, path string, flags int) (err error) 417//sys Unmount(path string, flags int) (err error) 418//sys write(fd int, p []byte) (n int, err error) 419//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) 420//sys munmap(addr uintptr, length uintptr) (err error) 421//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ 422//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE 423 424/* 425 * Unimplemented 426 */ 427// Profil 428// Sigaction 429// Sigprocmask 430// Getlogin 431// Sigpending 432// Sigaltstack 433// Ioctl 434// Reboot 435// Execve 436// Vfork 437// Sbrk 438// Sstk 439// Ovadvise 440// Mincore 441// Setitimer 442// Swapon 443// Select 444// Sigsuspend 445// Readv 446// Writev 447// Nfssvc 448// Getfh 449// Quotactl 450// Mount 451// Csops 452// Waitid 453// Add_profil 454// Kdebug_trace 455// Sigreturn 456// Atsocket 457// Kqueue_from_portset_np 458// Kqueue_portset 459// Getattrlist 460// Setattrlist 461// Getdirentriesattr 462// Searchfs 463// Delete 464// Copyfile 465// Watchevent 466// Waitevent 467// Modwatch 468// Fsctl 469// Initgroups 470// Posix_spawn 471// Nfsclnt 472// Fhopen 473// Minherit 474// Semsys 475// Msgsys 476// Shmsys 477// Semctl 478// Semget 479// Semop 480// Msgctl 481// Msgget 482// Msgsnd 483// Msgrcv 484// Shmat 485// Shmctl 486// Shmdt 487// Shmget 488// Shm_open 489// Shm_unlink 490// Sem_open 491// Sem_close 492// Sem_unlink 493// Sem_wait 494// Sem_trywait 495// Sem_post 496// Sem_getvalue 497// Sem_init 498// Sem_destroy 499// Open_extended 500// Umask_extended 501// Stat_extended 502// Lstat_extended 503// Fstat_extended 504// Chmod_extended 505// Fchmod_extended 506// Access_extended 507// Settid 508// Gettid 509// Setsgroups 510// Getsgroups 511// Setwgroups 512// Getwgroups 513// Mkfifo_extended 514// Mkdir_extended 515// Identitysvc 516// Shared_region_check_np 517// Shared_region_map_np 518// __pthread_mutex_destroy 519// __pthread_mutex_init 520// __pthread_mutex_lock 521// __pthread_mutex_trylock 522// __pthread_mutex_unlock 523// __pthread_cond_init 524// __pthread_cond_destroy 525// __pthread_cond_broadcast 526// __pthread_cond_signal 527// Setsid_with_pid 528// __pthread_cond_timedwait 529// Aio_fsync 530// Aio_return 531// Aio_suspend 532// Aio_cancel 533// Aio_error 534// Aio_read 535// Aio_write 536// Lio_listio 537// __pthread_cond_wait 538// Iopolicysys 539// __pthread_kill 540// __pthread_sigmask 541// __sigwait 542// __disable_threadsignal 543// __pthread_markcancel 544// __pthread_canceled 545// __semwait_signal 546// Proc_info 547// sendfile 548// Stat64_extended 549// Lstat64_extended 550// Fstat64_extended 551// __pthread_chdir 552// __pthread_fchdir 553// Audit 554// Auditon 555// Getauid 556// Setauid 557// Getaudit 558// Setaudit 559// Getaudit_addr 560// Setaudit_addr 561// Auditctl 562// Bsdthread_create 563// Bsdthread_terminate 564// Stack_snapshot 565// Bsdthread_register 566// Workq_open 567// Workq_ops 568// __mac_execve 569// __mac_syscall 570// __mac_get_file 571// __mac_set_file 572// __mac_get_link 573// __mac_set_link 574// __mac_get_proc 575// __mac_set_proc 576// __mac_get_fd 577// __mac_set_fd 578// __mac_get_pid 579// __mac_get_lcid 580// __mac_get_lctx 581// __mac_set_lctx 582// Setlcid 583// Read_nocancel 584// Write_nocancel 585// Open_nocancel 586// Close_nocancel 587// Wait4_nocancel 588// Recvmsg_nocancel 589// Sendmsg_nocancel 590// Recvfrom_nocancel 591// Accept_nocancel 592// Fcntl_nocancel 593// Select_nocancel 594// Fsync_nocancel 595// Connect_nocancel 596// Sigsuspend_nocancel 597// Readv_nocancel 598// Writev_nocancel 599// Sendto_nocancel 600// Pread_nocancel 601// Pwrite_nocancel 602// Waitid_nocancel 603// Poll_nocancel 604// Msgsnd_nocancel 605// Msgrcv_nocancel 606// Sem_wait_nocancel 607// Aio_suspend_nocancel 608// __sigwait_nocancel 609// __semwait_signal_nocancel 610// __mac_mount 611// __mac_get_mount 612// __mac_getfsstat 613