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

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