syscall_bsd.go 16 KB

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