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_zos_s390x.go 53KB

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