vendor/golang.org/x/sys/unix/syscall_darwin.go
changeset 256 6d9efbef00a9
parent 251 1c52a0eeb952
child 260 445e01aede7e
equal deleted inserted replaced
255:4f153a23adab 256:6d9efbef00a9
    11 // syscall_bsd.go or syscall_unix.go.
    11 // syscall_bsd.go or syscall_unix.go.
    12 
    12 
    13 package unix
    13 package unix
    14 
    14 
    15 import (
    15 import (
    16 	"errors"
    16 	"fmt"
       
    17 	"runtime"
    17 	"syscall"
    18 	"syscall"
    18 	"unsafe"
    19 	"unsafe"
    19 )
    20 )
    20 
       
    21 const ImplementsGetwd = true
       
    22 
       
    23 func 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 
    21 
    39 // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
    22 // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
    40 type SockaddrDatalink struct {
    23 type SockaddrDatalink struct {
    41 	Len    uint8
    24 	Len    uint8
    42 	Family uint8
    25 	Family uint8
    47 	Slen   uint8
    30 	Slen   uint8
    48 	Data   [12]int8
    31 	Data   [12]int8
    49 	raw    RawSockaddrDatalink
    32 	raw    RawSockaddrDatalink
    50 }
    33 }
    51 
    34 
       
    35 // SockaddrCtl implements the Sockaddr interface for AF_SYSTEM type sockets.
       
    36 type SockaddrCtl struct {
       
    37 	ID   uint32
       
    38 	Unit uint32
       
    39 	raw  RawSockaddrCtl
       
    40 }
       
    41 
       
    42 func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
       
    43 	sa.raw.Sc_len = SizeofSockaddrCtl
       
    44 	sa.raw.Sc_family = AF_SYSTEM
       
    45 	sa.raw.Ss_sysaddr = AF_SYS_CONTROL
       
    46 	sa.raw.Sc_id = sa.ID
       
    47 	sa.raw.Sc_unit = sa.Unit
       
    48 	return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
       
    49 }
       
    50 
       
    51 func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
       
    52 	switch rsa.Addr.Family {
       
    53 	case AF_SYSTEM:
       
    54 		pp := (*RawSockaddrCtl)(unsafe.Pointer(rsa))
       
    55 		if pp.Ss_sysaddr == AF_SYS_CONTROL {
       
    56 			sa := new(SockaddrCtl)
       
    57 			sa.ID = pp.Sc_id
       
    58 			sa.Unit = pp.Sc_unit
       
    59 			return sa, nil
       
    60 		}
       
    61 	}
       
    62 	return nil, EAFNOSUPPORT
       
    63 }
       
    64 
       
    65 // Some external packages rely on SYS___SYSCTL being defined to implement their
       
    66 // own sysctl wrappers. Provide it here, even though direct syscalls are no
       
    67 // longer supported on darwin.
       
    68 const SYS___SYSCTL = SYS_SYSCTL
       
    69 
    52 // Translate "kern.hostname" to []_C_int{0,1,2,3}.
    70 // Translate "kern.hostname" to []_C_int{0,1,2,3}.
    53 func nametomib(name string) (mib []_C_int, err error) {
    71 func nametomib(name string) (mib []_C_int, err error) {
    54 	const siz = unsafe.Sizeof(mib[0])
    72 	const siz = unsafe.Sizeof(mib[0])
    55 
    73 
    56 	// NOTE(rsc): It seems strange to set the buffer to have
    74 	// NOTE(rsc): It seems strange to set the buffer to have
    90 }
   108 }
    91 
   109 
    92 func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
   110 func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
    93 func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
   111 func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
    94 
   112 
    95 const (
       
    96 	attrBitMapCount = 5
       
    97 	attrCmnFullpath = 0x08000000
       
    98 )
       
    99 
       
   100 type attrList struct {
   113 type attrList struct {
   101 	bitmapCount uint16
   114 	bitmapCount uint16
   102 	_           uint16
   115 	_           uint16
   103 	CommonAttr  uint32
   116 	CommonAttr  uint32
   104 	VolAttr     uint32
   117 	VolAttr     uint32
   105 	DirAttr     uint32
   118 	DirAttr     uint32
   106 	FileAttr    uint32
   119 	FileAttr    uint32
   107 	Forkattr    uint32
   120 	Forkattr    uint32
   108 }
   121 }
   109 
   122 
   110 func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
   123 //sysnb	pipe(p *[2]int32) (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 
       
   158 //sysnb pipe() (r int, w int, err error)
       
   159 
   124 
   160 func Pipe(p []int) (err error) {
   125 func Pipe(p []int) (err error) {
   161 	if len(p) != 2 {
   126 	if len(p) != 2 {
   162 		return EINVAL
   127 		return EINVAL
   163 	}
   128 	}
   164 	p[0], p[1], err = pipe()
   129 	var x [2]int32
       
   130 	err = pipe(&x)
       
   131 	p[0] = int(x[0])
       
   132 	p[1] = int(x[1])
   165 	return
   133 	return
   166 }
   134 }
   167 
   135 
   168 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
   136 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
   169 	var _p0 unsafe.Pointer
   137 	var _p0 unsafe.Pointer
   303 		unsafe.Pointer(&attributes),
   271 		unsafe.Pointer(&attributes),
   304 		unsafe.Sizeof(attributes),
   272 		unsafe.Sizeof(attributes),
   305 		options)
   273 		options)
   306 }
   274 }
   307 
   275 
   308 //sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
   276 //sys	setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
   309 
   277 
   310 func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
   278 func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
   311 	// Darwin doesn't support SYS_UTIMENSAT
   279 	// Darwin doesn't support SYS_UTIMENSAT
   312 	return ENOSYS
   280 	return ENOSYS
   313 }
   281 }
   322 
   290 
   323 func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
   291 func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
   324 
   292 
   325 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
   293 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
   326 
   294 
   327 //sys   sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
   295 func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error {
       
   296 	err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo)))
       
   297 	runtime.KeepAlive(ctlInfo)
       
   298 	return err
       
   299 }
       
   300 
       
   301 // IfreqMTU is struct ifreq used to get or set a network device's MTU.
       
   302 type IfreqMTU struct {
       
   303 	Name [IFNAMSIZ]byte
       
   304 	MTU  int32
       
   305 }
       
   306 
       
   307 // IoctlGetIfreqMTU performs the SIOCGIFMTU ioctl operation on fd to get the MTU
       
   308 // of the network device specified by ifname.
       
   309 func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) {
       
   310 	var ifreq IfreqMTU
       
   311 	copy(ifreq.Name[:], ifname)
       
   312 	err := ioctl(fd, SIOCGIFMTU, uintptr(unsafe.Pointer(&ifreq)))
       
   313 	return &ifreq, err
       
   314 }
       
   315 
       
   316 // IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU
       
   317 // of the network device specified by ifreq.Name.
       
   318 func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error {
       
   319 	err := ioctl(fd, SIOCSIFMTU, uintptr(unsafe.Pointer(ifreq)))
       
   320 	runtime.KeepAlive(ifreq)
       
   321 	return err
       
   322 }
       
   323 
       
   324 //sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
   328 
   325 
   329 func Uname(uname *Utsname) error {
   326 func Uname(uname *Utsname) error {
   330 	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
   327 	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
   331 	n := unsafe.Sizeof(uname.Sysname)
   328 	n := unsafe.Sizeof(uname.Sysname)
   332 	if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
   329 	if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
   378 	}
   375 	}
   379 	var length = int64(count)
   376 	var length = int64(count)
   380 	err = sendfile(infd, outfd, *offset, &length, nil, 0)
   377 	err = sendfile(infd, outfd, *offset, &length, nil, 0)
   381 	written = int(length)
   378 	written = int(length)
   382 	return
   379 	return
       
   380 }
       
   381 
       
   382 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
       
   383 	var value IPMreqn
       
   384 	vallen := _Socklen(SizeofIPMreqn)
       
   385 	errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
       
   386 	return &value, errno
       
   387 }
       
   388 
       
   389 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
       
   390 	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
       
   391 }
       
   392 
       
   393 // GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct.
       
   394 // The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively.
       
   395 func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
       
   396 	x := new(Xucred)
       
   397 	vallen := _Socklen(SizeofXucred)
       
   398 	err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
       
   399 	return x, err
       
   400 }
       
   401 
       
   402 func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
       
   403 	mib, err := sysctlmib(name)
       
   404 	if err != nil {
       
   405 		return nil, err
       
   406 	}
       
   407 
       
   408 	// Find size.
       
   409 	n := uintptr(0)
       
   410 	if err := sysctl(mib, nil, &n, nil, 0); err != nil {
       
   411 		return nil, err
       
   412 	}
       
   413 	if n == 0 {
       
   414 		return nil, nil
       
   415 	}
       
   416 	if n%SizeofKinfoProc != 0 {
       
   417 		return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
       
   418 	}
       
   419 
       
   420 	// Read into buffer of that size.
       
   421 	buf := make([]KinfoProc, n/SizeofKinfoProc)
       
   422 	if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
       
   423 		return nil, err
       
   424 	}
       
   425 	if n%SizeofKinfoProc != 0 {
       
   426 		return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
       
   427 	}
       
   428 
       
   429 	// The actual call may return less than the original reported required
       
   430 	// size so ensure we deal with that.
       
   431 	return buf[:n/SizeofKinfoProc], nil
   383 }
   432 }
   384 
   433 
   385 //sys	sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
   434 //sys	sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
   386 
   435 
   387 /*
   436 /*
   394 //sys	Chmod(path string, mode uint32) (err error)
   443 //sys	Chmod(path string, mode uint32) (err error)
   395 //sys	Chown(path string, uid int, gid int) (err error)
   444 //sys	Chown(path string, uid int, gid int) (err error)
   396 //sys	Chroot(path string) (err error)
   445 //sys	Chroot(path string) (err error)
   397 //sys	ClockGettime(clockid int32, time *Timespec) (err error)
   446 //sys	ClockGettime(clockid int32, time *Timespec) (err error)
   398 //sys	Close(fd int) (err error)
   447 //sys	Close(fd int) (err error)
       
   448 //sys	Clonefile(src string, dst string, flags int) (err error)
       
   449 //sys	Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error)
   399 //sys	Dup(fd int) (nfd int, err error)
   450 //sys	Dup(fd int) (nfd int, err error)
   400 //sys	Dup2(from int, to int) (err error)
   451 //sys	Dup2(from int, to int) (err error)
   401 //sys	Exchangedata(path1 string, path2 string, options int) (err error)
   452 //sys	Exchangedata(path1 string, path2 string, options int) (err error)
   402 //sys	Exit(code int)
   453 //sys	Exit(code int)
   403 //sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
   454 //sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
   405 //sys	Fchflags(fd int, flags int) (err error)
   456 //sys	Fchflags(fd int, flags int) (err error)
   406 //sys	Fchmod(fd int, mode uint32) (err error)
   457 //sys	Fchmod(fd int, mode uint32) (err error)
   407 //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
   458 //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
   408 //sys	Fchown(fd int, uid int, gid int) (err error)
   459 //sys	Fchown(fd int, uid int, gid int) (err error)
   409 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
   460 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
       
   461 //sys	Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error)
   410 //sys	Flock(fd int, how int) (err error)
   462 //sys	Flock(fd int, how int) (err error)
   411 //sys	Fpathconf(fd int, name int) (val int, err error)
   463 //sys	Fpathconf(fd int, name int) (val int, err error)
   412 //sys	Fsync(fd int) (err error)
   464 //sys	Fsync(fd int) (err error)
   413 //sys	Ftruncate(fd int, length int64) (err error)
   465 //sys	Ftruncate(fd int, length int64) (err error)
       
   466 //sys	Getcwd(buf []byte) (n int, err error)
   414 //sys	Getdtablesize() (size int)
   467 //sys	Getdtablesize() (size int)
   415 //sysnb	Getegid() (egid int)
   468 //sysnb	Getegid() (egid int)
   416 //sysnb	Geteuid() (uid int)
   469 //sysnb	Geteuid() (uid int)
   417 //sysnb	Getgid() (gid int)
   470 //sysnb	Getgid() (gid int)
   418 //sysnb	Getpgid(pid int) (pgid int, err error)
   471 //sysnb	Getpgid(pid int) (pgid int, err error)
   421 //sysnb	Getppid() (ppid int)
   474 //sysnb	Getppid() (ppid int)
   422 //sys	Getpriority(which int, who int) (prio int, err error)
   475 //sys	Getpriority(which int, who int) (prio int, err error)
   423 //sysnb	Getrlimit(which int, lim *Rlimit) (err error)
   476 //sysnb	Getrlimit(which int, lim *Rlimit) (err error)
   424 //sysnb	Getrusage(who int, rusage *Rusage) (err error)
   477 //sysnb	Getrusage(who int, rusage *Rusage) (err error)
   425 //sysnb	Getsid(pid int) (sid int, err error)
   478 //sysnb	Getsid(pid int) (sid int, err error)
       
   479 //sysnb	Gettimeofday(tp *Timeval) (err error)
   426 //sysnb	Getuid() (uid int)
   480 //sysnb	Getuid() (uid int)
   427 //sysnb	Issetugid() (tainted bool)
   481 //sysnb	Issetugid() (tainted bool)
   428 //sys	Kqueue() (fd int, err error)
   482 //sys	Kqueue() (fd int, err error)
   429 //sys	Lchown(path string, uid int, gid int) (err error)
   483 //sys	Lchown(path string, uid int, gid int) (err error)
   430 //sys	Link(path string, link string) (err error)
   484 //sys	Link(path string, link string) (err error)
   469 //sys	Undelete(path string) (err error)
   523 //sys	Undelete(path string) (err error)
   470 //sys	Unlink(path string) (err error)
   524 //sys	Unlink(path string) (err error)
   471 //sys	Unlinkat(dirfd int, path string, flags int) (err error)
   525 //sys	Unlinkat(dirfd int, path string, flags int) (err error)
   472 //sys	Unmount(path string, flags int) (err error)
   526 //sys	Unmount(path string, flags int) (err error)
   473 //sys	write(fd int, p []byte) (n int, err error)
   527 //sys	write(fd int, p []byte) (n int, err error)
   474 //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
   528 //sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
   475 //sys   munmap(addr uintptr, length uintptr) (err error)
   529 //sys	munmap(addr uintptr, length uintptr) (err error)
   476 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
   530 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
   477 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
   531 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
   478 
   532 
   479 /*
   533 /*
   480  * Unimplemented
   534  * Unimplemented