syscall_plan9.go 7.0 KB

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