syscall_plan9.go 7.0 KB

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