syscall_zos_s390x.go 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979
  1. // Copyright 2020 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. //go:build zos && s390x
  5. // +build zos,s390x
  6. package unix
  7. import (
  8. "bytes"
  9. "fmt"
  10. "runtime"
  11. "sort"
  12. "strings"
  13. "sync"
  14. "syscall"
  15. "unsafe"
  16. )
  17. const (
  18. O_CLOEXEC = 0 // Dummy value (not supported).
  19. AF_LOCAL = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
  20. )
  21. func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
  22. func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
  23. func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
  24. func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
  25. func syscall_syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
  26. func syscall_rawsyscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
  27. func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
  28. stat.Dev = uint64(statLE.Dev)
  29. stat.Ino = uint64(statLE.Ino)
  30. stat.Nlink = uint64(statLE.Nlink)
  31. stat.Mode = uint32(statLE.Mode)
  32. stat.Uid = uint32(statLE.Uid)
  33. stat.Gid = uint32(statLE.Gid)
  34. stat.Rdev = uint64(statLE.Rdev)
  35. stat.Size = statLE.Size
  36. stat.Atim.Sec = int64(statLE.Atim)
  37. stat.Atim.Nsec = 0 //zos doesn't return nanoseconds
  38. stat.Mtim.Sec = int64(statLE.Mtim)
  39. stat.Mtim.Nsec = 0 //zos doesn't return nanoseconds
  40. stat.Ctim.Sec = int64(statLE.Ctim)
  41. stat.Ctim.Nsec = 0 //zos doesn't return nanoseconds
  42. stat.Blksize = int64(statLE.Blksize)
  43. stat.Blocks = statLE.Blocks
  44. }
  45. func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
  46. func svcLoad(name *byte) unsafe.Pointer
  47. func svcUnload(name *byte, fnptr unsafe.Pointer) int64
  48. func (d *Dirent) NameString() string {
  49. if d == nil {
  50. return ""
  51. }
  52. s := string(d.Name[:])
  53. idx := strings.IndexByte(s, 0)
  54. if idx == -1 {
  55. return s
  56. } else {
  57. return s[:idx]
  58. }
  59. }
  60. func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
  61. if sa.Port < 0 || sa.Port > 0xFFFF {
  62. return nil, 0, EINVAL
  63. }
  64. sa.raw.Len = SizeofSockaddrInet4
  65. sa.raw.Family = AF_INET
  66. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  67. p[0] = byte(sa.Port >> 8)
  68. p[1] = byte(sa.Port)
  69. sa.raw.Addr = sa.Addr
  70. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  71. }
  72. func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
  73. if sa.Port < 0 || sa.Port > 0xFFFF {
  74. return nil, 0, EINVAL
  75. }
  76. sa.raw.Len = SizeofSockaddrInet6
  77. sa.raw.Family = AF_INET6
  78. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  79. p[0] = byte(sa.Port >> 8)
  80. p[1] = byte(sa.Port)
  81. sa.raw.Scope_id = sa.ZoneId
  82. sa.raw.Addr = sa.Addr
  83. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  84. }
  85. func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
  86. name := sa.Name
  87. n := len(name)
  88. if n >= len(sa.raw.Path) || n == 0 {
  89. return nil, 0, EINVAL
  90. }
  91. sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
  92. sa.raw.Family = AF_UNIX
  93. for i := 0; i < n; i++ {
  94. sa.raw.Path[i] = int8(name[i])
  95. }
  96. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  97. }
  98. func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
  99. // TODO(neeilan): Implement use of first param (fd)
  100. switch rsa.Addr.Family {
  101. case AF_UNIX:
  102. pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
  103. sa := new(SockaddrUnix)
  104. // For z/OS, only replace NUL with @ when the
  105. // length is not zero.
  106. if pp.Len != 0 && pp.Path[0] == 0 {
  107. // "Abstract" Unix domain socket.
  108. // Rewrite leading NUL as @ for textual display.
  109. // (This is the standard convention.)
  110. // Not friendly to overwrite in place,
  111. // but the callers below don't care.
  112. pp.Path[0] = '@'
  113. }
  114. // Assume path ends at NUL.
  115. //
  116. // For z/OS, the length of the name is a field
  117. // in the structure. To be on the safe side, we
  118. // will still scan the name for a NUL but only
  119. // to the length provided in the structure.
  120. //
  121. // This is not technically the Linux semantics for
  122. // abstract Unix domain sockets--they are supposed
  123. // to be uninterpreted fixed-size binary blobs--but
  124. // everyone uses this convention.
  125. n := 0
  126. for n < int(pp.Len) && pp.Path[n] != 0 {
  127. n++
  128. }
  129. sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
  130. return sa, nil
  131. case AF_INET:
  132. pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
  133. sa := new(SockaddrInet4)
  134. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  135. sa.Port = int(p[0])<<8 + int(p[1])
  136. sa.Addr = pp.Addr
  137. return sa, nil
  138. case AF_INET6:
  139. pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
  140. sa := new(SockaddrInet6)
  141. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  142. sa.Port = int(p[0])<<8 + int(p[1])
  143. sa.ZoneId = pp.Scope_id
  144. sa.Addr = pp.Addr
  145. return sa, nil
  146. }
  147. return nil, EAFNOSUPPORT
  148. }
  149. func Accept(fd int) (nfd int, sa Sockaddr, err error) {
  150. var rsa RawSockaddrAny
  151. var len _Socklen = SizeofSockaddrAny
  152. nfd, err = accept(fd, &rsa, &len)
  153. if err != nil {
  154. return
  155. }
  156. // TODO(neeilan): Remove 0 in call
  157. sa, err = anyToSockaddr(0, &rsa)
  158. if err != nil {
  159. Close(nfd)
  160. nfd = 0
  161. }
  162. return
  163. }
  164. func (iov *Iovec) SetLen(length int) {
  165. iov.Len = uint64(length)
  166. }
  167. func (msghdr *Msghdr) SetControllen(length int) {
  168. msghdr.Controllen = int32(length)
  169. }
  170. func (cmsg *Cmsghdr) SetLen(length int) {
  171. cmsg.Len = int32(length)
  172. }
  173. //sys fcntl(fd int, cmd int, arg int) (val int, err error)
  174. //sys read(fd int, p []byte) (n int, err error)
  175. //sys write(fd int, p []byte) (n int, err error)
  176. //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
  177. //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
  178. //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
  179. //sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
  180. //sysnb setgroups(n int, list *_Gid_t) (err error)
  181. //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
  182. //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
  183. //sysnb socket(domain int, typ int, proto int) (fd int, err error)
  184. //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
  185. //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
  186. //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
  187. //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
  188. //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
  189. //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
  190. //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A
  191. //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP
  192. //sys munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
  193. //sys ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL
  194. //sys ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = SYS_IOCTL
  195. //sys Access(path string, mode uint32) (err error) = SYS___ACCESS_A
  196. //sys Chdir(path string) (err error) = SYS___CHDIR_A
  197. //sys Chown(path string, uid int, gid int) (err error) = SYS___CHOWN_A
  198. //sys Chmod(path string, mode uint32) (err error) = SYS___CHMOD_A
  199. //sys Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
  200. //sys Dup(oldfd int) (fd int, err error)
  201. //sys Dup2(oldfd int, newfd int) (err error)
  202. //sys Errno2() (er2 int) = SYS___ERRNO2
  203. //sys Err2ad() (eadd *int) = SYS___ERR2AD
  204. //sys Exit(code int)
  205. //sys Fchdir(fd int) (err error)
  206. //sys Fchmod(fd int, mode uint32) (err error)
  207. //sys Fchown(fd int, uid int, gid int) (err error)
  208. //sys FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL
  209. //sys fstat(fd int, stat *Stat_LE_t) (err error)
  210. func Fstat(fd int, stat *Stat_t) (err error) {
  211. var statLE Stat_LE_t
  212. err = fstat(fd, &statLE)
  213. copyStat(stat, &statLE)
  214. return
  215. }
  216. //sys Fstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS
  217. //sys Fsync(fd int) (err error)
  218. //sys Ftruncate(fd int, length int64) (err error)
  219. //sys Getpagesize() (pgsize int) = SYS_GETPAGESIZE
  220. //sys Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT
  221. //sys Msync(b []byte, flags int) (err error) = SYS_MSYNC
  222. //sys Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
  223. //sys Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
  224. //sys W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
  225. //sys W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
  226. //sys mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
  227. //sys unmount(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
  228. //sys Chroot(path string) (err error) = SYS___CHROOT_A
  229. //sys Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
  230. //sysnb Uname(buf *Utsname) (err error) = SYS___UNAME_A
  231. func Ptsname(fd int) (name string, err error) {
  232. r0, _, e1 := syscall_syscall(SYS___PTSNAME_A, uintptr(fd), 0, 0)
  233. name = u2s(unsafe.Pointer(r0))
  234. if e1 != 0 {
  235. err = errnoErr(e1)
  236. }
  237. return
  238. }
  239. func u2s(cstr unsafe.Pointer) string {
  240. str := (*[1024]uint8)(cstr)
  241. i := 0
  242. for str[i] != 0 {
  243. i++
  244. }
  245. return string(str[:i])
  246. }
  247. func Close(fd int) (err error) {
  248. _, _, e1 := syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
  249. for i := 0; e1 == EAGAIN && i < 10; i++ {
  250. _, _, _ = syscall_syscall(SYS_USLEEP, uintptr(10), 0, 0)
  251. _, _, e1 = syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
  252. }
  253. if e1 != 0 {
  254. err = errnoErr(e1)
  255. }
  256. return
  257. }
  258. // Dummy function: there are no semantics for Madvise on z/OS
  259. func Madvise(b []byte, advice int) (err error) {
  260. return
  261. }
  262. //sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
  263. //sysnb Getegid() (egid int)
  264. //sysnb Geteuid() (uid int)
  265. //sysnb Getgid() (gid int)
  266. //sysnb Getpid() (pid int)
  267. //sysnb Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
  268. func Getpgrp() (pid int) {
  269. pid, _ = Getpgid(0)
  270. return
  271. }
  272. //sysnb Getppid() (pid int)
  273. //sys Getpriority(which int, who int) (prio int, err error)
  274. //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
  275. //sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE
  276. func Getrusage(who int, rusage *Rusage) (err error) {
  277. var ruz rusage_zos
  278. err = getrusage(who, &ruz)
  279. //Only the first two fields of Rusage are set
  280. rusage.Utime.Sec = ruz.Utime.Sec
  281. rusage.Utime.Usec = int64(ruz.Utime.Usec)
  282. rusage.Stime.Sec = ruz.Stime.Sec
  283. rusage.Stime.Usec = int64(ruz.Stime.Usec)
  284. return
  285. }
  286. //sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
  287. //sysnb Getuid() (uid int)
  288. //sysnb Kill(pid int, sig Signal) (err error)
  289. //sys Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
  290. //sys Link(path string, link string) (err error) = SYS___LINK_A
  291. //sys Listen(s int, n int) (err error)
  292. //sys lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
  293. func Lstat(path string, stat *Stat_t) (err error) {
  294. var statLE Stat_LE_t
  295. err = lstat(path, &statLE)
  296. copyStat(stat, &statLE)
  297. return
  298. }
  299. //sys Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
  300. //sys Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
  301. //sys Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
  302. //sys Pread(fd int, p []byte, offset int64) (n int, err error)
  303. //sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
  304. //sys Readlink(path string, buf []byte) (n int, err error) = SYS___READLINK_A
  305. //sys Rename(from string, to string) (err error) = SYS___RENAME_A
  306. //sys Rmdir(path string) (err error) = SYS___RMDIR_A
  307. //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
  308. //sys Setpriority(which int, who int, prio int) (err error)
  309. //sysnb Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
  310. //sysnb Setrlimit(resource int, lim *Rlimit) (err error)
  311. //sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID
  312. //sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID
  313. //sysnb Setsid() (pid int, err error) = SYS_SETSID
  314. //sys Setuid(uid int) (err error) = SYS_SETUID
  315. //sys Setgid(uid int) (err error) = SYS_SETGID
  316. //sys Shutdown(fd int, how int) (err error)
  317. //sys stat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A
  318. func Stat(path string, sta *Stat_t) (err error) {
  319. var statLE Stat_LE_t
  320. err = stat(path, &statLE)
  321. copyStat(sta, &statLE)
  322. return
  323. }
  324. //sys Symlink(path string, link string) (err error) = SYS___SYMLINK_A
  325. //sys Sync() = SYS_SYNC
  326. //sys Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
  327. //sys Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
  328. //sys Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
  329. //sys Umask(mask int) (oldmask int)
  330. //sys Unlink(path string) (err error) = SYS___UNLINK_A
  331. //sys Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
  332. //sys open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
  333. func Open(path string, mode int, perm uint32) (fd int, err error) {
  334. return open(path, mode, perm)
  335. }
  336. func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
  337. wd, err := Getwd()
  338. if err != nil {
  339. return err
  340. }
  341. if err := Fchdir(dirfd); err != nil {
  342. return err
  343. }
  344. defer Chdir(wd)
  345. return Mkfifo(path, mode)
  346. }
  347. //sys remove(path string) (err error)
  348. func Remove(path string) error {
  349. return remove(path)
  350. }
  351. const ImplementsGetwd = true
  352. func Getcwd(buf []byte) (n int, err error) {
  353. var p unsafe.Pointer
  354. if len(buf) > 0 {
  355. p = unsafe.Pointer(&buf[0])
  356. } else {
  357. p = unsafe.Pointer(&_zero)
  358. }
  359. _, _, e := syscall_syscall(SYS___GETCWD_A, uintptr(p), uintptr(len(buf)), 0)
  360. n = clen(buf) + 1
  361. if e != 0 {
  362. err = errnoErr(e)
  363. }
  364. return
  365. }
  366. func Getwd() (wd string, err error) {
  367. var buf [PathMax]byte
  368. n, err := Getcwd(buf[0:])
  369. if err != nil {
  370. return "", err
  371. }
  372. // Getcwd returns the number of bytes written to buf, including the NUL.
  373. if n < 1 || n > len(buf) || buf[n-1] != 0 {
  374. return "", EINVAL
  375. }
  376. return string(buf[0 : n-1]), nil
  377. }
  378. func Getgroups() (gids []int, err error) {
  379. n, err := getgroups(0, nil)
  380. if err != nil {
  381. return nil, err
  382. }
  383. if n == 0 {
  384. return nil, nil
  385. }
  386. // Sanity check group count. Max is 1<<16 on Linux.
  387. if n < 0 || n > 1<<20 {
  388. return nil, EINVAL
  389. }
  390. a := make([]_Gid_t, n)
  391. n, err = getgroups(n, &a[0])
  392. if err != nil {
  393. return nil, err
  394. }
  395. gids = make([]int, n)
  396. for i, v := range a[0:n] {
  397. gids[i] = int(v)
  398. }
  399. return
  400. }
  401. func Setgroups(gids []int) (err error) {
  402. if len(gids) == 0 {
  403. return setgroups(0, nil)
  404. }
  405. a := make([]_Gid_t, len(gids))
  406. for i, v := range gids {
  407. a[i] = _Gid_t(v)
  408. }
  409. return setgroups(len(a), &a[0])
  410. }
  411. func gettid() uint64
  412. func Gettid() (tid int) {
  413. return int(gettid())
  414. }
  415. type WaitStatus uint32
  416. // Wait status is 7 bits at bottom, either 0 (exited),
  417. // 0x7F (stopped), or a signal number that caused an exit.
  418. // The 0x80 bit is whether there was a core dump.
  419. // An extra number (exit code, signal causing a stop)
  420. // is in the high bits. At least that's the idea.
  421. // There are various irregularities. For example, the
  422. // "continued" status is 0xFFFF, distinguishing itself
  423. // from stopped via the core dump bit.
  424. const (
  425. mask = 0x7F
  426. core = 0x80
  427. exited = 0x00
  428. stopped = 0x7F
  429. shift = 8
  430. )
  431. func (w WaitStatus) Exited() bool { return w&mask == exited }
  432. func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
  433. func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
  434. func (w WaitStatus) Continued() bool { return w == 0xFFFF }
  435. func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
  436. func (w WaitStatus) ExitStatus() int {
  437. if !w.Exited() {
  438. return -1
  439. }
  440. return int(w>>shift) & 0xFF
  441. }
  442. func (w WaitStatus) Signal() Signal {
  443. if !w.Signaled() {
  444. return -1
  445. }
  446. return Signal(w & mask)
  447. }
  448. func (w WaitStatus) StopSignal() Signal {
  449. if !w.Stopped() {
  450. return -1
  451. }
  452. return Signal(w>>shift) & 0xFF
  453. }
  454. func (w WaitStatus) TrapCause() int { return -1 }
  455. //sys waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
  456. func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  457. // TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
  458. // At the moment rusage will not be touched.
  459. var status _C_int
  460. wpid, err = waitpid(pid, &status, options)
  461. if wstatus != nil {
  462. *wstatus = WaitStatus(status)
  463. }
  464. return
  465. }
  466. //sysnb gettimeofday(tv *timeval_zos) (err error)
  467. func Gettimeofday(tv *Timeval) (err error) {
  468. var tvz timeval_zos
  469. err = gettimeofday(&tvz)
  470. tv.Sec = tvz.Sec
  471. tv.Usec = int64(tvz.Usec)
  472. return
  473. }
  474. func Time(t *Time_t) (tt Time_t, err error) {
  475. var tv Timeval
  476. err = Gettimeofday(&tv)
  477. if err != nil {
  478. return 0, err
  479. }
  480. if t != nil {
  481. *t = Time_t(tv.Sec)
  482. }
  483. return Time_t(tv.Sec), nil
  484. }
  485. func setTimespec(sec, nsec int64) Timespec {
  486. return Timespec{Sec: sec, Nsec: nsec}
  487. }
  488. func setTimeval(sec, usec int64) Timeval { //fix
  489. return Timeval{Sec: sec, Usec: usec}
  490. }
  491. //sysnb pipe(p *[2]_C_int) (err error)
  492. func Pipe(p []int) (err error) {
  493. if len(p) != 2 {
  494. return EINVAL
  495. }
  496. var pp [2]_C_int
  497. err = pipe(&pp)
  498. if err == nil {
  499. p[0] = int(pp[0])
  500. p[1] = int(pp[1])
  501. }
  502. return
  503. }
  504. //sys utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
  505. func Utimes(path string, tv []Timeval) (err error) {
  506. if len(tv) != 2 {
  507. return EINVAL
  508. }
  509. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  510. }
  511. func UtimesNano(path string, ts []Timespec) error {
  512. if len(ts) != 2 {
  513. return EINVAL
  514. }
  515. // Not as efficient as it could be because Timespec and
  516. // Timeval have different types in the different OSes
  517. tv := [2]Timeval{
  518. NsecToTimeval(TimespecToNsec(ts[0])),
  519. NsecToTimeval(TimespecToNsec(ts[1])),
  520. }
  521. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  522. }
  523. func Getsockname(fd int) (sa Sockaddr, err error) {
  524. var rsa RawSockaddrAny
  525. var len _Socklen = SizeofSockaddrAny
  526. if err = getsockname(fd, &rsa, &len); err != nil {
  527. return
  528. }
  529. // TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
  530. return anyToSockaddr(0, &rsa)
  531. }
  532. const (
  533. // identifier constants
  534. nwmHeaderIdentifier = 0xd5e6d4c8
  535. nwmFilterIdentifier = 0xd5e6d4c6
  536. nwmTCPConnIdentifier = 0xd5e6d4c3
  537. nwmRecHeaderIdentifier = 0xd5e6d4d9
  538. nwmIPStatsIdentifier = 0xd5e6d4c9d7e2e340
  539. nwmIPGStatsIdentifier = 0xd5e6d4c9d7c7e2e3
  540. nwmTCPStatsIdentifier = 0xd5e6d4e3c3d7e2e3
  541. nwmUDPStatsIdentifier = 0xd5e6d4e4c4d7e2e3
  542. nwmICMPGStatsEntry = 0xd5e6d4c9c3d4d7c7
  543. nwmICMPTStatsEntry = 0xd5e6d4c9c3d4d7e3
  544. // nwmHeader constants
  545. nwmVersion1 = 1
  546. nwmVersion2 = 2
  547. nwmCurrentVer = 2
  548. nwmTCPConnType = 1
  549. nwmGlobalStatsType = 14
  550. // nwmFilter constants
  551. nwmFilterLclAddrMask = 0x20000000 // Local address
  552. nwmFilterSrcAddrMask = 0x20000000 // Source address
  553. nwmFilterLclPortMask = 0x10000000 // Local port
  554. nwmFilterSrcPortMask = 0x10000000 // Source port
  555. // nwmConnEntry constants
  556. nwmTCPStateClosed = 1
  557. nwmTCPStateListen = 2
  558. nwmTCPStateSynSent = 3
  559. nwmTCPStateSynRcvd = 4
  560. nwmTCPStateEstab = 5
  561. nwmTCPStateFinWait1 = 6
  562. nwmTCPStateFinWait2 = 7
  563. nwmTCPStateClosWait = 8
  564. nwmTCPStateLastAck = 9
  565. nwmTCPStateClosing = 10
  566. nwmTCPStateTimeWait = 11
  567. nwmTCPStateDeletTCB = 12
  568. // Existing constants on linux
  569. BPF_TCP_CLOSE = 1
  570. BPF_TCP_LISTEN = 2
  571. BPF_TCP_SYN_SENT = 3
  572. BPF_TCP_SYN_RECV = 4
  573. BPF_TCP_ESTABLISHED = 5
  574. BPF_TCP_FIN_WAIT1 = 6
  575. BPF_TCP_FIN_WAIT2 = 7
  576. BPF_TCP_CLOSE_WAIT = 8
  577. BPF_TCP_LAST_ACK = 9
  578. BPF_TCP_CLOSING = 10
  579. BPF_TCP_TIME_WAIT = 11
  580. BPF_TCP_NEW_SYN_RECV = -1
  581. BPF_TCP_MAX_STATES = -2
  582. )
  583. type nwmTriplet struct {
  584. offset uint32
  585. length uint32
  586. number uint32
  587. }
  588. type nwmQuadruplet struct {
  589. offset uint32
  590. length uint32
  591. number uint32
  592. match uint32
  593. }
  594. type nwmHeader struct {
  595. ident uint32
  596. length uint32
  597. version uint16
  598. nwmType uint16
  599. bytesNeeded uint32
  600. options uint32
  601. _ [16]byte
  602. inputDesc nwmTriplet
  603. outputDesc nwmQuadruplet
  604. }
  605. type nwmFilter struct {
  606. ident uint32
  607. flags uint32
  608. resourceName [8]byte
  609. resourceId uint32
  610. listenerId uint32
  611. local [28]byte // union of sockaddr4 and sockaddr6
  612. remote [28]byte // union of sockaddr4 and sockaddr6
  613. _ uint16
  614. _ uint16
  615. asid uint16
  616. _ [2]byte
  617. tnLuName [8]byte
  618. tnMonGrp uint32
  619. tnAppl [8]byte
  620. applData [40]byte
  621. nInterface [16]byte
  622. dVipa [16]byte
  623. dVipaPfx uint16
  624. dVipaPort uint16
  625. dVipaFamily byte
  626. _ [3]byte
  627. destXCF [16]byte
  628. destXCFPfx uint16
  629. destXCFFamily byte
  630. _ [1]byte
  631. targIP [16]byte
  632. targIPPfx uint16
  633. targIPFamily byte
  634. _ [1]byte
  635. _ [20]byte
  636. }
  637. type nwmRecHeader struct {
  638. ident uint32
  639. length uint32
  640. number byte
  641. _ [3]byte
  642. }
  643. type nwmTCPStatsEntry struct {
  644. ident uint64
  645. currEstab uint32
  646. activeOpened uint32
  647. passiveOpened uint32
  648. connClosed uint32
  649. estabResets uint32
  650. attemptFails uint32
  651. passiveDrops uint32
  652. timeWaitReused uint32
  653. inSegs uint64
  654. predictAck uint32
  655. predictData uint32
  656. inDupAck uint32
  657. inBadSum uint32
  658. inBadLen uint32
  659. inShort uint32
  660. inDiscOldTime uint32
  661. inAllBeforeWin uint32
  662. inSomeBeforeWin uint32
  663. inAllAfterWin uint32
  664. inSomeAfterWin uint32
  665. inOutOfOrder uint32
  666. inAfterClose uint32
  667. inWinProbes uint32
  668. inWinUpdates uint32
  669. outWinUpdates uint32
  670. outSegs uint64
  671. outDelayAcks uint32
  672. outRsts uint32
  673. retransSegs uint32
  674. retransTimeouts uint32
  675. retransDrops uint32
  676. pmtuRetrans uint32
  677. pmtuErrors uint32
  678. outWinProbes uint32
  679. probeDrops uint32
  680. keepAliveProbes uint32
  681. keepAliveDrops uint32
  682. finwait2Drops uint32
  683. acceptCount uint64
  684. inBulkQSegs uint64
  685. inDiscards uint64
  686. connFloods uint32
  687. connStalls uint32
  688. cfgEphemDef uint16
  689. ephemInUse uint16
  690. ephemHiWater uint16
  691. flags byte
  692. _ [1]byte
  693. ephemExhaust uint32
  694. smcRCurrEstabLnks uint32
  695. smcRLnkActTimeOut uint32
  696. smcRActLnkOpened uint32
  697. smcRPasLnkOpened uint32
  698. smcRLnksClosed uint32
  699. smcRCurrEstab uint32
  700. smcRActiveOpened uint32
  701. smcRPassiveOpened uint32
  702. smcRConnClosed uint32
  703. smcRInSegs uint64
  704. smcROutSegs uint64
  705. smcRInRsts uint32
  706. smcROutRsts uint32
  707. smcDCurrEstabLnks uint32
  708. smcDActLnkOpened uint32
  709. smcDPasLnkOpened uint32
  710. smcDLnksClosed uint32
  711. smcDCurrEstab uint32
  712. smcDActiveOpened uint32
  713. smcDPassiveOpened uint32
  714. smcDConnClosed uint32
  715. smcDInSegs uint64
  716. smcDOutSegs uint64
  717. smcDInRsts uint32
  718. smcDOutRsts uint32
  719. }
  720. type nwmConnEntry struct {
  721. ident uint32
  722. local [28]byte // union of sockaddr4 and sockaddr6
  723. remote [28]byte // union of sockaddr4 and sockaddr6
  724. startTime [8]byte // uint64, changed to prevent padding from being inserted
  725. lastActivity [8]byte // uint64
  726. bytesIn [8]byte // uint64
  727. bytesOut [8]byte // uint64
  728. inSegs [8]byte // uint64
  729. outSegs [8]byte // uint64
  730. state uint16
  731. activeOpen byte
  732. flag01 byte
  733. outBuffered uint32
  734. inBuffered uint32
  735. maxSndWnd uint32
  736. reXmtCount uint32
  737. congestionWnd uint32
  738. ssThresh uint32
  739. roundTripTime uint32
  740. roundTripVar uint32
  741. sendMSS uint32
  742. sndWnd uint32
  743. rcvBufSize uint32
  744. sndBufSize uint32
  745. outOfOrderCount uint32
  746. lcl0WindowCount uint32
  747. rmt0WindowCount uint32
  748. dupacks uint32
  749. flag02 byte
  750. sockOpt6Cont byte
  751. asid uint16
  752. resourceName [8]byte
  753. resourceId uint32
  754. subtask uint32
  755. sockOpt byte
  756. sockOpt6 byte
  757. clusterConnFlag byte
  758. proto byte
  759. targetAppl [8]byte
  760. luName [8]byte
  761. clientUserId [8]byte
  762. logMode [8]byte
  763. timeStamp uint32
  764. timeStampAge uint32
  765. serverResourceId uint32
  766. intfName [16]byte
  767. ttlsStatPol byte
  768. ttlsStatConn byte
  769. ttlsSSLProt uint16
  770. ttlsNegCiph [2]byte
  771. ttlsSecType byte
  772. ttlsFIPS140Mode byte
  773. ttlsUserID [8]byte
  774. applData [40]byte
  775. inOldestTime [8]byte // uint64
  776. outOldestTime [8]byte // uint64
  777. tcpTrustedPartner byte
  778. _ [3]byte
  779. bulkDataIntfName [16]byte
  780. ttlsNegCiph4 [4]byte
  781. smcReason uint32
  782. lclSMCLinkId uint32
  783. rmtSMCLinkId uint32
  784. smcStatus byte
  785. smcFlags byte
  786. _ [2]byte
  787. rcvWnd uint32
  788. lclSMCBufSz uint32
  789. rmtSMCBufSz uint32
  790. ttlsSessID [32]byte
  791. ttlsSessIDLen int16
  792. _ [1]byte
  793. smcDStatus byte
  794. smcDReason uint32
  795. }
  796. var svcNameTable [][]byte = [][]byte{
  797. []byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
  798. }
  799. const (
  800. svc_EZBNMIF4 = 0
  801. )
  802. func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
  803. jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
  804. responseBuffer := [4096]byte{0}
  805. var bufferAlet, reasonCode uint32 = 0, 0
  806. var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
  807. dsa := [18]uint64{0}
  808. var argv [7]unsafe.Pointer
  809. argv[0] = unsafe.Pointer(&jobname[0])
  810. argv[1] = unsafe.Pointer(&responseBuffer[0])
  811. argv[2] = unsafe.Pointer(&bufferAlet)
  812. argv[3] = unsafe.Pointer(&bufferLen)
  813. argv[4] = unsafe.Pointer(&returnValue)
  814. argv[5] = unsafe.Pointer(&returnCode)
  815. argv[6] = unsafe.Pointer(&reasonCode)
  816. request := (*struct {
  817. header nwmHeader
  818. filter nwmFilter
  819. })(unsafe.Pointer(&responseBuffer[0]))
  820. EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
  821. if EZBNMIF4 == nil {
  822. return nil, errnoErr(EINVAL)
  823. }
  824. // GetGlobalStats EZBNMIF4 call
  825. request.header.ident = nwmHeaderIdentifier
  826. request.header.length = uint32(unsafe.Sizeof(request.header))
  827. request.header.version = nwmCurrentVer
  828. request.header.nwmType = nwmGlobalStatsType
  829. request.header.options = 0x80000000
  830. svcCall(EZBNMIF4, &argv[0], &dsa[0])
  831. // outputDesc field is filled by EZBNMIF4 on success
  832. if returnCode != 0 || request.header.outputDesc.offset == 0 {
  833. return nil, errnoErr(EINVAL)
  834. }
  835. // Check that EZBNMIF4 returned a nwmRecHeader
  836. recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  837. if recHeader.ident != nwmRecHeaderIdentifier {
  838. return nil, errnoErr(EINVAL)
  839. }
  840. // Parse nwmTriplets to get offsets of returned entries
  841. var sections []*uint64
  842. var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
  843. for i := uint32(0); i < uint32(recHeader.number); i++ {
  844. offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
  845. sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
  846. for j := uint32(0); j < sectionDesc.number; j++ {
  847. offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
  848. sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
  849. }
  850. }
  851. // Find nwmTCPStatsEntry in returned entries
  852. var tcpStats *nwmTCPStatsEntry = nil
  853. for _, ptr := range sections {
  854. switch *ptr {
  855. case nwmTCPStatsIdentifier:
  856. if tcpStats != nil {
  857. return nil, errnoErr(EINVAL)
  858. }
  859. tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
  860. case nwmIPStatsIdentifier:
  861. case nwmIPGStatsIdentifier:
  862. case nwmUDPStatsIdentifier:
  863. case nwmICMPGStatsEntry:
  864. case nwmICMPTStatsEntry:
  865. default:
  866. return nil, errnoErr(EINVAL)
  867. }
  868. }
  869. if tcpStats == nil {
  870. return nil, errnoErr(EINVAL)
  871. }
  872. // GetConnectionDetail EZBNMIF4 call
  873. responseBuffer = [4096]byte{0}
  874. dsa = [18]uint64{0}
  875. bufferAlet, reasonCode = 0, 0
  876. bufferLen, returnValue, returnCode = 4096, 0, 0
  877. nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
  878. nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
  879. argv[0] = unsafe.Pointer(uintptr(*nameptr))
  880. request.header.ident = nwmHeaderIdentifier
  881. request.header.length = uint32(unsafe.Sizeof(request.header))
  882. request.header.version = nwmCurrentVer
  883. request.header.nwmType = nwmTCPConnType
  884. request.header.options = 0x80000000
  885. request.filter.ident = nwmFilterIdentifier
  886. var localSockaddr RawSockaddrAny
  887. socklen := _Socklen(SizeofSockaddrAny)
  888. err := getsockname(fd, &localSockaddr, &socklen)
  889. if err != nil {
  890. return nil, errnoErr(EINVAL)
  891. }
  892. if localSockaddr.Addr.Family == AF_INET {
  893. localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
  894. localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
  895. localSockFilter.Family = AF_INET
  896. var i int
  897. for i = 0; i < 4; i++ {
  898. if localSockaddr.Addr[i] != 0 {
  899. break
  900. }
  901. }
  902. if i != 4 {
  903. request.filter.flags |= nwmFilterLclAddrMask
  904. for i = 0; i < 4; i++ {
  905. localSockFilter.Addr[i] = localSockaddr.Addr[i]
  906. }
  907. }
  908. if localSockaddr.Port != 0 {
  909. request.filter.flags |= nwmFilterLclPortMask
  910. localSockFilter.Port = localSockaddr.Port
  911. }
  912. } else if localSockaddr.Addr.Family == AF_INET6 {
  913. localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
  914. localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
  915. localSockFilter.Family = AF_INET6
  916. var i int
  917. for i = 0; i < 16; i++ {
  918. if localSockaddr.Addr[i] != 0 {
  919. break
  920. }
  921. }
  922. if i != 16 {
  923. request.filter.flags |= nwmFilterLclAddrMask
  924. for i = 0; i < 16; i++ {
  925. localSockFilter.Addr[i] = localSockaddr.Addr[i]
  926. }
  927. }
  928. if localSockaddr.Port != 0 {
  929. request.filter.flags |= nwmFilterLclPortMask
  930. localSockFilter.Port = localSockaddr.Port
  931. }
  932. }
  933. svcCall(EZBNMIF4, &argv[0], &dsa[0])
  934. // outputDesc field is filled by EZBNMIF4 on success
  935. if returnCode != 0 || request.header.outputDesc.offset == 0 {
  936. return nil, errnoErr(EINVAL)
  937. }
  938. // Check that EZBNMIF4 returned a nwmConnEntry
  939. conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  940. if conn.ident != nwmTCPConnIdentifier {
  941. return nil, errnoErr(EINVAL)
  942. }
  943. // Copy data from the returned data structures into tcpInfo
  944. // Stats from nwmConnEntry are specific to that connection.
  945. // Stats from nwmTCPStatsEntry are global (to the interface?)
  946. // Fields may not be an exact match. Some fields have no equivalent.
  947. var tcpinfo TCPInfo
  948. tcpinfo.State = uint8(conn.state)
  949. tcpinfo.Ca_state = 0 // dummy
  950. tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
  951. tcpinfo.Probes = uint8(tcpStats.outWinProbes)
  952. tcpinfo.Backoff = 0 // dummy
  953. tcpinfo.Options = 0 // dummy
  954. tcpinfo.Rto = tcpStats.retransTimeouts
  955. tcpinfo.Ato = tcpStats.outDelayAcks
  956. tcpinfo.Snd_mss = conn.sendMSS
  957. tcpinfo.Rcv_mss = conn.sendMSS // dummy
  958. tcpinfo.Unacked = 0 // dummy
  959. tcpinfo.Sacked = 0 // dummy
  960. tcpinfo.Lost = 0 // dummy
  961. tcpinfo.Retrans = conn.reXmtCount
  962. tcpinfo.Fackets = 0 // dummy
  963. tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
  964. tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
  965. tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  966. tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  967. tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
  968. tcpinfo.Rcv_ssthresh = conn.ssThresh
  969. tcpinfo.Rtt = conn.roundTripTime
  970. tcpinfo.Rttvar = conn.roundTripVar
  971. tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
  972. tcpinfo.Snd_cwnd = conn.congestionWnd
  973. tcpinfo.Advmss = conn.sendMSS // dummy
  974. tcpinfo.Reordering = 0 // dummy
  975. tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
  976. tcpinfo.Rcv_space = conn.sendMSS // dummy
  977. tcpinfo.Total_retrans = conn.reXmtCount
  978. svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
  979. return &tcpinfo, nil
  980. }
  981. // GetsockoptString returns the string value of the socket option opt for the
  982. // socket associated with fd at the given socket level.
  983. func GetsockoptString(fd, level, opt int) (string, error) {
  984. buf := make([]byte, 256)
  985. vallen := _Socklen(len(buf))
  986. err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
  987. if err != nil {
  988. return "", err
  989. }
  990. return string(buf[:vallen-1]), nil
  991. }
  992. func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  993. var msg Msghdr
  994. var rsa RawSockaddrAny
  995. msg.Name = (*byte)(unsafe.Pointer(&rsa))
  996. msg.Namelen = SizeofSockaddrAny
  997. var iov Iovec
  998. if len(p) > 0 {
  999. iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1000. iov.SetLen(len(p))
  1001. }
  1002. var dummy byte
  1003. if len(oob) > 0 {
  1004. // receive at least one normal byte
  1005. if len(p) == 0 {
  1006. iov.Base = &dummy
  1007. iov.SetLen(1)
  1008. }
  1009. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1010. msg.SetControllen(len(oob))
  1011. }
  1012. msg.Iov = &iov
  1013. msg.Iovlen = 1
  1014. if n, err = recvmsg(fd, &msg, flags); err != nil {
  1015. return
  1016. }
  1017. oobn = int(msg.Controllen)
  1018. recvflags = int(msg.Flags)
  1019. // source address is only specified if the socket is unconnected
  1020. if rsa.Addr.Family != AF_UNSPEC {
  1021. // TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
  1022. from, err = anyToSockaddr(0, &rsa)
  1023. }
  1024. return
  1025. }
  1026. func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
  1027. _, err = SendmsgN(fd, p, oob, to, flags)
  1028. return
  1029. }
  1030. func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
  1031. var ptr unsafe.Pointer
  1032. var salen _Socklen
  1033. if to != nil {
  1034. var err error
  1035. ptr, salen, err = to.sockaddr()
  1036. if err != nil {
  1037. return 0, err
  1038. }
  1039. }
  1040. var msg Msghdr
  1041. msg.Name = (*byte)(unsafe.Pointer(ptr))
  1042. msg.Namelen = int32(salen)
  1043. var iov Iovec
  1044. if len(p) > 0 {
  1045. iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1046. iov.SetLen(len(p))
  1047. }
  1048. var dummy byte
  1049. if len(oob) > 0 {
  1050. // send at least one normal byte
  1051. if len(p) == 0 {
  1052. iov.Base = &dummy
  1053. iov.SetLen(1)
  1054. }
  1055. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1056. msg.SetControllen(len(oob))
  1057. }
  1058. msg.Iov = &iov
  1059. msg.Iovlen = 1
  1060. if n, err = sendmsg(fd, &msg, flags); err != nil {
  1061. return 0, err
  1062. }
  1063. if len(oob) > 0 && len(p) == 0 {
  1064. n = 0
  1065. }
  1066. return n, nil
  1067. }
  1068. func Opendir(name string) (uintptr, error) {
  1069. p, err := BytePtrFromString(name)
  1070. if err != nil {
  1071. return 0, err
  1072. }
  1073. dir, _, e := syscall_syscall(SYS___OPENDIR_A, uintptr(unsafe.Pointer(p)), 0, 0)
  1074. runtime.KeepAlive(unsafe.Pointer(p))
  1075. if e != 0 {
  1076. err = errnoErr(e)
  1077. }
  1078. return dir, err
  1079. }
  1080. // clearsyscall.Errno resets the errno value to 0.
  1081. func clearErrno()
  1082. func Readdir(dir uintptr) (*Dirent, error) {
  1083. var ent Dirent
  1084. var res uintptr
  1085. // __readdir_r_a returns errno at the end of the directory stream, rather than 0.
  1086. // Therefore to avoid false positives we clear errno before calling it.
  1087. // TODO(neeilan): Commented this out to get sys/unix compiling on z/OS. Uncomment and fix. Error: "undefined: clearsyscall"
  1088. //clearsyscall.Errno() // TODO(mundaym): check pre-emption rules.
  1089. e, _, _ := syscall_syscall(SYS___READDIR_R_A, dir, uintptr(unsafe.Pointer(&ent)), uintptr(unsafe.Pointer(&res)))
  1090. var err error
  1091. if e != 0 {
  1092. err = errnoErr(Errno(e))
  1093. }
  1094. if res == 0 {
  1095. return nil, err
  1096. }
  1097. return &ent, err
  1098. }
  1099. func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
  1100. r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
  1101. if int64(r0) == -1 {
  1102. err = errnoErr(Errno(e1))
  1103. }
  1104. return
  1105. }
  1106. func Closedir(dir uintptr) error {
  1107. _, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
  1108. if e != 0 {
  1109. return errnoErr(e)
  1110. }
  1111. return nil
  1112. }
  1113. func Seekdir(dir uintptr, pos int) {
  1114. _, _, _ = syscall_syscall(SYS_SEEKDIR, dir, uintptr(pos), 0)
  1115. }
  1116. func Telldir(dir uintptr) (int, error) {
  1117. p, _, e := syscall_syscall(SYS_TELLDIR, dir, 0, 0)
  1118. pos := int(p)
  1119. if pos == -1 {
  1120. return pos, errnoErr(e)
  1121. }
  1122. return pos, nil
  1123. }
  1124. // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
  1125. func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
  1126. // struct flock is packed on z/OS. We can't emulate that in Go so
  1127. // instead we pack it here.
  1128. var flock [24]byte
  1129. *(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
  1130. *(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
  1131. *(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
  1132. *(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
  1133. *(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
  1134. _, _, errno := syscall_syscall(SYS_FCNTL, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
  1135. lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
  1136. lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
  1137. lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
  1138. lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
  1139. lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
  1140. if errno == 0 {
  1141. return nil
  1142. }
  1143. return errno
  1144. }
  1145. func Flock(fd int, how int) error {
  1146. var flock_type int16
  1147. var fcntl_cmd int
  1148. switch how {
  1149. case LOCK_SH | LOCK_NB:
  1150. flock_type = F_RDLCK
  1151. fcntl_cmd = F_SETLK
  1152. case LOCK_EX | LOCK_NB:
  1153. flock_type = F_WRLCK
  1154. fcntl_cmd = F_SETLK
  1155. case LOCK_EX:
  1156. flock_type = F_WRLCK
  1157. fcntl_cmd = F_SETLKW
  1158. case LOCK_UN:
  1159. flock_type = F_UNLCK
  1160. fcntl_cmd = F_SETLKW
  1161. default:
  1162. }
  1163. flock := Flock_t{
  1164. Type: int16(flock_type),
  1165. Whence: int16(0),
  1166. Start: int64(0),
  1167. Len: int64(0),
  1168. Pid: int32(Getppid()),
  1169. }
  1170. err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
  1171. return err
  1172. }
  1173. func Mlock(b []byte) (err error) {
  1174. _, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1175. if e1 != 0 {
  1176. err = errnoErr(e1)
  1177. }
  1178. return
  1179. }
  1180. func Mlock2(b []byte, flags int) (err error) {
  1181. _, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1182. if e1 != 0 {
  1183. err = errnoErr(e1)
  1184. }
  1185. return
  1186. }
  1187. func Mlockall(flags int) (err error) {
  1188. _, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1189. if e1 != 0 {
  1190. err = errnoErr(e1)
  1191. }
  1192. return
  1193. }
  1194. func Munlock(b []byte) (err error) {
  1195. _, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
  1196. if e1 != 0 {
  1197. err = errnoErr(e1)
  1198. }
  1199. return
  1200. }
  1201. func Munlockall() (err error) {
  1202. _, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
  1203. if e1 != 0 {
  1204. err = errnoErr(e1)
  1205. }
  1206. return
  1207. }
  1208. func ClockGettime(clockid int32, ts *Timespec) error {
  1209. var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
  1210. var nsec_per_sec int64 = 1000000000
  1211. if ts == nil {
  1212. return EFAULT
  1213. }
  1214. if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
  1215. var nanotime int64 = runtime.Nanotime1()
  1216. ts.Sec = nanotime / nsec_per_sec
  1217. ts.Nsec = nanotime % nsec_per_sec
  1218. } else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
  1219. var tm Tms
  1220. _, err := Times(&tm)
  1221. if err != nil {
  1222. return EFAULT
  1223. }
  1224. ts.Sec = int64(tm.Utime / ticks_per_sec)
  1225. ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
  1226. } else {
  1227. return EINVAL
  1228. }
  1229. return nil
  1230. }
  1231. func Statfs(path string, stat *Statfs_t) (err error) {
  1232. fd, err := open(path, O_RDONLY, 0)
  1233. defer Close(fd)
  1234. if err != nil {
  1235. return err
  1236. }
  1237. return Fstatfs(fd, stat)
  1238. }
  1239. var (
  1240. Stdin = 0
  1241. Stdout = 1
  1242. Stderr = 2
  1243. )
  1244. // Do the interface allocations only once for common
  1245. // Errno values.
  1246. var (
  1247. errEAGAIN error = syscall.EAGAIN
  1248. errEINVAL error = syscall.EINVAL
  1249. errENOENT error = syscall.ENOENT
  1250. )
  1251. var (
  1252. signalNameMapOnce sync.Once
  1253. signalNameMap map[string]syscall.Signal
  1254. )
  1255. // errnoErr returns common boxed Errno values, to prevent
  1256. // allocations at runtime.
  1257. func errnoErr(e Errno) error {
  1258. switch e {
  1259. case 0:
  1260. return nil
  1261. case EAGAIN:
  1262. return errEAGAIN
  1263. case EINVAL:
  1264. return errEINVAL
  1265. case ENOENT:
  1266. return errENOENT
  1267. }
  1268. return e
  1269. }
  1270. // ErrnoName returns the error name for error number e.
  1271. func ErrnoName(e Errno) string {
  1272. i := sort.Search(len(errorList), func(i int) bool {
  1273. return errorList[i].num >= e
  1274. })
  1275. if i < len(errorList) && errorList[i].num == e {
  1276. return errorList[i].name
  1277. }
  1278. return ""
  1279. }
  1280. // SignalName returns the signal name for signal number s.
  1281. func SignalName(s syscall.Signal) string {
  1282. i := sort.Search(len(signalList), func(i int) bool {
  1283. return signalList[i].num >= s
  1284. })
  1285. if i < len(signalList) && signalList[i].num == s {
  1286. return signalList[i].name
  1287. }
  1288. return ""
  1289. }
  1290. // SignalNum returns the syscall.Signal for signal named s,
  1291. // or 0 if a signal with such name is not found.
  1292. // The signal name should start with "SIG".
  1293. func SignalNum(s string) syscall.Signal {
  1294. signalNameMapOnce.Do(func() {
  1295. signalNameMap = make(map[string]syscall.Signal, len(signalList))
  1296. for _, signal := range signalList {
  1297. signalNameMap[signal.name] = signal.num
  1298. }
  1299. })
  1300. return signalNameMap[s]
  1301. }
  1302. // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
  1303. func clen(n []byte) int {
  1304. i := bytes.IndexByte(n, 0)
  1305. if i == -1 {
  1306. i = len(n)
  1307. }
  1308. return i
  1309. }
  1310. // Mmap manager, for use by operating system-specific implementations.
  1311. type mmapper struct {
  1312. sync.Mutex
  1313. active map[*byte][]byte // active mappings; key is last byte in mapping
  1314. mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
  1315. munmap func(addr uintptr, length uintptr) error
  1316. }
  1317. func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  1318. if length <= 0 {
  1319. return nil, EINVAL
  1320. }
  1321. // Map the requested memory.
  1322. addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
  1323. if errno != nil {
  1324. return nil, errno
  1325. }
  1326. // Slice memory layout
  1327. var sl = struct {
  1328. addr uintptr
  1329. len int
  1330. cap int
  1331. }{addr, length, length}
  1332. // Use unsafe to turn sl into a []byte.
  1333. b := *(*[]byte)(unsafe.Pointer(&sl))
  1334. // Register mapping in m and return it.
  1335. p := &b[cap(b)-1]
  1336. m.Lock()
  1337. defer m.Unlock()
  1338. m.active[p] = b
  1339. return b, nil
  1340. }
  1341. func (m *mmapper) Munmap(data []byte) (err error) {
  1342. if len(data) == 0 || len(data) != cap(data) {
  1343. return EINVAL
  1344. }
  1345. // Find the base of the mapping.
  1346. p := &data[cap(data)-1]
  1347. m.Lock()
  1348. defer m.Unlock()
  1349. b := m.active[p]
  1350. if b == nil || &b[0] != &data[0] {
  1351. return EINVAL
  1352. }
  1353. // Unmap the memory and update m.
  1354. if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
  1355. return errno
  1356. }
  1357. delete(m.active, p)
  1358. return nil
  1359. }
  1360. func Read(fd int, p []byte) (n int, err error) {
  1361. n, err = read(fd, p)
  1362. if raceenabled {
  1363. if n > 0 {
  1364. raceWriteRange(unsafe.Pointer(&p[0]), n)
  1365. }
  1366. if err == nil {
  1367. raceAcquire(unsafe.Pointer(&ioSync))
  1368. }
  1369. }
  1370. return
  1371. }
  1372. func Write(fd int, p []byte) (n int, err error) {
  1373. if raceenabled {
  1374. raceReleaseMerge(unsafe.Pointer(&ioSync))
  1375. }
  1376. n, err = write(fd, p)
  1377. if raceenabled && n > 0 {
  1378. raceReadRange(unsafe.Pointer(&p[0]), n)
  1379. }
  1380. return
  1381. }
  1382. // For testing: clients can set this flag to force
  1383. // creation of IPv6 sockets to return EAFNOSUPPORT.
  1384. var SocketDisableIPv6 bool
  1385. // Sockaddr represents a socket address.
  1386. type Sockaddr interface {
  1387. sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
  1388. }
  1389. // SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
  1390. type SockaddrInet4 struct {
  1391. Port int
  1392. Addr [4]byte
  1393. raw RawSockaddrInet4
  1394. }
  1395. // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
  1396. type SockaddrInet6 struct {
  1397. Port int
  1398. ZoneId uint32
  1399. Addr [16]byte
  1400. raw RawSockaddrInet6
  1401. }
  1402. // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
  1403. type SockaddrUnix struct {
  1404. Name string
  1405. raw RawSockaddrUnix
  1406. }
  1407. func Bind(fd int, sa Sockaddr) (err error) {
  1408. ptr, n, err := sa.sockaddr()
  1409. if err != nil {
  1410. return err
  1411. }
  1412. return bind(fd, ptr, n)
  1413. }
  1414. func Connect(fd int, sa Sockaddr) (err error) {
  1415. ptr, n, err := sa.sockaddr()
  1416. if err != nil {
  1417. return err
  1418. }
  1419. return connect(fd, ptr, n)
  1420. }
  1421. func Getpeername(fd int) (sa Sockaddr, err error) {
  1422. var rsa RawSockaddrAny
  1423. var len _Socklen = SizeofSockaddrAny
  1424. if err = getpeername(fd, &rsa, &len); err != nil {
  1425. return
  1426. }
  1427. return anyToSockaddr(fd, &rsa)
  1428. }
  1429. func GetsockoptByte(fd, level, opt int) (value byte, err error) {
  1430. var n byte
  1431. vallen := _Socklen(1)
  1432. err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1433. return n, err
  1434. }
  1435. func GetsockoptInt(fd, level, opt int) (value int, err error) {
  1436. var n int32
  1437. vallen := _Socklen(4)
  1438. err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1439. return int(n), err
  1440. }
  1441. func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
  1442. vallen := _Socklen(4)
  1443. err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
  1444. return value, err
  1445. }
  1446. func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
  1447. var value IPMreq
  1448. vallen := _Socklen(SizeofIPMreq)
  1449. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1450. return &value, err
  1451. }
  1452. func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
  1453. var value IPv6Mreq
  1454. vallen := _Socklen(SizeofIPv6Mreq)
  1455. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1456. return &value, err
  1457. }
  1458. func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
  1459. var value IPv6MTUInfo
  1460. vallen := _Socklen(SizeofIPv6MTUInfo)
  1461. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1462. return &value, err
  1463. }
  1464. func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
  1465. var value ICMPv6Filter
  1466. vallen := _Socklen(SizeofICMPv6Filter)
  1467. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1468. return &value, err
  1469. }
  1470. func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
  1471. var linger Linger
  1472. vallen := _Socklen(SizeofLinger)
  1473. err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
  1474. return &linger, err
  1475. }
  1476. func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
  1477. var tv Timeval
  1478. vallen := _Socklen(unsafe.Sizeof(tv))
  1479. err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
  1480. return &tv, err
  1481. }
  1482. func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
  1483. var n uint64
  1484. vallen := _Socklen(8)
  1485. err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1486. return n, err
  1487. }
  1488. func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
  1489. var rsa RawSockaddrAny
  1490. var len _Socklen = SizeofSockaddrAny
  1491. if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
  1492. return
  1493. }
  1494. if rsa.Addr.Family != AF_UNSPEC {
  1495. from, err = anyToSockaddr(fd, &rsa)
  1496. }
  1497. return
  1498. }
  1499. func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
  1500. ptr, n, err := to.sockaddr()
  1501. if err != nil {
  1502. return err
  1503. }
  1504. return sendto(fd, p, flags, ptr, n)
  1505. }
  1506. func SetsockoptByte(fd, level, opt int, value byte) (err error) {
  1507. return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
  1508. }
  1509. func SetsockoptInt(fd, level, opt int, value int) (err error) {
  1510. var n = int32(value)
  1511. return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
  1512. }
  1513. func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
  1514. return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
  1515. }
  1516. func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
  1517. return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
  1518. }
  1519. func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
  1520. return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
  1521. }
  1522. func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
  1523. return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
  1524. }
  1525. func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
  1526. return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
  1527. }
  1528. func SetsockoptString(fd, level, opt int, s string) (err error) {
  1529. var p unsafe.Pointer
  1530. if len(s) > 0 {
  1531. p = unsafe.Pointer(&[]byte(s)[0])
  1532. }
  1533. return setsockopt(fd, level, opt, p, uintptr(len(s)))
  1534. }
  1535. func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
  1536. return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
  1537. }
  1538. func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
  1539. return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
  1540. }
  1541. func Socket(domain, typ, proto int) (fd int, err error) {
  1542. if domain == AF_INET6 && SocketDisableIPv6 {
  1543. return -1, EAFNOSUPPORT
  1544. }
  1545. fd, err = socket(domain, typ, proto)
  1546. return
  1547. }
  1548. func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
  1549. var fdx [2]int32
  1550. err = socketpair(domain, typ, proto, &fdx)
  1551. if err == nil {
  1552. fd[0] = int(fdx[0])
  1553. fd[1] = int(fdx[1])
  1554. }
  1555. return
  1556. }
  1557. var ioSync int64
  1558. func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
  1559. func SetNonblock(fd int, nonblocking bool) (err error) {
  1560. flag, err := fcntl(fd, F_GETFL, 0)
  1561. if err != nil {
  1562. return err
  1563. }
  1564. if nonblocking {
  1565. flag |= O_NONBLOCK
  1566. } else {
  1567. flag &= ^O_NONBLOCK
  1568. }
  1569. _, err = fcntl(fd, F_SETFL, flag)
  1570. return err
  1571. }
  1572. // Exec calls execve(2), which replaces the calling executable in the process
  1573. // tree. argv0 should be the full path to an executable ("/bin/ls") and the
  1574. // executable name should also be the first argument in argv (["ls", "-l"]).
  1575. // envv are the environment variables that should be passed to the new
  1576. // process (["USER=go", "PWD=/tmp"]).
  1577. func Exec(argv0 string, argv []string, envv []string) error {
  1578. return syscall.Exec(argv0, argv, envv)
  1579. }
  1580. func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  1581. if needspace := 8 - len(fstype); needspace <= 0 {
  1582. fstype = fstype[:8]
  1583. } else {
  1584. fstype += " "[:needspace]
  1585. }
  1586. return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
  1587. }
  1588. func Unmount(name string, mtm int) (err error) {
  1589. // mountpoint is always a full path and starts with a '/'
  1590. // check if input string is not a mountpoint but a filesystem name
  1591. if name[0] != '/' {
  1592. return unmount(name, mtm)
  1593. }
  1594. // treat name as mountpoint
  1595. b2s := func(arr []byte) string {
  1596. nulli := bytes.IndexByte(arr, 0)
  1597. if nulli == -1 {
  1598. return string(arr)
  1599. } else {
  1600. return string(arr[:nulli])
  1601. }
  1602. }
  1603. var buffer struct {
  1604. header W_Mnth
  1605. fsinfo [64]W_Mntent
  1606. }
  1607. fsCount, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
  1608. if err != nil {
  1609. return err
  1610. }
  1611. if fsCount == 0 {
  1612. return EINVAL
  1613. }
  1614. for i := 0; i < fsCount; i++ {
  1615. if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
  1616. err = unmount(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
  1617. break
  1618. }
  1619. }
  1620. return err
  1621. }
  1622. func fdToPath(dirfd int) (path string, err error) {
  1623. var buffer [1024]byte
  1624. // w_ctrl()
  1625. ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
  1626. []uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
  1627. if ret == 0 {
  1628. zb := bytes.IndexByte(buffer[:], 0)
  1629. if zb == -1 {
  1630. zb = len(buffer)
  1631. }
  1632. // __e2a_l()
  1633. runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
  1634. []uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
  1635. return string(buffer[:zb]), nil
  1636. }
  1637. // __errno()
  1638. errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
  1639. []uintptr{}))))
  1640. // __errno2()
  1641. errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
  1642. []uintptr{}))
  1643. // strerror_r()
  1644. ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
  1645. []uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
  1646. if ret == 0 {
  1647. zb := bytes.IndexByte(buffer[:], 0)
  1648. if zb == -1 {
  1649. zb = len(buffer)
  1650. }
  1651. return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
  1652. } else {
  1653. return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
  1654. }
  1655. }
  1656. func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
  1657. var d Dirent
  1658. d.Ino = uint64(dirent.Ino)
  1659. offset, err := Telldir(dir)
  1660. if err != nil {
  1661. return d, err
  1662. }
  1663. d.Off = int64(offset)
  1664. s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
  1665. copy(d.Name[:], s)
  1666. d.Reclen = uint16(24 + len(d.NameString()))
  1667. var st Stat_t
  1668. path = path + "/" + s
  1669. err = Lstat(path, &st)
  1670. if err != nil {
  1671. return d, err
  1672. }
  1673. d.Type = uint8(st.Mode >> 24)
  1674. return d, err
  1675. }
  1676. func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
  1677. // Simulation of Getdirentries port from the Darwin implementation.
  1678. // COMMENTS FROM DARWIN:
  1679. // It's not the full required semantics, but should handle the case
  1680. // of calling Getdirentries or ReadDirent repeatedly.
  1681. // It won't handle assigning the results of lseek to *basep, or handle
  1682. // the directory being edited underfoot.
  1683. skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
  1684. if err != nil {
  1685. return 0, err
  1686. }
  1687. // Get path from fd to avoid unavailable call (fdopendir)
  1688. path, err := fdToPath(fd)
  1689. if err != nil {
  1690. return 0, err
  1691. }
  1692. d, err := Opendir(path)
  1693. if err != nil {
  1694. return 0, err
  1695. }
  1696. defer Closedir(d)
  1697. var cnt int64
  1698. for {
  1699. var entryLE direntLE
  1700. var entrypLE *direntLE
  1701. e := readdir_r(d, &entryLE, &entrypLE)
  1702. if e != nil {
  1703. return n, e
  1704. }
  1705. if entrypLE == nil {
  1706. break
  1707. }
  1708. if skip > 0 {
  1709. skip--
  1710. cnt++
  1711. continue
  1712. }
  1713. // Dirent on zos has a different structure
  1714. entry, e := direntLeToDirentUnix(&entryLE, d, path)
  1715. if e != nil {
  1716. return n, e
  1717. }
  1718. reclen := int(entry.Reclen)
  1719. if reclen > len(buf) {
  1720. // Not enough room. Return for now.
  1721. // The counter will let us know where we should start up again.
  1722. // Note: this strategy for suspending in the middle and
  1723. // restarting is O(n^2) in the length of the directory. Oh well.
  1724. break
  1725. }
  1726. // Copy entry into return buffer.
  1727. s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
  1728. copy(buf, s)
  1729. buf = buf[reclen:]
  1730. n += reclen
  1731. cnt++
  1732. }
  1733. // Set the seek offset of the input fd to record
  1734. // how many files we've already returned.
  1735. _, err = Seek(fd, cnt, 0 /* SEEK_SET */)
  1736. if err != nil {
  1737. return n, err
  1738. }
  1739. return n, nil
  1740. }
  1741. func ReadDirent(fd int, buf []byte) (n int, err error) {
  1742. var base = (*uintptr)(unsafe.Pointer(new(uint64)))
  1743. return Getdirentries(fd, buf, base)
  1744. }
  1745. func direntIno(buf []byte) (uint64, bool) {
  1746. return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
  1747. }
  1748. func direntReclen(buf []byte) (uint64, bool) {
  1749. return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
  1750. }
  1751. func direntNamlen(buf []byte) (uint64, bool) {
  1752. reclen, ok := direntReclen(buf)
  1753. if !ok {
  1754. return 0, false
  1755. }
  1756. return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
  1757. }