You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

syscall_plan9.go 7.0KB

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