syscall_bsd.go 16 KB

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