syscall_bsd.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  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. for i := 0; i < len(sa.Addr); i++ {
  136. sa.raw.Addr[i] = sa.Addr[i]
  137. }
  138. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  139. }
  140. func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
  141. if sa.Port < 0 || sa.Port > 0xFFFF {
  142. return nil, 0, EINVAL
  143. }
  144. sa.raw.Len = SizeofSockaddrInet6
  145. sa.raw.Family = AF_INET6
  146. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  147. p[0] = byte(sa.Port >> 8)
  148. p[1] = byte(sa.Port)
  149. sa.raw.Scope_id = sa.ZoneId
  150. for i := 0; i < len(sa.Addr); i++ {
  151. sa.raw.Addr[i] = sa.Addr[i]
  152. }
  153. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  154. }
  155. func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
  156. name := sa.Name
  157. n := len(name)
  158. if n >= len(sa.raw.Path) || n == 0 {
  159. return nil, 0, EINVAL
  160. }
  161. sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
  162. sa.raw.Family = AF_UNIX
  163. for i := 0; i < n; i++ {
  164. sa.raw.Path[i] = int8(name[i])
  165. }
  166. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  167. }
  168. func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
  169. if sa.Index == 0 {
  170. return nil, 0, EINVAL
  171. }
  172. sa.raw.Len = sa.Len
  173. sa.raw.Family = AF_LINK
  174. sa.raw.Index = sa.Index
  175. sa.raw.Type = sa.Type
  176. sa.raw.Nlen = sa.Nlen
  177. sa.raw.Alen = sa.Alen
  178. sa.raw.Slen = sa.Slen
  179. for i := 0; i < len(sa.raw.Data); i++ {
  180. sa.raw.Data[i] = sa.Data[i]
  181. }
  182. return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
  183. }
  184. func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
  185. switch rsa.Addr.Family {
  186. case AF_LINK:
  187. pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
  188. sa := new(SockaddrDatalink)
  189. sa.Len = pp.Len
  190. sa.Family = pp.Family
  191. sa.Index = pp.Index
  192. sa.Type = pp.Type
  193. sa.Nlen = pp.Nlen
  194. sa.Alen = pp.Alen
  195. sa.Slen = pp.Slen
  196. for i := 0; i < len(sa.Data); i++ {
  197. sa.Data[i] = pp.Data[i]
  198. }
  199. return sa, nil
  200. case AF_UNIX:
  201. pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
  202. if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
  203. return nil, EINVAL
  204. }
  205. sa := new(SockaddrUnix)
  206. // Some BSDs include the trailing NUL in the length, whereas
  207. // others do not. Work around this by subtracting the leading
  208. // family and len. The path is then scanned to see if a NUL
  209. // terminator still exists within the length.
  210. n := int(pp.Len) - 2 // subtract leading Family, Len
  211. for i := 0; i < n; i++ {
  212. if pp.Path[i] == 0 {
  213. // found early NUL; assume Len included the NUL
  214. // or was overestimating.
  215. n = i
  216. break
  217. }
  218. }
  219. bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
  220. sa.Name = string(bytes)
  221. return sa, nil
  222. case AF_INET:
  223. pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
  224. sa := new(SockaddrInet4)
  225. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  226. sa.Port = int(p[0])<<8 + int(p[1])
  227. for i := 0; i < len(sa.Addr); i++ {
  228. sa.Addr[i] = pp.Addr[i]
  229. }
  230. return sa, nil
  231. case AF_INET6:
  232. pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
  233. sa := new(SockaddrInet6)
  234. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  235. sa.Port = int(p[0])<<8 + int(p[1])
  236. sa.ZoneId = pp.Scope_id
  237. for i := 0; i < len(sa.Addr); i++ {
  238. sa.Addr[i] = pp.Addr[i]
  239. }
  240. return sa, nil
  241. }
  242. return anyToSockaddrGOOS(fd, rsa)
  243. }
  244. func Accept(fd int) (nfd int, sa Sockaddr, err error) {
  245. var rsa RawSockaddrAny
  246. var len _Socklen = SizeofSockaddrAny
  247. nfd, err = accept(fd, &rsa, &len)
  248. if err != nil {
  249. return
  250. }
  251. if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 {
  252. // Accepted socket has no address.
  253. // This is likely due to a bug in xnu kernels,
  254. // where instead of ECONNABORTED error socket
  255. // is accepted, but has no address.
  256. Close(nfd)
  257. return 0, nil, ECONNABORTED
  258. }
  259. sa, err = anyToSockaddr(fd, &rsa)
  260. if err != nil {
  261. Close(nfd)
  262. nfd = 0
  263. }
  264. return
  265. }
  266. func Getsockname(fd int) (sa Sockaddr, err error) {
  267. var rsa RawSockaddrAny
  268. var len _Socklen = SizeofSockaddrAny
  269. if err = getsockname(fd, &rsa, &len); err != nil {
  270. return
  271. }
  272. // TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
  273. // reported upstream.
  274. if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
  275. rsa.Addr.Family = AF_UNIX
  276. rsa.Addr.Len = SizeofSockaddrUnix
  277. }
  278. return anyToSockaddr(fd, &rsa)
  279. }
  280. //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
  281. // GetsockoptString returns the string value of the socket option opt for the
  282. // socket associated with fd at the given socket level.
  283. func GetsockoptString(fd, level, opt int) (string, error) {
  284. buf := make([]byte, 256)
  285. vallen := _Socklen(len(buf))
  286. err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
  287. if err != nil {
  288. return "", err
  289. }
  290. return string(buf[:vallen-1]), nil
  291. }
  292. //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
  293. //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
  294. //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
  295. func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  296. var msg Msghdr
  297. var rsa RawSockaddrAny
  298. msg.Name = (*byte)(unsafe.Pointer(&rsa))
  299. msg.Namelen = uint32(SizeofSockaddrAny)
  300. var iov Iovec
  301. if len(p) > 0 {
  302. iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  303. iov.SetLen(len(p))
  304. }
  305. var dummy byte
  306. if len(oob) > 0 {
  307. // receive at least one normal byte
  308. if len(p) == 0 {
  309. iov.Base = &dummy
  310. iov.SetLen(1)
  311. }
  312. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  313. msg.SetControllen(len(oob))
  314. }
  315. msg.Iov = &iov
  316. msg.Iovlen = 1
  317. if n, err = recvmsg(fd, &msg, flags); err != nil {
  318. return
  319. }
  320. oobn = int(msg.Controllen)
  321. recvflags = int(msg.Flags)
  322. // source address is only specified if the socket is unconnected
  323. if rsa.Addr.Family != AF_UNSPEC {
  324. from, err = anyToSockaddr(fd, &rsa)
  325. }
  326. return
  327. }
  328. //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
  329. func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
  330. _, err = SendmsgN(fd, p, oob, to, flags)
  331. return
  332. }
  333. func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
  334. var ptr unsafe.Pointer
  335. var salen _Socklen
  336. if to != nil {
  337. ptr, salen, err = to.sockaddr()
  338. if err != nil {
  339. return 0, err
  340. }
  341. }
  342. var msg Msghdr
  343. msg.Name = (*byte)(unsafe.Pointer(ptr))
  344. msg.Namelen = uint32(salen)
  345. var iov Iovec
  346. if len(p) > 0 {
  347. iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  348. iov.SetLen(len(p))
  349. }
  350. var dummy byte
  351. if len(oob) > 0 {
  352. // send at least one normal byte
  353. if len(p) == 0 {
  354. iov.Base = &dummy
  355. iov.SetLen(1)
  356. }
  357. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  358. msg.SetControllen(len(oob))
  359. }
  360. msg.Iov = &iov
  361. msg.Iovlen = 1
  362. if n, err = sendmsg(fd, &msg, flags); err != nil {
  363. return 0, err
  364. }
  365. if len(oob) > 0 && len(p) == 0 {
  366. n = 0
  367. }
  368. return n, nil
  369. }
  370. //sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
  371. func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
  372. var change, event unsafe.Pointer
  373. if len(changes) > 0 {
  374. change = unsafe.Pointer(&changes[0])
  375. }
  376. if len(events) > 0 {
  377. event = unsafe.Pointer(&events[0])
  378. }
  379. return kevent(kq, change, len(changes), event, len(events), timeout)
  380. }
  381. // sysctlmib translates name to mib number and appends any additional args.
  382. func sysctlmib(name string, args ...int) ([]_C_int, error) {
  383. // Translate name to mib number.
  384. mib, err := nametomib(name)
  385. if err != nil {
  386. return nil, err
  387. }
  388. for _, a := range args {
  389. mib = append(mib, _C_int(a))
  390. }
  391. return mib, nil
  392. }
  393. func Sysctl(name string) (string, error) {
  394. return SysctlArgs(name)
  395. }
  396. func SysctlArgs(name string, args ...int) (string, error) {
  397. buf, err := SysctlRaw(name, args...)
  398. if err != nil {
  399. return "", err
  400. }
  401. n := len(buf)
  402. // Throw away terminating NUL.
  403. if n > 0 && buf[n-1] == '\x00' {
  404. n--
  405. }
  406. return string(buf[0:n]), nil
  407. }
  408. func SysctlUint32(name string) (uint32, error) {
  409. return SysctlUint32Args(name)
  410. }
  411. func SysctlUint32Args(name string, args ...int) (uint32, error) {
  412. mib, err := sysctlmib(name, args...)
  413. if err != nil {
  414. return 0, err
  415. }
  416. n := uintptr(4)
  417. buf := make([]byte, 4)
  418. if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
  419. return 0, err
  420. }
  421. if n != 4 {
  422. return 0, EIO
  423. }
  424. return *(*uint32)(unsafe.Pointer(&buf[0])), nil
  425. }
  426. func SysctlUint64(name string, args ...int) (uint64, error) {
  427. mib, err := sysctlmib(name, args...)
  428. if err != nil {
  429. return 0, err
  430. }
  431. n := uintptr(8)
  432. buf := make([]byte, 8)
  433. if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
  434. return 0, err
  435. }
  436. if n != 8 {
  437. return 0, EIO
  438. }
  439. return *(*uint64)(unsafe.Pointer(&buf[0])), nil
  440. }
  441. func SysctlRaw(name string, args ...int) ([]byte, error) {
  442. mib, err := sysctlmib(name, args...)
  443. if err != nil {
  444. return nil, err
  445. }
  446. // Find size.
  447. n := uintptr(0)
  448. if err := sysctl(mib, nil, &n, nil, 0); err != nil {
  449. return nil, err
  450. }
  451. if n == 0 {
  452. return nil, nil
  453. }
  454. // Read into buffer of that size.
  455. buf := make([]byte, n)
  456. if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
  457. return nil, err
  458. }
  459. // The actual call may return less than the original reported required
  460. // size so ensure we deal with that.
  461. return buf[:n], nil
  462. }
  463. func SysctlClockinfo(name string) (*Clockinfo, error) {
  464. mib, err := sysctlmib(name)
  465. if err != nil {
  466. return nil, err
  467. }
  468. n := uintptr(SizeofClockinfo)
  469. var ci Clockinfo
  470. if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
  471. return nil, err
  472. }
  473. if n != SizeofClockinfo {
  474. return nil, EIO
  475. }
  476. return &ci, nil
  477. }
  478. func SysctlTimeval(name string) (*Timeval, error) {
  479. mib, err := sysctlmib(name)
  480. if err != nil {
  481. return nil, err
  482. }
  483. var tv Timeval
  484. n := uintptr(unsafe.Sizeof(tv))
  485. if err := sysctl(mib, (*byte)(unsafe.Pointer(&tv)), &n, nil, 0); err != nil {
  486. return nil, err
  487. }
  488. if n != unsafe.Sizeof(tv) {
  489. return nil, EIO
  490. }
  491. return &tv, nil
  492. }
  493. //sys utimes(path string, timeval *[2]Timeval) (err error)
  494. func Utimes(path string, tv []Timeval) error {
  495. if tv == nil {
  496. return utimes(path, nil)
  497. }
  498. if len(tv) != 2 {
  499. return EINVAL
  500. }
  501. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  502. }
  503. func UtimesNano(path string, ts []Timespec) error {
  504. if ts == nil {
  505. err := utimensat(AT_FDCWD, path, nil, 0)
  506. if err != ENOSYS {
  507. return err
  508. }
  509. return utimes(path, nil)
  510. }
  511. if len(ts) != 2 {
  512. return EINVAL
  513. }
  514. // Darwin setattrlist can set nanosecond timestamps
  515. err := setattrlistTimes(path, ts, 0)
  516. if err != ENOSYS {
  517. return err
  518. }
  519. err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
  520. if err != ENOSYS {
  521. return err
  522. }
  523. // Not as efficient as it could be because Timespec and
  524. // Timeval have different types in the different OSes
  525. tv := [2]Timeval{
  526. NsecToTimeval(TimespecToNsec(ts[0])),
  527. NsecToTimeval(TimespecToNsec(ts[1])),
  528. }
  529. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  530. }
  531. func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
  532. if ts == nil {
  533. return utimensat(dirfd, path, nil, flags)
  534. }
  535. if len(ts) != 2 {
  536. return EINVAL
  537. }
  538. err := setattrlistTimes(path, ts, flags)
  539. if err != ENOSYS {
  540. return err
  541. }
  542. return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
  543. }
  544. //sys futimes(fd int, timeval *[2]Timeval) (err error)
  545. func Futimes(fd int, tv []Timeval) error {
  546. if tv == nil {
  547. return futimes(fd, nil)
  548. }
  549. if len(tv) != 2 {
  550. return EINVAL
  551. }
  552. return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  553. }
  554. //sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
  555. func Poll(fds []PollFd, timeout int) (n int, err error) {
  556. if len(fds) == 0 {
  557. return poll(nil, 0, timeout)
  558. }
  559. return poll(&fds[0], len(fds), timeout)
  560. }
  561. // TODO: wrap
  562. // Acct(name nil-string) (err error)
  563. // Gethostuuid(uuid *byte, timeout *Timespec) (err error)
  564. // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
  565. var mapper = &mmapper{
  566. active: make(map[*byte][]byte),
  567. mmap: mmap,
  568. munmap: munmap,
  569. }
  570. func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  571. return mapper.Mmap(fd, offset, length, prot, flags)
  572. }
  573. func Munmap(b []byte) (err error) {
  574. return mapper.Munmap(b)
  575. }
  576. //sys Madvise(b []byte, behav int) (err error)
  577. //sys Mlock(b []byte) (err error)
  578. //sys Mlockall(flags int) (err error)
  579. //sys Mprotect(b []byte, prot int) (err error)
  580. //sys Msync(b []byte, flags int) (err error)
  581. //sys Munlock(b []byte) (err error)
  582. //sys Munlockall() (err error)