syscall_plan9.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // Copyright 2011 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. // Plan 9 system calls.
  5. // This file is compiled as ordinary Go code,
  6. // but it is also input to mksyscall,
  7. // which parses the //sys lines and generates system call stubs.
  8. // Note that sometimes we use a lowercase //sys name and
  9. // wrap it in our own nicer implementation.
  10. package plan9
  11. import (
  12. "syscall"
  13. "unsafe"
  14. )
  15. // A Note is a string describing a process note.
  16. // It implements the os.Signal interface.
  17. type Note string
  18. func (n Note) Signal() {}
  19. func (n Note) String() string {
  20. return string(n)
  21. }
  22. var (
  23. Stdin = 0
  24. Stdout = 1
  25. Stderr = 2
  26. )
  27. // For testing: clients can set this flag to force
  28. // creation of IPv6 sockets to return EAFNOSUPPORT.
  29. var SocketDisableIPv6 bool
  30. func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
  31. func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
  32. func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
  33. func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
  34. func atoi(b []byte) (n uint) {
  35. n = 0
  36. for i := 0; i < len(b); i++ {
  37. n = n*10 + uint(b[i]-'0')
  38. }
  39. return
  40. }
  41. func cstring(s []byte) string {
  42. for i := range s {
  43. if s[i] == 0 {
  44. return string(s[0:i])
  45. }
  46. }
  47. return string(s)
  48. }
  49. func errstr() string {
  50. var buf [ERRMAX]byte
  51. RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
  52. buf[len(buf)-1] = 0
  53. return cstring(buf[:])
  54. }
  55. // Implemented in assembly to import from runtime.
  56. func exit(code int)
  57. func Exit(code int) { exit(code) }
  58. func readnum(path string) (uint, error) {
  59. var b [12]byte
  60. fd, e := Open(path, O_RDONLY)
  61. if e != nil {
  62. return 0, e
  63. }
  64. defer Close(fd)
  65. n, e := Pread(fd, b[:], 0)
  66. if e != nil {
  67. return 0, e
  68. }
  69. m := 0
  70. for ; m < n && b[m] == ' '; m++ {
  71. }
  72. return atoi(b[m : n-1]), nil
  73. }
  74. func Getpid() (pid int) {
  75. n, _ := readnum("#c/pid")
  76. return int(n)
  77. }
  78. func Getppid() (ppid int) {
  79. n, _ := readnum("#c/ppid")
  80. return int(n)
  81. }
  82. func Read(fd int, p []byte) (n int, err error) {
  83. return Pread(fd, p, -1)
  84. }
  85. func Write(fd int, p []byte) (n int, err error) {
  86. return Pwrite(fd, p, -1)
  87. }
  88. var ioSync int64
  89. func Getwd() (wd string, err error) {
  90. fd, e := Open(".", O_RDONLY)
  91. if e != nil {
  92. return "", e
  93. }
  94. defer Close(fd)
  95. return Fd2path(fd)
  96. }
  97. //sys fd2path(fd int, buf []byte) (err error)
  98. func Fd2path(fd int) (path string, err error) {
  99. var buf [512]byte
  100. e := fd2path(fd, buf[:])
  101. if e != nil {
  102. return "", e
  103. }
  104. return cstring(buf[:]), nil
  105. }
  106. //sys pipe(p *[2]int32) (err error)
  107. func Pipe(p []int) (err error) {
  108. if len(p) != 2 {
  109. return syscall.ErrorString("bad arg in system call")
  110. }
  111. var pp [2]int32
  112. err = pipe(&pp)
  113. p[0] = int(pp[0])
  114. p[1] = int(pp[1])
  115. return
  116. }
  117. // Underlying system call writes to newoffset via pointer.
  118. // Implemented in assembly to avoid allocation.
  119. func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
  120. func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
  121. newoffset, e := seek(0, fd, offset, whence)
  122. if newoffset == -1 {
  123. err = syscall.ErrorString(e)
  124. }
  125. return
  126. }
  127. func Mkdir(path string, mode uint32) (err error) {
  128. fd, err := Create(path, O_RDONLY, DMDIR|mode)
  129. if fd != -1 {
  130. Close(fd)
  131. }
  132. return
  133. }
  134. type Waitmsg struct {
  135. Pid int
  136. Time [3]uint32
  137. Msg string
  138. }
  139. func (w Waitmsg) Exited() bool { return true }
  140. func (w Waitmsg) Signaled() bool { return false }
  141. func (w Waitmsg) ExitStatus() int {
  142. if len(w.Msg) == 0 {
  143. // a normal exit returns no message
  144. return 0
  145. }
  146. return 1
  147. }
  148. //sys await(s []byte) (n int, err error)
  149. func Await(w *Waitmsg) (err error) {
  150. var buf [512]byte
  151. var f [5][]byte
  152. n, err := await(buf[:])
  153. if err != nil || w == nil {
  154. return
  155. }
  156. nf := 0
  157. p := 0
  158. for i := 0; i < n && nf < len(f)-1; i++ {
  159. if buf[i] == ' ' {
  160. f[nf] = buf[p:i]
  161. p = i + 1
  162. nf++
  163. }
  164. }
  165. f[nf] = buf[p:]
  166. nf++
  167. if nf != len(f) {
  168. return syscall.ErrorString("invalid wait message")
  169. }
  170. w.Pid = int(atoi(f[0]))
  171. w.Time[0] = uint32(atoi(f[1]))
  172. w.Time[1] = uint32(atoi(f[2]))
  173. w.Time[2] = uint32(atoi(f[3]))
  174. w.Msg = cstring(f[4])
  175. if w.Msg == "''" {
  176. // await() returns '' for no error
  177. w.Msg = ""
  178. }
  179. return
  180. }
  181. func Unmount(name, old string) (err error) {
  182. oldp, err := BytePtrFromString(old)
  183. if err != nil {
  184. return err
  185. }
  186. oldptr := uintptr(unsafe.Pointer(oldp))
  187. var r0 uintptr
  188. var e syscall.ErrorString
  189. // bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
  190. if name == "" {
  191. r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
  192. } else {
  193. namep, err := BytePtrFromString(name)
  194. if err != nil {
  195. return err
  196. }
  197. r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
  198. }
  199. if int32(r0) == -1 {
  200. err = e
  201. }
  202. return
  203. }
  204. func Fchdir(fd int) (err error) {
  205. path, err := Fd2path(fd)
  206. if err != nil {
  207. return
  208. }
  209. return Chdir(path)
  210. }
  211. type Timespec struct {
  212. Sec int32
  213. Nsec int32
  214. }
  215. type Timeval struct {
  216. Sec int32
  217. Usec int32
  218. }
  219. func NsecToTimeval(nsec int64) (tv Timeval) {
  220. nsec += 999 // round up to microsecond
  221. tv.Usec = int32(nsec % 1e9 / 1e3)
  222. tv.Sec = int32(nsec / 1e9)
  223. return
  224. }
  225. func nsec() int64 {
  226. var scratch int64
  227. r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
  228. // TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
  229. if r0 == 0 {
  230. return scratch
  231. }
  232. return int64(r0)
  233. }
  234. func Gettimeofday(tv *Timeval) error {
  235. nsec := nsec()
  236. *tv = NsecToTimeval(nsec)
  237. return nil
  238. }
  239. func Getpagesize() int { return 0x1000 }
  240. func Getegid() (egid int) { return -1 }
  241. func Geteuid() (euid int) { return -1 }
  242. func Getgid() (gid int) { return -1 }
  243. func Getuid() (uid int) { return -1 }
  244. func Getgroups() (gids []int, err error) {
  245. return make([]int, 0), nil
  246. }
  247. //sys Dup(oldfd int, newfd int) (fd int, err error)
  248. //sys Open(path string, mode int) (fd int, err error)
  249. //sys Create(path string, mode int, perm uint32) (fd int, err error)
  250. //sys Remove(path string) (err error)
  251. //sys Pread(fd int, p []byte, offset int64) (n int, err error)
  252. //sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
  253. //sys Close(fd int) (err error)
  254. //sys Chdir(path string) (err error)
  255. //sys Bind(name string, old string, flag int) (err error)
  256. //sys Mount(fd int, afd int, old string, flag int, aname string) (err error)
  257. //sys Stat(path string, edir []byte) (n int, err error)
  258. //sys Fstat(fd int, edir []byte) (n int, err error)
  259. //sys Wstat(path string, edir []byte) (err error)
  260. //sys Fwstat(fd int, edir []byte) (err error)