srpc_nacl.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. // Copyright 2013 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. // Native Client SRPC message passing.
  5. // This code is needed to invoke SecureRandom, the NaCl equivalent of /dev/random.
  6. package unix
  7. import (
  8. "errors"
  9. "sync"
  10. "unsafe"
  11. )
  12. // An srpcClient represents the client side of an SRPC connection.
  13. type srpcClient struct {
  14. fd int // to server
  15. r msgReceiver
  16. s msgSender
  17. service map[string]srpcService // services by name
  18. outMu sync.Mutex // protects writing to connection
  19. mu sync.Mutex // protects following fields
  20. muxer bool // is someone reading and muxing responses
  21. pending map[uint32]*srpc
  22. idGen uint32 // generator for request IDs
  23. }
  24. // An srpcService is a single method that the server offers.
  25. type srpcService struct {
  26. num uint32 // method number
  27. fmt string // argument format; see "parsing of RPC messages" below
  28. }
  29. // An srpc represents a single srpc issued by a client.
  30. type srpc struct {
  31. Ret []interface{}
  32. Done chan *srpc
  33. Err error
  34. c *srpcClient
  35. id uint32
  36. }
  37. // newClient allocates a new SRPC client using the file descriptor fd.
  38. func newClient(fd int) (*srpcClient, error) {
  39. c := new(srpcClient)
  40. c.fd = fd
  41. c.r.fd = fd
  42. c.s.fd = fd
  43. c.service = make(map[string]srpcService)
  44. c.pending = make(map[uint32]*srpc)
  45. // service discovery request
  46. m := &msg{
  47. isRequest: 1,
  48. template: []interface{}{[]byte(nil)},
  49. size: []int{4000}, // max size to accept for returned byte slice
  50. }
  51. if err := m.pack(); err != nil {
  52. return nil, errors.New("Native Client SRPC service_discovery: preparing request: " + err.Error())
  53. }
  54. c.s.send(m)
  55. m, err := c.r.recv()
  56. if err != nil {
  57. return nil, err
  58. }
  59. m.unpack()
  60. if m.status != uint32(srpcOK) {
  61. return nil, errors.New("Native Client SRPC service_discovery: " + srpcErrno(m.status).Error())
  62. }
  63. list := m.value[0].([]byte)
  64. var n uint32
  65. for len(list) > 0 {
  66. var line []byte
  67. i := byteIndex(list, '\n')
  68. if i < 0 {
  69. line, list = list, nil
  70. } else {
  71. line, list = list[:i], list[i+1:]
  72. }
  73. i = byteIndex(line, ':')
  74. if i >= 0 {
  75. c.service[string(line)] = srpcService{n, string(line[i+1:])}
  76. }
  77. n++
  78. }
  79. return c, nil
  80. }
  81. func byteIndex(b []byte, c byte) int {
  82. for i, bi := range b {
  83. if bi == c {
  84. return i
  85. }
  86. }
  87. return -1
  88. }
  89. var yourTurn srpc
  90. func (c *srpcClient) wait(r *srpc) {
  91. var rx *srpc
  92. for rx = range r.Done {
  93. if rx != &yourTurn {
  94. break
  95. }
  96. c.input()
  97. }
  98. return
  99. }
  100. func (c *srpcClient) input() {
  101. // read message
  102. m, err := c.r.recv()
  103. if err != nil {
  104. println("Native Client SRPC receive error:", err.Error())
  105. return
  106. }
  107. if m.unpack(); m.status != uint32(srpcOK) {
  108. println("Native Client SRPC receive error: invalid message: ", srpcErrno(m.status).Error())
  109. return
  110. }
  111. // deliver to intended recipient
  112. c.mu.Lock()
  113. rpc, ok := c.pending[m.id]
  114. if ok {
  115. delete(c.pending, m.id)
  116. }
  117. // wake a new muxer if there are more RPCs to read
  118. c.muxer = false
  119. for _, rpc := range c.pending {
  120. c.muxer = true
  121. rpc.Done <- &yourTurn
  122. break
  123. }
  124. c.mu.Unlock()
  125. if !ok {
  126. println("Native Client: unexpected response for ID", m.id)
  127. return
  128. }
  129. rpc.Ret = m.value
  130. rpc.Done <- rpc
  131. }
  132. // Wait blocks until the RPC has finished.
  133. func (r *srpc) Wait() {
  134. r.c.wait(r)
  135. }
  136. // Start issues an RPC request for method name with the given arguments.
  137. // The RPC r must not be in use for another pending request.
  138. // To wait for the RPC to finish, receive from r.Done and then
  139. // inspect r.Ret and r.Errno.
  140. func (r *srpc) Start(name string, arg []interface{}) {
  141. r.Err = nil
  142. r.c.mu.Lock()
  143. srv, ok := r.c.service[name]
  144. if !ok {
  145. r.c.mu.Unlock()
  146. r.Err = srpcErrBadRPCNumber
  147. r.Done <- r
  148. return
  149. }
  150. r.c.pending[r.id] = r
  151. if !r.c.muxer {
  152. r.c.muxer = true
  153. r.Done <- &yourTurn
  154. }
  155. r.c.mu.Unlock()
  156. var m msg
  157. m.id = r.id
  158. m.isRequest = 1
  159. m.rpc = srv.num
  160. m.value = arg
  161. // Fill in the return values and sizes to generate
  162. // the right type chars. We'll take most any size.
  163. // Skip over input arguments.
  164. // We could check them against arg, but the server
  165. // will do that anyway.
  166. i := 0
  167. for srv.fmt[i] != ':' {
  168. i++
  169. }
  170. format := srv.fmt[i+1:]
  171. // Now the return prototypes.
  172. m.template = make([]interface{}, len(format))
  173. m.size = make([]int, len(format))
  174. for i := 0; i < len(format); i++ {
  175. switch format[i] {
  176. default:
  177. println("Native Client SRPC: unexpected service type " + string(format[i]))
  178. r.Err = srpcErrBadRPCNumber
  179. r.Done <- r
  180. return
  181. case 'b':
  182. m.template[i] = false
  183. case 'C':
  184. m.template[i] = []byte(nil)
  185. m.size[i] = 1 << 30
  186. case 'd':
  187. m.template[i] = float64(0)
  188. case 'D':
  189. m.template[i] = []float64(nil)
  190. m.size[i] = 1 << 30
  191. case 'h':
  192. m.template[i] = int(-1)
  193. case 'i':
  194. m.template[i] = int32(0)
  195. case 'I':
  196. m.template[i] = []int32(nil)
  197. m.size[i] = 1 << 30
  198. case 's':
  199. m.template[i] = ""
  200. m.size[i] = 1 << 30
  201. }
  202. }
  203. if err := m.pack(); err != nil {
  204. r.Err = errors.New("Native Client RPC Start " + name + ": preparing request: " + err.Error())
  205. r.Done <- r
  206. return
  207. }
  208. r.c.outMu.Lock()
  209. r.c.s.send(&m)
  210. r.c.outMu.Unlock()
  211. }
  212. // Call is a convenience wrapper that starts the RPC request,
  213. // waits for it to finish, and then returns the results.
  214. // Its implementation is:
  215. //
  216. // r.Start(name, arg)
  217. // r.Wait()
  218. // return r.Ret, r.Errno
  219. //
  220. func (c *srpcClient) Call(name string, arg ...interface{}) (ret []interface{}, err error) {
  221. r := c.NewRPC(nil)
  222. r.Start(name, arg)
  223. r.Wait()
  224. return r.Ret, r.Err
  225. }
  226. // NewRPC creates a new RPC on the client connection.
  227. func (c *srpcClient) NewRPC(done chan *srpc) *srpc {
  228. if done == nil {
  229. done = make(chan *srpc, 1)
  230. }
  231. c.mu.Lock()
  232. id := c.idGen
  233. c.idGen++
  234. c.mu.Unlock()
  235. return &srpc{Done: done, c: c, id: id}
  236. }
  237. // The current protocol number.
  238. // Kind of useless, since there have been backwards-incompatible changes
  239. // to the wire protocol that did not update the protocol number.
  240. // At this point it's really just a sanity check.
  241. const protocol = 0xc0da0002
  242. // An srpcErrno is an SRPC status code.
  243. type srpcErrno uint32
  244. const (
  245. srpcOK srpcErrno = 256 + iota
  246. srpcErrBreak
  247. srpcErrMessageTruncated
  248. srpcErrNoMemory
  249. srpcErrProtocolMismatch
  250. srpcErrBadRPCNumber
  251. srpcErrBadArgType
  252. srpcErrTooFewArgs
  253. srpcErrTooManyArgs
  254. srpcErrInArgTypeMismatch
  255. srpcErrOutArgTypeMismatch
  256. srpcErrInternalError
  257. srpcErrAppError
  258. )
  259. var srpcErrstr = [...]string{
  260. srpcOK - srpcOK: "ok",
  261. srpcErrBreak - srpcOK: "break",
  262. srpcErrMessageTruncated - srpcOK: "message truncated",
  263. srpcErrNoMemory - srpcOK: "out of memory",
  264. srpcErrProtocolMismatch - srpcOK: "protocol mismatch",
  265. srpcErrBadRPCNumber - srpcOK: "invalid RPC method number",
  266. srpcErrBadArgType - srpcOK: "unexpected argument type",
  267. srpcErrTooFewArgs - srpcOK: "too few arguments",
  268. srpcErrTooManyArgs - srpcOK: "too many arguments",
  269. srpcErrInArgTypeMismatch - srpcOK: "input argument type mismatch",
  270. srpcErrOutArgTypeMismatch - srpcOK: "output argument type mismatch",
  271. srpcErrInternalError - srpcOK: "internal error",
  272. srpcErrAppError - srpcOK: "application error",
  273. }
  274. func (e srpcErrno) Error() string {
  275. if e < srpcOK || int(e-srpcOK) >= len(srpcErrstr) {
  276. return "srpcErrno(" + itoa(int(e)) + ")"
  277. }
  278. return srpcErrstr[e-srpcOK]
  279. }
  280. // A msgHdr is the data argument to the imc_recvmsg
  281. // and imc_sendmsg system calls.
  282. type msgHdr struct {
  283. iov *iov
  284. niov int32
  285. desc *int32
  286. ndesc int32
  287. flags uint32
  288. }
  289. // A single region for I/O.
  290. type iov struct {
  291. base *byte
  292. len int32
  293. }
  294. const maxMsgSize = 1<<16 - 4*4
  295. // A msgReceiver receives messages from a file descriptor.
  296. type msgReceiver struct {
  297. fd int
  298. data [maxMsgSize]byte
  299. desc [8]int32
  300. hdr msgHdr
  301. iov iov
  302. }
  303. func (r *msgReceiver) recv() (*msg, error) {
  304. // Init pointers to buffers where syscall recvmsg can write.
  305. r.iov.base = &r.data[0]
  306. r.iov.len = int32(len(r.data))
  307. r.hdr.iov = &r.iov
  308. r.hdr.niov = 1
  309. r.hdr.desc = &r.desc[0]
  310. r.hdr.ndesc = int32(len(r.desc))
  311. n, _, e := Syscall(sys_imc_recvmsg, uintptr(r.fd), uintptr(unsafe.Pointer(&r.hdr)), 0)
  312. if e != 0 {
  313. println("Native Client imc_recvmsg: ", e.Error())
  314. return nil, e
  315. }
  316. // Make a copy of the data so that the next recvmsg doesn't
  317. // smash it. The system call did not update r.iov.len. Instead it
  318. // returned the total byte count as n.
  319. m := new(msg)
  320. m.data = make([]byte, n)
  321. copy(m.data, r.data[0:])
  322. // Make a copy of the desc too.
  323. // The system call *did* update r.hdr.ndesc.
  324. if r.hdr.ndesc > 0 {
  325. m.desc = make([]int32, r.hdr.ndesc)
  326. copy(m.desc, r.desc[:])
  327. }
  328. return m, nil
  329. }
  330. // A msgSender sends messages on a file descriptor.
  331. type msgSender struct {
  332. fd int
  333. hdr msgHdr
  334. iov iov
  335. }
  336. func (s *msgSender) send(m *msg) error {
  337. if len(m.data) > 0 {
  338. s.iov.base = &m.data[0]
  339. }
  340. s.iov.len = int32(len(m.data))
  341. s.hdr.iov = &s.iov
  342. s.hdr.niov = 1
  343. s.hdr.desc = nil
  344. s.hdr.ndesc = 0
  345. _, _, e := Syscall(sys_imc_sendmsg, uintptr(s.fd), uintptr(unsafe.Pointer(&s.hdr)), 0)
  346. if e != 0 {
  347. println("Native Client imc_sendmsg: ", e.Error())
  348. return e
  349. }
  350. return nil
  351. }
  352. // A msg is the Go representation of an SRPC message.
  353. type msg struct {
  354. data []byte // message data
  355. desc []int32 // message file descriptors
  356. // parsed version of message
  357. id uint32
  358. isRequest uint32
  359. rpc uint32
  360. status uint32
  361. value []interface{}
  362. template []interface{}
  363. size []int
  364. format string
  365. broken bool
  366. }
  367. // reading from a msg
  368. func (m *msg) uint32() uint32 {
  369. if m.broken {
  370. return 0
  371. }
  372. if len(m.data) < 4 {
  373. m.broken = true
  374. return 0
  375. }
  376. b := m.data[:4]
  377. x := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
  378. m.data = m.data[4:]
  379. return x
  380. }
  381. func (m *msg) uint64() uint64 {
  382. x := uint64(m.uint32()) | uint64(m.uint32())<<32
  383. if m.broken {
  384. return 0
  385. }
  386. return x
  387. }
  388. func (m *msg) bytes(n int) []byte {
  389. if m.broken {
  390. return nil
  391. }
  392. if len(m.data) < n {
  393. m.broken = true
  394. return nil
  395. }
  396. x := m.data[0:n]
  397. m.data = m.data[n:]
  398. return x
  399. }
  400. // writing to a msg
  401. func (m *msg) wuint32(x uint32) {
  402. m.data = append(m.data, byte(x), byte(x>>8), byte(x>>16), byte(x>>24))
  403. }
  404. func (m *msg) wuint64(x uint64) {
  405. lo := uint32(x)
  406. hi := uint32(x >> 32)
  407. m.data = append(m.data, byte(lo), byte(lo>>8), byte(lo>>16), byte(lo>>24), byte(hi), byte(hi>>8), byte(hi>>16), byte(hi>>24))
  408. }
  409. func (m *msg) wbytes(p []byte) {
  410. m.data = append(m.data, p...)
  411. }
  412. func (m *msg) wstring(s string) {
  413. m.data = append(m.data, s...)
  414. }
  415. // Parsing of RPC messages.
  416. //
  417. // Each message begins with
  418. // total_size uint32
  419. // total_descs uint32
  420. // fragment_size uint32
  421. // fragment_descs uint32
  422. //
  423. // If fragment_size < total_size or fragment_descs < total_descs, the actual
  424. // message is broken up in multiple messages; follow-up messages omit
  425. // the "total" fields and begin with the "fragment" fields.
  426. // We do not support putting fragmented messages back together.
  427. // To do this we would need to change the message receiver.
  428. //
  429. // After that size information, the message header follows:
  430. // protocol uint32
  431. // requestID uint32
  432. // isRequest uint32
  433. // rpcNumber uint32
  434. // status uint32
  435. // numValue uint32
  436. // numTemplate uint32
  437. //
  438. // After the header come numTemplate fixed-size arguments,
  439. // numValue fixed-size arguments, and then the variable-sized
  440. // part of the values. The templates describe the expected results
  441. // and have no associated variable sized data in the request.
  442. //
  443. // Each fixed-size argument has the form:
  444. // tag uint32 // really a char, like 'b' or 'C'
  445. // pad uint32 // unused
  446. // val1 uint32
  447. // val2 uint32
  448. //
  449. // The tags are:
  450. // 'b': bool; val1 == 0 or 1
  451. // 'C': []byte; val1 == len, data in variable-sized section
  452. // 'd': float64; (val1, val2) is data
  453. // 'D': []float64; val1 == len, data in variable-sized section
  454. // 'h': int; val1 == file descriptor
  455. // 'i': int32; descriptor in next entry in m.desc
  456. // 'I': []int; val1 == len, data in variable-sized section
  457. // 's': string; val1 == len, data in variable-sized section
  458. //
  459. func (m *msg) pack() error {
  460. m.data = m.data[:0]
  461. m.desc = m.desc[:0]
  462. // sizes, to fill in later
  463. m.wuint32(0)
  464. m.wuint32(0)
  465. m.wuint32(0)
  466. m.wuint32(0)
  467. // message header
  468. m.wuint32(protocol)
  469. m.wuint32(m.id)
  470. m.wuint32(m.isRequest)
  471. m.wuint32(m.rpc)
  472. m.wuint32(m.status)
  473. m.wuint32(uint32(len(m.value)))
  474. m.wuint32(uint32(len(m.template)))
  475. // fixed-size templates
  476. for i, x := range m.template {
  477. var tag, val1, val2 uint32
  478. switch x.(type) {
  479. default:
  480. return errors.New("unexpected template type")
  481. case bool:
  482. tag = 'b'
  483. case []byte:
  484. tag = 'C'
  485. val1 = uint32(m.size[i])
  486. case float64:
  487. tag = 'd'
  488. case []float64:
  489. tag = 'D'
  490. val1 = uint32(m.size[i])
  491. case int:
  492. tag = 'h'
  493. case int32:
  494. tag = 'i'
  495. case []int32:
  496. tag = 'I'
  497. val1 = uint32(m.size[i])
  498. case string:
  499. tag = 's'
  500. val1 = uint32(m.size[i])
  501. }
  502. m.wuint32(tag)
  503. m.wuint32(0)
  504. m.wuint32(val1)
  505. m.wuint32(val2)
  506. }
  507. // fixed-size values
  508. for _, x := range m.value {
  509. var tag, val1, val2 uint32
  510. switch x := x.(type) {
  511. default:
  512. return errors.New("unexpected value type")
  513. case bool:
  514. tag = 'b'
  515. if x {
  516. val1 = 1
  517. }
  518. case []byte:
  519. tag = 'C'
  520. val1 = uint32(len(x))
  521. case float64:
  522. tag = 'd'
  523. v := float64bits(x)
  524. val1 = uint32(v)
  525. val2 = uint32(v >> 32)
  526. case []float64:
  527. tag = 'D'
  528. val1 = uint32(len(x))
  529. case int32:
  530. tag = 'i'
  531. m.desc = append(m.desc, x)
  532. case []int32:
  533. tag = 'I'
  534. val1 = uint32(len(x))
  535. case string:
  536. tag = 's'
  537. val1 = uint32(len(x) + 1)
  538. }
  539. m.wuint32(tag)
  540. m.wuint32(0)
  541. m.wuint32(val1)
  542. m.wuint32(val2)
  543. }
  544. // variable-length data for values
  545. for _, x := range m.value {
  546. switch x := x.(type) {
  547. case []byte:
  548. m.wbytes(x)
  549. case []float64:
  550. for _, f := range x {
  551. m.wuint64(float64bits(f))
  552. }
  553. case []int32:
  554. for _, j := range x {
  555. m.wuint32(uint32(j))
  556. }
  557. case string:
  558. m.wstring(x)
  559. m.wstring("\x00")
  560. }
  561. }
  562. // fill in sizes
  563. data := m.data
  564. m.data = m.data[:0]
  565. m.wuint32(uint32(len(data)))
  566. m.wuint32(uint32(len(m.desc)))
  567. m.wuint32(uint32(len(data)))
  568. m.wuint32(uint32(len(m.desc)))
  569. m.data = data
  570. return nil
  571. }
  572. func (m *msg) unpack() error {
  573. totalSize := m.uint32()
  574. totalDesc := m.uint32()
  575. fragSize := m.uint32()
  576. fragDesc := m.uint32()
  577. if totalSize != fragSize || totalDesc != fragDesc {
  578. return errors.New("Native Client: fragmented RPC messages not supported")
  579. }
  580. if m.uint32() != protocol {
  581. return errors.New("Native Client: RPC protocol mismatch")
  582. }
  583. // message header
  584. m.id = m.uint32()
  585. m.isRequest = m.uint32()
  586. m.rpc = m.uint32()
  587. m.status = m.uint32()
  588. m.value = make([]interface{}, m.uint32())
  589. m.template = make([]interface{}, m.uint32())
  590. m.size = make([]int, len(m.template))
  591. if m.broken {
  592. return errors.New("Native Client: malformed message")
  593. }
  594. // fixed-size templates
  595. for i := range m.template {
  596. tag := m.uint32()
  597. m.uint32() // padding
  598. val1 := m.uint32()
  599. m.uint32() // val2
  600. switch tag {
  601. default:
  602. return errors.New("Native Client: unexpected template type " + string(rune(tag)))
  603. case 'b':
  604. m.template[i] = false
  605. case 'C':
  606. m.template[i] = []byte(nil)
  607. m.size[i] = int(val1)
  608. case 'd':
  609. m.template[i] = float64(0)
  610. case 'D':
  611. m.template[i] = []float64(nil)
  612. m.size[i] = int(val1)
  613. case 'i':
  614. m.template[i] = int32(0)
  615. case 'I':
  616. m.template[i] = []int32(nil)
  617. m.size[i] = int(val1)
  618. case 'h':
  619. m.template[i] = int(0)
  620. case 's':
  621. m.template[i] = ""
  622. m.size[i] = int(val1)
  623. }
  624. }
  625. // fixed-size values
  626. var (
  627. strsize []uint32
  628. d int
  629. )
  630. for i := range m.value {
  631. tag := m.uint32()
  632. m.uint32() // padding
  633. val1 := m.uint32()
  634. val2 := m.uint32()
  635. switch tag {
  636. default:
  637. return errors.New("Native Client: unexpected value type " + string(rune(tag)))
  638. case 'b':
  639. m.value[i] = val1 > 0
  640. case 'C':
  641. m.value[i] = []byte(nil)
  642. strsize = append(strsize, val1)
  643. case 'd':
  644. m.value[i] = float64frombits(uint64(val1) | uint64(val2)<<32)
  645. case 'D':
  646. m.value[i] = make([]float64, val1)
  647. case 'i':
  648. m.value[i] = int32(val1)
  649. case 'I':
  650. m.value[i] = make([]int32, val1)
  651. case 'h':
  652. m.value[i] = int(m.desc[d])
  653. d++
  654. case 's':
  655. m.value[i] = ""
  656. strsize = append(strsize, val1)
  657. }
  658. }
  659. // variable-sized parts of values
  660. for i, x := range m.value {
  661. switch x := x.(type) {
  662. case []byte:
  663. m.value[i] = m.bytes(int(strsize[0]))
  664. strsize = strsize[1:]
  665. case []float64:
  666. for i := range x {
  667. x[i] = float64frombits(m.uint64())
  668. }
  669. case []int32:
  670. for i := range x {
  671. x[i] = int32(m.uint32())
  672. }
  673. case string:
  674. m.value[i] = string(m.bytes(int(strsize[0])))
  675. strsize = strsize[1:]
  676. }
  677. }
  678. if len(m.data) > 0 {
  679. return errors.New("Native Client: junk at end of message")
  680. }
  681. return nil
  682. }
  683. func float64bits(x float64) uint64 {
  684. return *(*uint64)(unsafe.Pointer(&x))
  685. }
  686. func float64frombits(x uint64) float64 {
  687. return *(*float64)(unsafe.Pointer(&x))
  688. }
  689. // At startup, connect to the name service.
  690. var nsClient = nsConnect()
  691. func nsConnect() *srpcClient {
  692. var ns int32 = -1
  693. _, _, errno := Syscall(sys_nameservice, uintptr(unsafe.Pointer(&ns)), 0, 0)
  694. if errno != 0 {
  695. println("Native Client nameservice:", errno.Error())
  696. return nil
  697. }
  698. sock, _, errno := Syscall(sys_imc_connect, uintptr(ns), 0, 0)
  699. if errno != 0 {
  700. println("Native Client nameservice connect:", errno.Error())
  701. return nil
  702. }
  703. c, err := newClient(int(sock))
  704. if err != nil {
  705. println("Native Client nameservice init:", err.Error())
  706. return nil
  707. }
  708. return c
  709. }
  710. const (
  711. nsSuccess = 0
  712. nsNameNotFound = 1
  713. nsDuplicateName = 2
  714. nsInsufficientResources = 3
  715. nsPermissionDenied = 4
  716. nsInvalidArgument = 5
  717. )
  718. func openNamedService(name string, mode int32) (fd int, err error) {
  719. if nsClient == nil {
  720. return 0, errors.New("no name service")
  721. }
  722. ret, err := nsClient.Call("lookup:si:ih", name, int32(mode))
  723. if err != nil {
  724. return 0, err
  725. }
  726. status := ret[0].(int32)
  727. fd = ret[1].(int)
  728. switch status {
  729. case nsSuccess:
  730. // ok
  731. case nsNameNotFound:
  732. return -1, ENOENT
  733. case nsDuplicateName:
  734. return -1, EEXIST
  735. case nsInsufficientResources:
  736. return -1, EWOULDBLOCK
  737. case nsPermissionDenied:
  738. return -1, EPERM
  739. case nsInvalidArgument:
  740. return -1, EINVAL
  741. default:
  742. return -1, EINVAL
  743. }
  744. return fd, nil
  745. }