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