PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/pkg/syscall/syscall_linux_386.go

https://code.google.com/p/go/
Go | 345 lines | 247 code | 49 blank | 49 comment | 64 complexity | 27f4e1c5e6b07c6e3afc00eb2771dbac MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright 2009 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. package syscall
  5. import "unsafe"
  6. func Getpagesize() int { return 4096 }
  7. func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
  8. func NsecToTimespec(nsec int64) (ts Timespec) {
  9. ts.Sec = int32(nsec / 1e9)
  10. ts.Nsec = int32(nsec % 1e9)
  11. return
  12. }
  13. func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
  14. func NsecToTimeval(nsec int64) (tv Timeval) {
  15. nsec += 999 // round up to microsecond
  16. tv.Sec = int32(nsec / 1e9)
  17. tv.Usec = int32(nsec % 1e9 / 1e3)
  18. return
  19. }
  20. // 64-bit file system and 32-bit uid calls
  21. // (386 default is 32-bit file system and 16-bit uid).
  22. //sys Chown(path string, uid int, gid int) (err error) = SYS_CHOWN32
  23. //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
  24. //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
  25. //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
  26. //sysnb Getegid() (egid int) = SYS_GETEGID32
  27. //sysnb Geteuid() (euid int) = SYS_GETEUID32
  28. //sysnb Getgid() (gid int) = SYS_GETGID32
  29. //sysnb Getuid() (uid int) = SYS_GETUID32
  30. //sys Ioperm(from int, num int, on int) (err error)
  31. //sys Iopl(level int) (err error)
  32. //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
  33. //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
  34. //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
  35. //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
  36. //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
  37. //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
  38. //sys Setfsuid(uid int) (err error) = SYS_SETFSUID32
  39. //sysnb Setgid(gid int) (err error) = SYS_SETGID32
  40. //sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
  41. //sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
  42. //sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
  43. //sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
  44. //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
  45. //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
  46. //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
  47. //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
  48. //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
  49. //sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
  50. //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
  51. //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
  52. func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
  53. page := uintptr(offset / 4096)
  54. if offset != int64(page)*4096 {
  55. return 0, EINVAL
  56. }
  57. return mmap2(addr, length, prot, flags, fd, page)
  58. }
  59. type rlimit32 struct {
  60. Cur uint32
  61. Max uint32
  62. }
  63. //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
  64. const rlimInf32 = ^uint32(0)
  65. const rlimInf64 = ^uint64(0)
  66. func Getrlimit(resource int, rlim *Rlimit) (err error) {
  67. err = prlimit(0, resource, nil, rlim)
  68. if err != ENOSYS {
  69. return err
  70. }
  71. rl := rlimit32{}
  72. err = getrlimit(resource, &rl)
  73. if err != nil {
  74. return
  75. }
  76. if rl.Cur == rlimInf32 {
  77. rlim.Cur = rlimInf64
  78. } else {
  79. rlim.Cur = uint64(rl.Cur)
  80. }
  81. if rl.Max == rlimInf32 {
  82. rlim.Max = rlimInf64
  83. } else {
  84. rlim.Max = uint64(rl.Max)
  85. }
  86. return
  87. }
  88. //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
  89. func Setrlimit(resource int, rlim *Rlimit) (err error) {
  90. err = prlimit(0, resource, rlim, nil)
  91. if err != ENOSYS {
  92. return err
  93. }
  94. rl := rlimit32{}
  95. if rlim.Cur == rlimInf64 {
  96. rl.Cur = rlimInf32
  97. } else if rlim.Cur < uint64(rlimInf32) {
  98. rl.Cur = uint32(rlim.Cur)
  99. } else {
  100. return EINVAL
  101. }
  102. if rlim.Max == rlimInf64 {
  103. rl.Max = rlimInf32
  104. } else if rlim.Max < uint64(rlimInf32) {
  105. rl.Max = uint32(rlim.Max)
  106. } else {
  107. return EINVAL
  108. }
  109. return setrlimit(resource, &rl)
  110. }
  111. // Underlying system call writes to newoffset via pointer.
  112. // Implemented in assembly to avoid allocation.
  113. func Seek(fd int, offset int64, whence int) (newoffset int64, err error)
  114. // Vsyscalls on amd64.
  115. //sysnb Gettimeofday(tv *Timeval) (err error)
  116. //sysnb Time(t *Time_t) (tt Time_t, err error)
  117. // On x86 Linux, all the socket calls go through an extra indirection,
  118. // I think because the 5-register system call interface can't handle
  119. // the 6-argument calls like sendto and recvfrom. Instead the
  120. // arguments to the underlying system call are the number below
  121. // and a pointer to an array of uintptr. We hide the pointer in the
  122. // socketcall assembly to avoid allocation on every system call.
  123. const (
  124. // see linux/net.h
  125. _SOCKET = 1
  126. _BIND = 2
  127. _CONNECT = 3
  128. _LISTEN = 4
  129. _ACCEPT = 5
  130. _GETSOCKNAME = 6
  131. _GETPEERNAME = 7
  132. _SOCKETPAIR = 8
  133. _SEND = 9
  134. _RECV = 10
  135. _SENDTO = 11
  136. _RECVFROM = 12
  137. _SHUTDOWN = 13
  138. _SETSOCKOPT = 14
  139. _GETSOCKOPT = 15
  140. _SENDMSG = 16
  141. _RECVMSG = 17
  142. _ACCEPT4 = 18
  143. _RECVMMSG = 19
  144. _SENDMMSG = 20
  145. )
  146. func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
  147. func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
  148. func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
  149. fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
  150. if e != 0 {
  151. err = e
  152. }
  153. return
  154. }
  155. func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
  156. fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
  157. if e != 0 {
  158. err = e
  159. }
  160. return
  161. }
  162. func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
  163. _, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
  164. if e != 0 {
  165. err = e
  166. }
  167. return
  168. }
  169. func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
  170. _, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
  171. if e != 0 {
  172. err = e
  173. }
  174. return
  175. }
  176. func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
  177. _, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
  178. if e != 0 {
  179. err = e
  180. }
  181. return
  182. }
  183. func bind(s int, addr uintptr, addrlen _Socklen) (err error) {
  184. _, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
  185. if e != 0 {
  186. err = e
  187. }
  188. return
  189. }
  190. func connect(s int, addr uintptr, addrlen _Socklen) (err error) {
  191. _, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
  192. if e != 0 {
  193. err = e
  194. }
  195. return
  196. }
  197. func socket(domain int, typ int, proto int) (fd int, err error) {
  198. fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
  199. if e != 0 {
  200. err = e
  201. }
  202. return
  203. }
  204. func getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) {
  205. _, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
  206. if e != 0 {
  207. err = e
  208. }
  209. return
  210. }
  211. func setsockopt(s int, level int, name int, val uintptr, vallen uintptr) (err error) {
  212. _, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), val, vallen, 0)
  213. if e != 0 {
  214. err = e
  215. }
  216. return
  217. }
  218. func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
  219. var base uintptr
  220. if len(p) > 0 {
  221. base = uintptr(unsafe.Pointer(&p[0]))
  222. }
  223. n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
  224. if e != 0 {
  225. err = e
  226. }
  227. return
  228. }
  229. func sendto(s int, p []byte, flags int, to uintptr, addrlen _Socklen) (err error) {
  230. var base uintptr
  231. if len(p) > 0 {
  232. base = uintptr(unsafe.Pointer(&p[0]))
  233. }
  234. _, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), to, uintptr(addrlen))
  235. if e != 0 {
  236. err = e
  237. }
  238. return
  239. }
  240. func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
  241. n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
  242. if e != 0 {
  243. err = e
  244. }
  245. return
  246. }
  247. func sendmsg(s int, msg *Msghdr, flags int) (err error) {
  248. _, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
  249. if e != 0 {
  250. err = e
  251. }
  252. return
  253. }
  254. func Listen(s int, n int) (err error) {
  255. _, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
  256. if e != 0 {
  257. err = e
  258. }
  259. return
  260. }
  261. func Shutdown(s, how int) (err error) {
  262. _, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
  263. if e != 0 {
  264. err = e
  265. }
  266. return
  267. }
  268. func Fstatfs(fd int, buf *Statfs_t) (err error) {
  269. _, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
  270. if e != 0 {
  271. err = e
  272. }
  273. return
  274. }
  275. func Statfs(path string, buf *Statfs_t) (err error) {
  276. pathp, err := BytePtrFromString(path)
  277. if err != nil {
  278. return err
  279. }
  280. _, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
  281. if e != 0 {
  282. err = e
  283. }
  284. return
  285. }
  286. func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
  287. func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
  288. func (iov *Iovec) SetLen(length int) {
  289. iov.Len = uint32(length)
  290. }
  291. func (msghdr *Msghdr) SetControllen(length int) {
  292. msghdr.Controllen = uint32(length)
  293. }
  294. func (cmsg *Cmsghdr) SetLen(length int) {
  295. cmsg.Len = uint32(length)
  296. }