You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

625 lines
15 KiB

  1. // Copyright 2009 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. //go:build darwin || dragonfly || freebsd || netbsd || openbsd
  5. // +build darwin dragonfly freebsd netbsd openbsd
  6. // BSD system call wrappers shared by *BSD based systems
  7. // including OS X (Darwin) and FreeBSD. Like the other
  8. // syscall_*.go files it is compiled as Go code but also
  9. // used as input to mksyscall which parses the //sys
  10. // lines and generates system call stubs.
  11. package unix
  12. import (
  13. "runtime"
  14. "syscall"
  15. "unsafe"
  16. )
  17. const ImplementsGetwd = true
  18. func Getwd() (string, error) {
  19. var buf [PathMax]byte
  20. _, err := Getcwd(buf[0:])
  21. if err != nil {
  22. return "", err
  23. }
  24. n := clen(buf[:])
  25. if n < 1 {
  26. return "", EINVAL
  27. }
  28. return string(buf[:n]), nil
  29. }
  30. /*
  31. * Wrapped
  32. */
  33. //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
  34. //sysnb setgroups(ngid int, gid *_Gid_t) (err error)
  35. func Getgroups() (gids []int, err error) {
  36. n, err := getgroups(0, nil)
  37. if err != nil {
  38. return nil, err
  39. }
  40. if n == 0 {
  41. return nil, nil
  42. }
  43. // Sanity check group count. Max is 16 on BSD.
  44. if n < 0 || n > 1000 {
  45. return nil, EINVAL
  46. }
  47. a := make([]_Gid_t, n)
  48. n, err = getgroups(n, &a[0])
  49. if err != nil {
  50. return nil, err
  51. }
  52. gids = make([]int, n)
  53. for i, v := range a[0:n] {
  54. gids[i] = int(v)
  55. }
  56. return
  57. }
  58. func Setgroups(gids []int) (err error) {
  59. if len(gids) == 0 {
  60. return setgroups(0, nil)
  61. }
  62. a := make([]_Gid_t, len(gids))
  63. for i, v := range gids {
  64. a[i] = _Gid_t(v)
  65. }
  66. return setgroups(len(a), &a[0])
  67. }
  68. // Wait status is 7 bits at bottom, either 0 (exited),
  69. // 0x7F (stopped), or a signal number that caused an exit.
  70. // The 0x80 bit is whether there was a core dump.
  71. // An extra number (exit code, signal causing a stop)
  72. // is in the high bits.
  73. type WaitStatus uint32
  74. const (
  75. mask = 0x7F
  76. core = 0x80
  77. shift = 8
  78. exited = 0
  79. killed = 9
  80. stopped = 0x7F
  81. )
  82. func (w WaitStatus) Exited() bool { return w&mask == exited }
  83. func (w WaitStatus) ExitStatus() int {
  84. if w&mask != exited {
  85. return -1
  86. }
  87. return int(w >> shift)
  88. }
  89. func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
  90. func (w WaitStatus) Signal() syscall.Signal {
  91. sig := syscall.Signal(w & mask)
  92. if sig == stopped || sig == 0 {
  93. return -1
  94. }
  95. return sig
  96. }
  97. func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
  98. func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }
  99. func (w WaitStatus) Killed() bool { return w&mask == killed && syscall.Signal(w>>shift) != SIGKILL }
  100. func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }
  101. func (w WaitStatus) StopSignal() syscall.Signal {
  102. if !w.Stopped() {
  103. return -1
  104. }
  105. return syscall.Signal(w>>shift) & 0xFF
  106. }
  107. func (w WaitStatus) TrapCause() int { return -1 }
  108. //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
  109. func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  110. var status _C_int
  111. wpid, err = wait4(pid, &status, options, rusage)
  112. if wstatus != nil {
  113. *wstatus = WaitStatus(status)
  114. }
  115. return
  116. }
  117. //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
  118. //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
  119. //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
  120. //sysnb socket(domain int, typ int, proto int) (fd int, err error)
  121. //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
  122. //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
  123. //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
  124. //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
  125. //sys Shutdown(s int, how int) (err error)
  126. func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
  127. if sa.Port < 0 || sa.Port > 0xFFFF {
  128. return nil, 0, EINVAL
  129. }
  130. sa.raw.Len = SizeofSockaddrInet4
  131. sa.raw.Family = AF_INET
  132. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  133. p[0] = byte(sa.Port >> 8)
  134. p[1] = byte(sa.Port)
  135. sa.raw.Addr = sa.Addr
  136. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  137. }
  138. func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
  139. if sa.Port < 0 || sa.Port > 0xFFFF {
  140. return nil, 0, EINVAL
  141. }
  142. sa.raw.Len = SizeofSockaddrInet6
  143. sa.raw.Family = AF_INET6
  144. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  145. p[0] = byte(sa.Port >> 8)
  146. p[1] = byte(sa.Port)
  147. sa.raw.Scope_id = sa.ZoneId
  148. sa.raw.Addr = sa.Addr
  149. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  150. }
  151. func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
  152. name := sa.Name
  153. n := len(name)
  154. if n >= len(sa.raw.Path) || n == 0 {
  155. return nil, 0, EINVAL
  156. }
  157. sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
  158. sa.raw.Family = AF_UNIX
  159. for i := 0; i < n; i++ {
  160. sa.raw.Path[i] = int8(name[i])
  161. }
  162. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  163. }
  164. func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
  165. if sa.Index == 0 {
  166. return nil, 0, EINVAL
  167. }
  168. sa.raw.Len = sa.Len
  169. sa.raw.Family = AF_LINK
  170. sa.raw.Index = sa.Index
  171. sa.raw.Type = sa.Type
  172. sa.raw.Nlen = sa.Nlen
  173. sa.raw.Alen = sa.Alen
  174. sa.raw.Slen = sa.Slen
  175. sa.raw.Data = sa.Data
  176. return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
  177. }
  178. func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
  179. switch rsa.Addr.Family {
  180. case AF_LINK:
  181. pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
  182. sa := new(SockaddrDatalink)
  183. sa.Len = pp.Len
  184. sa.Family = pp.Family
  185. sa.Index = pp.Index
  186. sa.Type = pp.Type
  187. sa.Nlen = pp.Nlen
  188. sa.Alen = pp.Alen
  189. sa.Slen = pp.Slen
  190. sa.Data = pp.Data
  191. return sa, nil
  192. case AF_UNIX:
  193. pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
  194. if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
  195. return nil, EINVAL
  196. }
  197. sa := new(SockaddrUnix)
  198. // Some BSDs include the trailing NUL in the length, whereas
  199. // others do not. Work around this by subtracting the leading
  200. // family and len. The path is then scanned to see if a NUL
  201. // terminator still exists within the length.
  202. n := int(pp.Len) - 2 // subtract leading Family, Len
  203. for i := 0; i < n; i++ {
  204. if pp.Path[i] == 0 {
  205. // found early NUL; assume Len included the NUL
  206. // or was overestimating.
  207. n = i
  208. break
  209. }
  210. }
  211. sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
  212. return sa, nil
  213. case AF_INET:
  214. pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
  215. sa := new(SockaddrInet4)
  216. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  217. sa.Port = int(p[0])<<8 + int(p[1])
  218. sa.Addr = pp.Addr
  219. return sa, nil
  220. case AF_INET6:
  221. pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
  222. sa := new(SockaddrInet6)
  223. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  224. sa.Port = int(p[0])<<8 + int(p[1])
  225. sa.ZoneId = pp.Scope_id
  226. sa.Addr = pp.Addr
  227. return sa, nil
  228. }
  229. return anyToSockaddrGOOS(fd, rsa)
  230. }
  231. func Accept(fd int) (nfd int, sa Sockaddr, err error) {
  232. var rsa RawSockaddrAny
  233. var len _Socklen = SizeofSockaddrAny
  234. nfd, err = accept(fd, &rsa, &len)
  235. if err != nil {
  236. return
  237. }
  238. if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 {
  239. // Accepted socket has no address.
  240. // This is likely due to a bug in xnu kernels,
  241. // where instead of ECONNABORTED error socket
  242. // is accepted, but has no address.
  243. Close(nfd)
  244. return 0, nil, ECONNABORTED
  245. }
  246. sa, err = anyToSockaddr(fd, &rsa)
  247. if err != nil {
  248. Close(nfd)
  249. nfd = 0
  250. }
  251. return
  252. }
  253. func Getsockname(fd int) (sa Sockaddr, err error) {
  254. var rsa RawSockaddrAny
  255. var len _Socklen = SizeofSockaddrAny
  256. if err = getsockname(fd, &rsa, &len); err != nil {
  257. return
  258. }
  259. // TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
  260. // reported upstream.
  261. if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
  262. rsa.Addr.Family = AF_UNIX
  263. rsa.Addr.Len = SizeofSockaddrUnix
  264. }
  265. return anyToSockaddr(fd, &rsa)
  266. }
  267. //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
  268. // GetsockoptString returns the string value of the socket option opt for the
  269. // socket associated with fd at the given socket level.
  270. func GetsockoptString(fd, level, opt int) (string, error) {
  271. buf := make([]byte, 256)
  272. vallen := _Socklen(len(buf))
  273. err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
  274. if err != nil {
  275. return "", err
  276. }
  277. return string(buf[:vallen-1]), nil
  278. }
  279. //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
  280. //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
  281. //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
  282. func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
  283. var msg Msghdr
  284. msg.Name = (*byte)(unsafe.Pointer(rsa))
  285. msg.Namelen = uint32(SizeofSockaddrAny)
  286. var dummy byte
  287. if len(oob) > 0 {
  288. // receive at least one normal byte
  289. if emptyIovecs(iov) {
  290. var iova [1]Iovec
  291. iova[0].Base = &dummy
  292. iova[0].SetLen(1)
  293. iov = iova[:]
  294. }
  295. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  296. msg.SetControllen(len(oob))
  297. }
  298. if len(iov) > 0 {
  299. msg.Iov = &iov[0]
  300. msg.SetIovlen(len(iov))
  301. }
  302. if n, err = recvmsg(fd, &msg, flags); err != nil {
  303. return
  304. }
  305. oobn = int(msg.Controllen)
  306. recvflags = int(msg.Flags)
  307. return
  308. }
  309. //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
  310. func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
  311. var msg Msghdr
  312. msg.Name = (*byte)(unsafe.Pointer(ptr))
  313. msg.Namelen = uint32(salen)
  314. var dummy byte
  315. var empty bool
  316. if len(oob) > 0 {
  317. // send at least one normal byte
  318. empty = emptyIovecs(iov)
  319. if empty {
  320. var iova [1]Iovec
  321. iova[0].Base = &dummy
  322. iova[0].SetLen(1)
  323. iov = iova[:]
  324. }
  325. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  326. msg.SetControllen(len(oob))
  327. }
  328. if len(iov) > 0 {
  329. msg.Iov = &iov[0]
  330. msg.SetIovlen(len(iov))
  331. }
  332. if n, err = sendmsg(fd, &msg, flags); err != nil {
  333. return 0, err
  334. }
  335. if len(oob) > 0 && empty {
  336. n = 0
  337. }
  338. return n, nil
  339. }
  340. //sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
  341. func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
  342. var change, event unsafe.Pointer
  343. if len(changes) > 0 {
  344. change = unsafe.Pointer(&changes[0])
  345. }
  346. if len(events) > 0 {
  347. event = unsafe.Pointer(&events[0])
  348. }
  349. return kevent(kq, change, len(changes), event, len(events), timeout)
  350. }
  351. // sysctlmib translates name to mib number and appends any additional args.
  352. func sysctlmib(name string, args ...int) ([]_C_int, error) {
  353. // Translate name to mib number.
  354. mib, err := nametomib(name)
  355. if err != nil {
  356. return nil, err
  357. }
  358. for _, a := range args {
  359. mib = append(mib, _C_int(a))
  360. }
  361. return mib, nil
  362. }
  363. func Sysctl(name string) (string, error) {
  364. return SysctlArgs(name)
  365. }
  366. func SysctlArgs(name string, args ...int) (string, error) {
  367. buf, err := SysctlRaw(name, args...)
  368. if err != nil {
  369. return "", err
  370. }
  371. n := len(buf)
  372. // Throw away terminating NUL.
  373. if n > 0 && buf[n-1] == '\x00' {
  374. n--
  375. }
  376. return string(buf[0:n]), nil
  377. }
  378. func SysctlUint32(name string) (uint32, error) {
  379. return SysctlUint32Args(name)
  380. }
  381. func SysctlUint32Args(name string, args ...int) (uint32, error) {
  382. mib, err := sysctlmib(name, args...)
  383. if err != nil {
  384. return 0, err
  385. }
  386. n := uintptr(4)
  387. buf := make([]byte, 4)
  388. if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
  389. return 0, err
  390. }
  391. if n != 4 {
  392. return 0, EIO
  393. }
  394. return *(*uint32)(unsafe.Pointer(&buf[0])), nil
  395. }
  396. func SysctlUint64(name string, args ...int) (uint64, error) {
  397. mib, err := sysctlmib(name, args...)
  398. if err != nil {
  399. return 0, err
  400. }
  401. n := uintptr(8)
  402. buf := make([]byte, 8)
  403. if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
  404. return 0, err
  405. }
  406. if n != 8 {
  407. return 0, EIO
  408. }
  409. return *(*uint64)(unsafe.Pointer(&buf[0])), nil
  410. }
  411. func SysctlRaw(name string, args ...int) ([]byte, error) {
  412. mib, err := sysctlmib(name, args...)
  413. if err != nil {
  414. return nil, err
  415. }
  416. // Find size.
  417. n := uintptr(0)
  418. if err := sysctl(mib, nil, &n, nil, 0); err != nil {
  419. return nil, err
  420. }
  421. if n == 0 {
  422. return nil, nil
  423. }
  424. // Read into buffer of that size.
  425. buf := make([]byte, n)
  426. if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
  427. return nil, err
  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], nil
  432. }
  433. func SysctlClockinfo(name string) (*Clockinfo, error) {
  434. mib, err := sysctlmib(name)
  435. if err != nil {
  436. return nil, err
  437. }
  438. n := uintptr(SizeofClockinfo)
  439. var ci Clockinfo
  440. if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
  441. return nil, err
  442. }
  443. if n != SizeofClockinfo {
  444. return nil, EIO
  445. }
  446. return &ci, nil
  447. }
  448. func SysctlTimeval(name string) (*Timeval, error) {
  449. mib, err := sysctlmib(name)
  450. if err != nil {
  451. return nil, err
  452. }
  453. var tv Timeval
  454. n := uintptr(unsafe.Sizeof(tv))
  455. if err := sysctl(mib, (*byte)(unsafe.Pointer(&tv)), &n, nil, 0); err != nil {
  456. return nil, err
  457. }
  458. if n != unsafe.Sizeof(tv) {
  459. return nil, EIO
  460. }
  461. return &tv, nil
  462. }
  463. //sys utimes(path string, timeval *[2]Timeval) (err error)
  464. func Utimes(path string, tv []Timeval) error {
  465. if tv == nil {
  466. return utimes(path, nil)
  467. }
  468. if len(tv) != 2 {
  469. return EINVAL
  470. }
  471. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  472. }
  473. func UtimesNano(path string, ts []Timespec) error {
  474. if ts == nil {
  475. err := utimensat(AT_FDCWD, path, nil, 0)
  476. if err != ENOSYS {
  477. return err
  478. }
  479. return utimes(path, nil)
  480. }
  481. if len(ts) != 2 {
  482. return EINVAL
  483. }
  484. err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
  485. if err != ENOSYS {
  486. return err
  487. }
  488. // Not as efficient as it could be because Timespec and
  489. // Timeval have different types in the different OSes
  490. tv := [2]Timeval{
  491. NsecToTimeval(TimespecToNsec(ts[0])),
  492. NsecToTimeval(TimespecToNsec(ts[1])),
  493. }
  494. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  495. }
  496. func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
  497. if ts == nil {
  498. return utimensat(dirfd, path, nil, flags)
  499. }
  500. if len(ts) != 2 {
  501. return EINVAL
  502. }
  503. return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
  504. }
  505. //sys futimes(fd int, timeval *[2]Timeval) (err error)
  506. func Futimes(fd int, tv []Timeval) error {
  507. if tv == nil {
  508. return futimes(fd, nil)
  509. }
  510. if len(tv) != 2 {
  511. return EINVAL
  512. }
  513. return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  514. }
  515. //sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
  516. func Poll(fds []PollFd, timeout int) (n int, err error) {
  517. if len(fds) == 0 {
  518. return poll(nil, 0, timeout)
  519. }
  520. return poll(&fds[0], len(fds), timeout)
  521. }
  522. // TODO: wrap
  523. // Acct(name nil-string) (err error)
  524. // Gethostuuid(uuid *byte, timeout *Timespec) (err error)
  525. // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
  526. var mapper = &mmapper{
  527. active: make(map[*byte][]byte),
  528. mmap: mmap,
  529. munmap: munmap,
  530. }
  531. func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  532. return mapper.Mmap(fd, offset, length, prot, flags)
  533. }
  534. func Munmap(b []byte) (err error) {
  535. return mapper.Munmap(b)
  536. }
  537. //sys Madvise(b []byte, behav int) (err error)
  538. //sys Mlock(b []byte) (err error)
  539. //sys Mlockall(flags int) (err error)
  540. //sys Mprotect(b []byte, prot int) (err error)
  541. //sys Msync(b []byte, flags int) (err error)
  542. //sys Munlock(b []byte) (err error)
  543. //sys Munlockall() (err error)