syscall_zos_s390x.go 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213
  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. // Many of the following syscalls are not available on all versions of z/OS.
  6. // Some missing calls have legacy implementations/simulations but others
  7. // will be missing completely. To achieve consistent failing behaviour on
  8. // legacy systems, we first test the function pointer via a safeloading
  9. // mechanism to see if the function exists on a given system. Then execution
  10. // is branched to either continue the function call, or return an error.
  11. package unix
  12. import (
  13. "bytes"
  14. "fmt"
  15. "os"
  16. "reflect"
  17. "regexp"
  18. "runtime"
  19. "sort"
  20. "strings"
  21. "sync"
  22. "syscall"
  23. "unsafe"
  24. )
  25. //go:noescape
  26. func initZosLibVec()
  27. //go:noescape
  28. func GetZosLibVec() uintptr
  29. func init() {
  30. initZosLibVec()
  31. r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACE\x00"))[0])))
  32. if r0 != 0 {
  33. n, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
  34. ZosTraceLevel = int(n)
  35. r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACEFD\x00"))[0])))
  36. if r0 != 0 {
  37. fd, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
  38. f := os.NewFile(fd, "zostracefile")
  39. if f != nil {
  40. ZosTracefile = f
  41. }
  42. }
  43. }
  44. }
  45. //go:noescape
  46. func CallLeFuncWithErr(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
  47. //go:noescape
  48. func CallLeFuncWithPtrReturn(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
  49. // -------------------------------
  50. // pointer validity test
  51. // good pointer returns 0
  52. // bad pointer returns 1
  53. //
  54. //go:nosplit
  55. func ptrtest(uintptr) uint64
  56. // Load memory at ptr location with error handling if the location is invalid
  57. //
  58. //go:noescape
  59. func safeload(ptr uintptr) (value uintptr, error uintptr)
  60. const (
  61. entrypointLocationOffset = 8 // From function descriptor
  62. xplinkEyecatcher = 0x00c300c500c500f1 // ".C.E.E.1"
  63. eyecatcherOffset = 16 // From function entrypoint (negative)
  64. ppa1LocationOffset = 8 // From function entrypoint (negative)
  65. nameLenOffset = 0x14 // From PPA1 start
  66. nameOffset = 0x16 // From PPA1 start
  67. )
  68. func getPpaOffset(funcptr uintptr) int64 {
  69. entrypoint, err := safeload(funcptr + entrypointLocationOffset)
  70. if err != 0 {
  71. return -1
  72. }
  73. // XPLink functions have ".C.E.E.1" as the first 8 bytes (EBCDIC)
  74. val, err := safeload(entrypoint - eyecatcherOffset)
  75. if err != 0 {
  76. return -1
  77. }
  78. if val != xplinkEyecatcher {
  79. return -1
  80. }
  81. ppaoff, err := safeload(entrypoint - ppa1LocationOffset)
  82. if err != 0 {
  83. return -1
  84. }
  85. ppaoff >>= 32
  86. return int64(ppaoff)
  87. }
  88. //-------------------------------
  89. // function descriptor pointer validity test
  90. // good pointer returns 0
  91. // bad pointer returns 1
  92. // TODO: currently mksyscall_zos_s390x.go generate empty string for funcName
  93. // have correct funcName pass to the funcptrtest function
  94. func funcptrtest(funcptr uintptr, funcName string) uint64 {
  95. entrypoint, err := safeload(funcptr + entrypointLocationOffset)
  96. if err != 0 {
  97. return 1
  98. }
  99. ppaoff := getPpaOffset(funcptr)
  100. if ppaoff == -1 {
  101. return 1
  102. }
  103. // PPA1 offset value is from the start of the entire function block, not the entrypoint
  104. ppa1 := (entrypoint - eyecatcherOffset) + uintptr(ppaoff)
  105. nameLen, err := safeload(ppa1 + nameLenOffset)
  106. if err != 0 {
  107. return 1
  108. }
  109. nameLen >>= 48
  110. if nameLen > 128 {
  111. return 1
  112. }
  113. // no function name input to argument end here
  114. if funcName == "" {
  115. return 0
  116. }
  117. var funcname [128]byte
  118. for i := 0; i < int(nameLen); i += 8 {
  119. v, err := safeload(ppa1 + nameOffset + uintptr(i))
  120. if err != 0 {
  121. return 1
  122. }
  123. funcname[i] = byte(v >> 56)
  124. funcname[i+1] = byte(v >> 48)
  125. funcname[i+2] = byte(v >> 40)
  126. funcname[i+3] = byte(v >> 32)
  127. funcname[i+4] = byte(v >> 24)
  128. funcname[i+5] = byte(v >> 16)
  129. funcname[i+6] = byte(v >> 8)
  130. funcname[i+7] = byte(v)
  131. }
  132. runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l
  133. []uintptr{uintptr(unsafe.Pointer(&funcname[0])), nameLen})
  134. name := string(funcname[:nameLen])
  135. if name != funcName {
  136. return 1
  137. }
  138. return 0
  139. }
  140. // For detection of capabilities on a system.
  141. // Is function descriptor f a valid function?
  142. func isValidLeFunc(f uintptr) error {
  143. ret := funcptrtest(f, "")
  144. if ret != 0 {
  145. return fmt.Errorf("Bad pointer, not an LE function ")
  146. }
  147. return nil
  148. }
  149. // Retrieve function name from descriptor
  150. func getLeFuncName(f uintptr) (string, error) {
  151. // assume it has been checked, only check ppa1 validity here
  152. entry := ((*[2]uintptr)(unsafe.Pointer(f)))[1]
  153. preamp := ((*[4]uint32)(unsafe.Pointer(entry - eyecatcherOffset)))
  154. offsetPpa1 := preamp[2]
  155. if offsetPpa1 > 0x0ffff {
  156. return "", fmt.Errorf("PPA1 offset seems too big 0x%x\n", offsetPpa1)
  157. }
  158. ppa1 := uintptr(unsafe.Pointer(preamp)) + uintptr(offsetPpa1)
  159. res := ptrtest(ppa1)
  160. if res != 0 {
  161. return "", fmt.Errorf("PPA1 address not valid")
  162. }
  163. size := *(*uint16)(unsafe.Pointer(ppa1 + nameLenOffset))
  164. if size > 128 {
  165. return "", fmt.Errorf("Function name seems too long, length=%d\n", size)
  166. }
  167. var name [128]byte
  168. funcname := (*[128]byte)(unsafe.Pointer(ppa1 + nameOffset))
  169. copy(name[0:size], funcname[0:size])
  170. runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l
  171. []uintptr{uintptr(unsafe.Pointer(&name[0])), uintptr(size)})
  172. return string(name[:size]), nil
  173. }
  174. // Check z/OS version
  175. func zosLeVersion() (version, release uint32) {
  176. p1 := (*(*uintptr)(unsafe.Pointer(uintptr(1208)))) >> 32
  177. p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 88)))
  178. p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 8)))
  179. p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 984)))
  180. vrm := *(*uint32)(unsafe.Pointer(p1 + 80))
  181. version = (vrm & 0x00ff0000) >> 16
  182. release = (vrm & 0x0000ff00) >> 8
  183. return
  184. }
  185. // returns a zos C FILE * for stdio fd 0, 1, 2
  186. func ZosStdioFilep(fd int32) uintptr {
  187. return uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(uint64(*(*uint32)(unsafe.Pointer(uintptr(1208)))) + 80))) + uint64((fd+2)<<3))))))))
  188. }
  189. func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
  190. stat.Dev = uint64(statLE.Dev)
  191. stat.Ino = uint64(statLE.Ino)
  192. stat.Nlink = uint64(statLE.Nlink)
  193. stat.Mode = uint32(statLE.Mode)
  194. stat.Uid = uint32(statLE.Uid)
  195. stat.Gid = uint32(statLE.Gid)
  196. stat.Rdev = uint64(statLE.Rdev)
  197. stat.Size = statLE.Size
  198. stat.Atim.Sec = int64(statLE.Atim)
  199. stat.Atim.Nsec = 0 //zos doesn't return nanoseconds
  200. stat.Mtim.Sec = int64(statLE.Mtim)
  201. stat.Mtim.Nsec = 0 //zos doesn't return nanoseconds
  202. stat.Ctim.Sec = int64(statLE.Ctim)
  203. stat.Ctim.Nsec = 0 //zos doesn't return nanoseconds
  204. stat.Blksize = int64(statLE.Blksize)
  205. stat.Blocks = statLE.Blocks
  206. }
  207. func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
  208. func svcLoad(name *byte) unsafe.Pointer
  209. func svcUnload(name *byte, fnptr unsafe.Pointer) int64
  210. func (d *Dirent) NameString() string {
  211. if d == nil {
  212. return ""
  213. }
  214. s := string(d.Name[:])
  215. idx := strings.IndexByte(s, 0)
  216. if idx == -1 {
  217. return s
  218. } else {
  219. return s[:idx]
  220. }
  221. }
  222. func DecodeData(dest []byte, sz int, val uint64) {
  223. for i := 0; i < sz; i++ {
  224. dest[sz-1-i] = byte((val >> (uint64(i * 8))) & 0xff)
  225. }
  226. }
  227. func EncodeData(data []byte) uint64 {
  228. var value uint64
  229. sz := len(data)
  230. for i := 0; i < sz; i++ {
  231. value |= uint64(data[i]) << uint64(((sz - i - 1) * 8))
  232. }
  233. return value
  234. }
  235. func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
  236. if sa.Port < 0 || sa.Port > 0xFFFF {
  237. return nil, 0, EINVAL
  238. }
  239. sa.raw.Len = SizeofSockaddrInet4
  240. sa.raw.Family = AF_INET
  241. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  242. p[0] = byte(sa.Port >> 8)
  243. p[1] = byte(sa.Port)
  244. for i := 0; i < len(sa.Addr); i++ {
  245. sa.raw.Addr[i] = sa.Addr[i]
  246. }
  247. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  248. }
  249. func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
  250. if sa.Port < 0 || sa.Port > 0xFFFF {
  251. return nil, 0, EINVAL
  252. }
  253. sa.raw.Len = SizeofSockaddrInet6
  254. sa.raw.Family = AF_INET6
  255. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  256. p[0] = byte(sa.Port >> 8)
  257. p[1] = byte(sa.Port)
  258. sa.raw.Scope_id = sa.ZoneId
  259. for i := 0; i < len(sa.Addr); i++ {
  260. sa.raw.Addr[i] = sa.Addr[i]
  261. }
  262. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  263. }
  264. func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
  265. name := sa.Name
  266. n := len(name)
  267. if n >= len(sa.raw.Path) || n == 0 {
  268. return nil, 0, EINVAL
  269. }
  270. sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
  271. sa.raw.Family = AF_UNIX
  272. for i := 0; i < n; i++ {
  273. sa.raw.Path[i] = int8(name[i])
  274. }
  275. return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
  276. }
  277. func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
  278. // TODO(neeilan): Implement use of first param (fd)
  279. switch rsa.Addr.Family {
  280. case AF_UNIX:
  281. pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
  282. sa := new(SockaddrUnix)
  283. // For z/OS, only replace NUL with @ when the
  284. // length is not zero.
  285. if pp.Len != 0 && pp.Path[0] == 0 {
  286. // "Abstract" Unix domain socket.
  287. // Rewrite leading NUL as @ for textual display.
  288. // (This is the standard convention.)
  289. // Not friendly to overwrite in place,
  290. // but the callers below don't care.
  291. pp.Path[0] = '@'
  292. }
  293. // Assume path ends at NUL.
  294. //
  295. // For z/OS, the length of the name is a field
  296. // in the structure. To be on the safe side, we
  297. // will still scan the name for a NUL but only
  298. // to the length provided in the structure.
  299. //
  300. // This is not technically the Linux semantics for
  301. // abstract Unix domain sockets--they are supposed
  302. // to be uninterpreted fixed-size binary blobs--but
  303. // everyone uses this convention.
  304. n := 0
  305. for n < int(pp.Len) && pp.Path[n] != 0 {
  306. n++
  307. }
  308. sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
  309. return sa, nil
  310. case AF_INET:
  311. pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
  312. sa := new(SockaddrInet4)
  313. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  314. sa.Port = int(p[0])<<8 + int(p[1])
  315. for i := 0; i < len(sa.Addr); i++ {
  316. sa.Addr[i] = pp.Addr[i]
  317. }
  318. return sa, nil
  319. case AF_INET6:
  320. pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
  321. sa := new(SockaddrInet6)
  322. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  323. sa.Port = int(p[0])<<8 + int(p[1])
  324. sa.ZoneId = pp.Scope_id
  325. for i := 0; i < len(sa.Addr); i++ {
  326. sa.Addr[i] = pp.Addr[i]
  327. }
  328. return sa, nil
  329. }
  330. return nil, EAFNOSUPPORT
  331. }
  332. func Accept(fd int) (nfd int, sa Sockaddr, err error) {
  333. var rsa RawSockaddrAny
  334. var len _Socklen = SizeofSockaddrAny
  335. nfd, err = accept(fd, &rsa, &len)
  336. if err != nil {
  337. return
  338. }
  339. // TODO(neeilan): Remove 0 in call
  340. sa, err = anyToSockaddr(0, &rsa)
  341. if err != nil {
  342. Close(nfd)
  343. nfd = 0
  344. }
  345. return
  346. }
  347. func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
  348. var rsa RawSockaddrAny
  349. var len _Socklen = SizeofSockaddrAny
  350. nfd, err = accept4(fd, &rsa, &len, flags)
  351. if err != nil {
  352. return
  353. }
  354. if len > SizeofSockaddrAny {
  355. panic("RawSockaddrAny too small")
  356. }
  357. // TODO(neeilan): Remove 0 in call
  358. sa, err = anyToSockaddr(0, &rsa)
  359. if err != nil {
  360. Close(nfd)
  361. nfd = 0
  362. }
  363. return
  364. }
  365. func Ctermid() (tty string, err error) {
  366. var termdev [1025]byte
  367. runtime.EnterSyscall()
  368. r0, err2, err1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___CTERMID_A<<4, uintptr(unsafe.Pointer(&termdev[0])))
  369. runtime.ExitSyscall()
  370. if r0 == 0 {
  371. return "", fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
  372. }
  373. s := string(termdev[:])
  374. idx := strings.Index(s, string(rune(0)))
  375. if idx == -1 {
  376. tty = s
  377. } else {
  378. tty = s[:idx]
  379. }
  380. return
  381. }
  382. func (iov *Iovec) SetLen(length int) {
  383. iov.Len = uint64(length)
  384. }
  385. func (msghdr *Msghdr) SetControllen(length int) {
  386. msghdr.Controllen = int32(length)
  387. }
  388. func (cmsg *Cmsghdr) SetLen(length int) {
  389. cmsg.Len = int32(length)
  390. }
  391. //sys fcntl(fd int, cmd int, arg int) (val int, err error)
  392. //sys Flistxattr(fd int, dest []byte) (sz int, err error) = SYS___FLISTXATTR_A
  393. //sys Fremovexattr(fd int, attr string) (err error) = SYS___FREMOVEXATTR_A
  394. //sys read(fd int, p []byte) (n int, err error)
  395. //sys write(fd int, p []byte) (n int, err error)
  396. //sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) = SYS___FGETXATTR_A
  397. //sys Fsetxattr(fd int, attr string, data []byte, flag int) (err error) = SYS___FSETXATTR_A
  398. //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
  399. //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = SYS___ACCEPT4_A
  400. //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
  401. //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
  402. //sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
  403. //sysnb setgroups(n int, list *_Gid_t) (err error)
  404. //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
  405. //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
  406. //sysnb socket(domain int, typ int, proto int) (fd int, err error)
  407. //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
  408. //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
  409. //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
  410. //sys Removexattr(path string, attr string) (err error) = SYS___REMOVEXATTR_A
  411. //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
  412. //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
  413. //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
  414. //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A
  415. //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP
  416. //sys munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
  417. //sys ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL
  418. //sys ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = SYS_IOCTL
  419. //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) = SYS_SHMAT
  420. //sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) = SYS_SHMCTL64
  421. //sys shmdt(addr uintptr) (err error) = SYS_SHMDT
  422. //sys shmget(key int, size int, flag int) (id int, err error) = SYS_SHMGET
  423. //sys Access(path string, mode uint32) (err error) = SYS___ACCESS_A
  424. //sys Chdir(path string) (err error) = SYS___CHDIR_A
  425. //sys Chown(path string, uid int, gid int) (err error) = SYS___CHOWN_A
  426. //sys Chmod(path string, mode uint32) (err error) = SYS___CHMOD_A
  427. //sys Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
  428. //sys Dup(oldfd int) (fd int, err error)
  429. //sys Dup2(oldfd int, newfd int) (err error)
  430. //sys Dup3(oldfd int, newfd int, flags int) (err error) = SYS_DUP3
  431. //sys Dirfd(dirp uintptr) (fd int, err error) = SYS_DIRFD
  432. //sys EpollCreate(size int) (fd int, err error) = SYS_EPOLL_CREATE
  433. //sys EpollCreate1(flags int) (fd int, err error) = SYS_EPOLL_CREATE1
  434. //sys EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) = SYS_EPOLL_CTL
  435. //sys EpollPwait(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error) = SYS_EPOLL_PWAIT
  436. //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_WAIT
  437. //sys Errno2() (er2 int) = SYS___ERRNO2
  438. //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD
  439. //sys Exit(code int)
  440. //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FACCESSAT_A
  441. func Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
  442. return Faccessat(dirfd, path, mode, flags)
  443. }
  444. //sys Fchdir(fd int) (err error)
  445. //sys Fchmod(fd int, mode uint32) (err error)
  446. //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FCHMODAT_A
  447. //sys Fchown(fd int, uid int, gid int) (err error)
  448. //sys Fchownat(fd int, path string, uid int, gid int, flags int) (err error) = SYS___FCHOWNAT_A
  449. //sys FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL
  450. //sys Fdatasync(fd int) (err error) = SYS_FDATASYNC
  451. //sys fstat(fd int, stat *Stat_LE_t) (err error)
  452. //sys fstatat(dirfd int, path string, stat *Stat_LE_t, flags int) (err error) = SYS___FSTATAT_A
  453. func Fstat(fd int, stat *Stat_t) (err error) {
  454. var statLE Stat_LE_t
  455. err = fstat(fd, &statLE)
  456. copyStat(stat, &statLE)
  457. return
  458. }
  459. func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
  460. var statLE Stat_LE_t
  461. err = fstatat(dirfd, path, &statLE, flags)
  462. copyStat(stat, &statLE)
  463. return
  464. }
  465. func impl_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
  466. var _p0 *byte
  467. _p0, err = BytePtrFromString(path)
  468. if err != nil {
  469. return
  470. }
  471. var _p1 *byte
  472. _p1, err = BytePtrFromString(attr)
  473. if err != nil {
  474. return
  475. }
  476. var _p2 unsafe.Pointer
  477. if len(dest) > 0 {
  478. _p2 = unsafe.Pointer(&dest[0])
  479. } else {
  480. _p2 = unsafe.Pointer(&_zero)
  481. }
  482. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)))
  483. sz = int(r0)
  484. if int64(r0) == -1 {
  485. err = errnoErr2(e1, e2)
  486. }
  487. return
  488. }
  489. //go:nosplit
  490. func get_GetxattrAddr() *(func(path string, attr string, dest []byte) (sz int, err error))
  491. var Getxattr = enter_Getxattr
  492. func enter_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
  493. funcref := get_GetxattrAddr()
  494. if validGetxattr() {
  495. *funcref = impl_Getxattr
  496. } else {
  497. *funcref = error_Getxattr
  498. }
  499. return (*funcref)(path, attr, dest)
  500. }
  501. func error_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
  502. return -1, ENOSYS
  503. }
  504. func validGetxattr() bool {
  505. if funcptrtest(GetZosLibVec()+SYS___GETXATTR_A<<4, "") == 0 {
  506. if name, err := getLeFuncName(GetZosLibVec() + SYS___GETXATTR_A<<4); err == nil {
  507. return name == "__getxattr_a"
  508. }
  509. }
  510. return false
  511. }
  512. //sys Lgetxattr(link string, attr string, dest []byte) (sz int, err error) = SYS___LGETXATTR_A
  513. //sys Lsetxattr(path string, attr string, data []byte, flags int) (err error) = SYS___LSETXATTR_A
  514. func impl_Setxattr(path string, attr string, data []byte, flags int) (err error) {
  515. var _p0 *byte
  516. _p0, err = BytePtrFromString(path)
  517. if err != nil {
  518. return
  519. }
  520. var _p1 *byte
  521. _p1, err = BytePtrFromString(attr)
  522. if err != nil {
  523. return
  524. }
  525. var _p2 unsafe.Pointer
  526. if len(data) > 0 {
  527. _p2 = unsafe.Pointer(&data[0])
  528. } else {
  529. _p2 = unsafe.Pointer(&_zero)
  530. }
  531. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags))
  532. if int64(r0) == -1 {
  533. err = errnoErr2(e1, e2)
  534. }
  535. return
  536. }
  537. //go:nosplit
  538. func get_SetxattrAddr() *(func(path string, attr string, data []byte, flags int) (err error))
  539. var Setxattr = enter_Setxattr
  540. func enter_Setxattr(path string, attr string, data []byte, flags int) (err error) {
  541. funcref := get_SetxattrAddr()
  542. if validSetxattr() {
  543. *funcref = impl_Setxattr
  544. } else {
  545. *funcref = error_Setxattr
  546. }
  547. return (*funcref)(path, attr, data, flags)
  548. }
  549. func error_Setxattr(path string, attr string, data []byte, flags int) (err error) {
  550. return ENOSYS
  551. }
  552. func validSetxattr() bool {
  553. if funcptrtest(GetZosLibVec()+SYS___SETXATTR_A<<4, "") == 0 {
  554. if name, err := getLeFuncName(GetZosLibVec() + SYS___SETXATTR_A<<4); err == nil {
  555. return name == "__setxattr_a"
  556. }
  557. }
  558. return false
  559. }
  560. //sys Fstatfs(fd int, buf *Statfs_t) (err error) = SYS_FSTATFS
  561. //sys Fstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS
  562. //sys Fsync(fd int) (err error)
  563. //sys Futimes(fd int, tv []Timeval) (err error) = SYS_FUTIMES
  564. //sys Futimesat(dirfd int, path string, tv []Timeval) (err error) = SYS___FUTIMESAT_A
  565. //sys Ftruncate(fd int, length int64) (err error)
  566. //sys Getrandom(buf []byte, flags int) (n int, err error) = SYS_GETRANDOM
  567. //sys InotifyInit() (fd int, err error) = SYS_INOTIFY_INIT
  568. //sys InotifyInit1(flags int) (fd int, err error) = SYS_INOTIFY_INIT1
  569. //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) = SYS___INOTIFY_ADD_WATCH_A
  570. //sys InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) = SYS_INOTIFY_RM_WATCH
  571. //sys Listxattr(path string, dest []byte) (sz int, err error) = SYS___LISTXATTR_A
  572. //sys Llistxattr(path string, dest []byte) (sz int, err error) = SYS___LLISTXATTR_A
  573. //sys Lremovexattr(path string, attr string) (err error) = SYS___LREMOVEXATTR_A
  574. //sys Lutimes(path string, tv []Timeval) (err error) = SYS___LUTIMES_A
  575. //sys Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT
  576. //sys Msync(b []byte, flags int) (err error) = SYS_MSYNC
  577. //sys Console2(cmsg *ConsMsg2, modstr *byte, concmd *uint32) (err error) = SYS___CONSOLE2
  578. // Pipe2 begin
  579. //go:nosplit
  580. func getPipe2Addr() *(func([]int, int) error)
  581. var Pipe2 = pipe2Enter
  582. func pipe2Enter(p []int, flags int) (err error) {
  583. if funcptrtest(GetZosLibVec()+SYS_PIPE2<<4, "") == 0 {
  584. *getPipe2Addr() = pipe2Impl
  585. } else {
  586. *getPipe2Addr() = pipe2Error
  587. }
  588. return (*getPipe2Addr())(p, flags)
  589. }
  590. func pipe2Impl(p []int, flags int) (err error) {
  591. var pp [2]_C_int
  592. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PIPE2<<4, uintptr(unsafe.Pointer(&pp[0])), uintptr(flags))
  593. if int64(r0) == -1 {
  594. err = errnoErr2(e1, e2)
  595. } else {
  596. p[0] = int(pp[0])
  597. p[1] = int(pp[1])
  598. }
  599. return
  600. }
  601. func pipe2Error(p []int, flags int) (err error) {
  602. return fmt.Errorf("Pipe2 is not available on this system")
  603. }
  604. // Pipe2 end
  605. //sys Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
  606. func Readdir(dir uintptr) (dirent *Dirent, err error) {
  607. runtime.EnterSyscall()
  608. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READDIR_A<<4, uintptr(dir))
  609. runtime.ExitSyscall()
  610. dirent = (*Dirent)(unsafe.Pointer(r0))
  611. if int64(r0) == -1 {
  612. err = errnoErr2(e1, e2)
  613. }
  614. return
  615. }
  616. //sys Readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) = SYS___READDIR_R_A
  617. //sys Statfs(path string, buf *Statfs_t) (err error) = SYS___STATFS_A
  618. //sys Syncfs(fd int) (err error) = SYS_SYNCFS
  619. //sys Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
  620. //sys W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
  621. //sys W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
  622. //sys mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
  623. //sys unmount_LE(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
  624. //sys Chroot(path string) (err error) = SYS___CHROOT_A
  625. //sys Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
  626. //sysnb Uname(buf *Utsname) (err error) = SYS_____OSNAME_A
  627. //sys Unshare(flags int) (err error) = SYS_UNSHARE
  628. func Ptsname(fd int) (name string, err error) {
  629. runtime.EnterSyscall()
  630. r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___PTSNAME_A<<4, uintptr(fd))
  631. runtime.ExitSyscall()
  632. if r0 == 0 {
  633. err = errnoErr2(e1, e2)
  634. } else {
  635. name = u2s(unsafe.Pointer(r0))
  636. }
  637. return
  638. }
  639. func u2s(cstr unsafe.Pointer) string {
  640. str := (*[1024]uint8)(cstr)
  641. i := 0
  642. for str[i] != 0 {
  643. i++
  644. }
  645. return string(str[:i])
  646. }
  647. func Close(fd int) (err error) {
  648. runtime.EnterSyscall()
  649. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
  650. runtime.ExitSyscall()
  651. for i := 0; e1 == EAGAIN && i < 10; i++ {
  652. runtime.EnterSyscall()
  653. CallLeFuncWithErr(GetZosLibVec()+SYS_USLEEP<<4, uintptr(10))
  654. runtime.ExitSyscall()
  655. runtime.EnterSyscall()
  656. r0, e2, e1 = CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
  657. runtime.ExitSyscall()
  658. }
  659. if r0 != 0 {
  660. err = errnoErr2(e1, e2)
  661. }
  662. return
  663. }
  664. // Dummy function: there are no semantics for Madvise on z/OS
  665. func Madvise(b []byte, advice int) (err error) {
  666. return
  667. }
  668. func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  669. return mapper.Mmap(fd, offset, length, prot, flags)
  670. }
  671. func Munmap(b []byte) (err error) {
  672. return mapper.Munmap(b)
  673. }
  674. func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
  675. xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
  676. return unsafe.Pointer(xaddr), err
  677. }
  678. func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
  679. return mapper.munmap(uintptr(addr), length)
  680. }
  681. //sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
  682. //sysnb Getgid() (gid int)
  683. //sysnb Getpid() (pid int)
  684. //sysnb Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
  685. func Getpgrp() (pid int) {
  686. pid, _ = Getpgid(0)
  687. return
  688. }
  689. //sysnb Getppid() (pid int)
  690. //sys Getpriority(which int, who int) (prio int, err error)
  691. //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
  692. //sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE
  693. func Getrusage(who int, rusage *Rusage) (err error) {
  694. var ruz rusage_zos
  695. err = getrusage(who, &ruz)
  696. //Only the first two fields of Rusage are set
  697. rusage.Utime.Sec = ruz.Utime.Sec
  698. rusage.Utime.Usec = int64(ruz.Utime.Usec)
  699. rusage.Stime.Sec = ruz.Stime.Sec
  700. rusage.Stime.Usec = int64(ruz.Stime.Usec)
  701. return
  702. }
  703. //sys Getegid() (egid int) = SYS_GETEGID
  704. //sys Geteuid() (euid int) = SYS_GETEUID
  705. //sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
  706. //sysnb Getuid() (uid int)
  707. //sysnb Kill(pid int, sig Signal) (err error)
  708. //sys Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
  709. //sys Link(path string, link string) (err error) = SYS___LINK_A
  710. //sys Linkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) = SYS___LINKAT_A
  711. //sys Listen(s int, n int) (err error)
  712. //sys lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
  713. func Lstat(path string, stat *Stat_t) (err error) {
  714. var statLE Stat_LE_t
  715. err = lstat(path, &statLE)
  716. copyStat(stat, &statLE)
  717. return
  718. }
  719. // for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/
  720. func isSpecialPath(path []byte) (v bool) {
  721. var special = [4][8]byte{
  722. {'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
  723. {'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
  724. {'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
  725. {'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
  726. var i, j int
  727. for i = 0; i < len(special); i++ {
  728. for j = 0; j < len(special[i]); j++ {
  729. if path[j] != special[i][j] {
  730. break
  731. }
  732. }
  733. if j == len(special[i]) {
  734. return true
  735. }
  736. }
  737. return false
  738. }
  739. func realpath(srcpath string, abspath []byte) (pathlen int, errno int) {
  740. var source [1024]byte
  741. copy(source[:], srcpath)
  742. source[len(srcpath)] = 0
  743. ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___REALPATH_A<<4, //__realpath_a()
  744. []uintptr{uintptr(unsafe.Pointer(&source[0])),
  745. uintptr(unsafe.Pointer(&abspath[0]))})
  746. if ret != 0 {
  747. index := bytes.IndexByte(abspath[:], byte(0))
  748. if index != -1 {
  749. return index, 0
  750. }
  751. } else {
  752. errptr := (*int)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{}))) //__errno()
  753. return 0, *errptr
  754. }
  755. return 0, 245 // EBADDATA 245
  756. }
  757. func Readlink(path string, buf []byte) (n int, err error) {
  758. var _p0 *byte
  759. _p0, err = BytePtrFromString(path)
  760. if err != nil {
  761. return
  762. }
  763. var _p1 unsafe.Pointer
  764. if len(buf) > 0 {
  765. _p1 = unsafe.Pointer(&buf[0])
  766. } else {
  767. _p1 = unsafe.Pointer(&_zero)
  768. }
  769. n = int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___READLINK_A<<4,
  770. []uintptr{uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))}))
  771. runtime.KeepAlive(unsafe.Pointer(_p0))
  772. if n == -1 {
  773. value := *(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
  774. err = errnoErr(Errno(value))
  775. } else {
  776. if buf[0] == '$' {
  777. if isSpecialPath(buf[1:9]) {
  778. cnt, err1 := realpath(path, buf)
  779. if err1 == 0 {
  780. n = cnt
  781. }
  782. }
  783. }
  784. }
  785. return
  786. }
  787. func impl_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
  788. var _p0 *byte
  789. _p0, err = BytePtrFromString(path)
  790. if err != nil {
  791. return
  792. }
  793. var _p1 unsafe.Pointer
  794. if len(buf) > 0 {
  795. _p1 = unsafe.Pointer(&buf[0])
  796. } else {
  797. _p1 = unsafe.Pointer(&_zero)
  798. }
  799. runtime.EnterSyscall()
  800. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
  801. runtime.ExitSyscall()
  802. n = int(r0)
  803. if int64(r0) == -1 {
  804. err = errnoErr2(e1, e2)
  805. return n, err
  806. } else {
  807. if buf[0] == '$' {
  808. if isSpecialPath(buf[1:9]) {
  809. cnt, err1 := realpath(path, buf)
  810. if err1 == 0 {
  811. n = cnt
  812. }
  813. }
  814. }
  815. }
  816. return
  817. }
  818. //go:nosplit
  819. func get_ReadlinkatAddr() *(func(dirfd int, path string, buf []byte) (n int, err error))
  820. var Readlinkat = enter_Readlinkat
  821. func enter_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
  822. funcref := get_ReadlinkatAddr()
  823. if funcptrtest(GetZosLibVec()+SYS___READLINKAT_A<<4, "") == 0 {
  824. *funcref = impl_Readlinkat
  825. } else {
  826. *funcref = error_Readlinkat
  827. }
  828. return (*funcref)(dirfd, path, buf)
  829. }
  830. func error_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
  831. n = -1
  832. err = ENOSYS
  833. return
  834. }
  835. //sys Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
  836. //sys Mkdirat(dirfd int, path string, mode uint32) (err error) = SYS___MKDIRAT_A
  837. //sys Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
  838. //sys Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
  839. //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) = SYS___MKNODAT_A
  840. //sys PivotRoot(newroot string, oldroot string) (err error) = SYS___PIVOT_ROOT_A
  841. //sys Pread(fd int, p []byte, offset int64) (n int, err error)
  842. //sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
  843. //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) = SYS___PRCTL_A
  844. //sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT
  845. //sys Rename(from string, to string) (err error) = SYS___RENAME_A
  846. //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) = SYS___RENAMEAT_A
  847. //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) = SYS___RENAMEAT2_A
  848. //sys Rmdir(path string) (err error) = SYS___RMDIR_A
  849. //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
  850. //sys Setegid(egid int) (err error) = SYS_SETEGID
  851. //sys Seteuid(euid int) (err error) = SYS_SETEUID
  852. //sys Sethostname(p []byte) (err error) = SYS___SETHOSTNAME_A
  853. //sys Setns(fd int, nstype int) (err error) = SYS_SETNS
  854. //sys Setpriority(which int, who int, prio int) (err error)
  855. //sysnb Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
  856. //sysnb Setrlimit(resource int, lim *Rlimit) (err error)
  857. //sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID
  858. //sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID
  859. //sysnb Setsid() (pid int, err error) = SYS_SETSID
  860. //sys Setuid(uid int) (err error) = SYS_SETUID
  861. //sys Setgid(uid int) (err error) = SYS_SETGID
  862. //sys Shutdown(fd int, how int) (err error)
  863. //sys stat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A
  864. func Stat(path string, sta *Stat_t) (err error) {
  865. var statLE Stat_LE_t
  866. err = stat(path, &statLE)
  867. copyStat(sta, &statLE)
  868. return
  869. }
  870. //sys Symlink(path string, link string) (err error) = SYS___SYMLINK_A
  871. //sys Symlinkat(oldPath string, dirfd int, newPath string) (err error) = SYS___SYMLINKAT_A
  872. //sys Sync() = SYS_SYNC
  873. //sys Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
  874. //sys Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
  875. //sys Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
  876. //sys Umask(mask int) (oldmask int)
  877. //sys Unlink(path string) (err error) = SYS___UNLINK_A
  878. //sys Unlinkat(dirfd int, path string, flags int) (err error) = SYS___UNLINKAT_A
  879. //sys Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
  880. //sys open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
  881. func Open(path string, mode int, perm uint32) (fd int, err error) {
  882. if mode&O_ACCMODE == 0 {
  883. mode |= O_RDONLY
  884. }
  885. return open(path, mode, perm)
  886. }
  887. //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) = SYS___OPENAT_A
  888. func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
  889. if flags&O_ACCMODE == 0 {
  890. flags |= O_RDONLY
  891. }
  892. return openat(dirfd, path, flags, mode)
  893. }
  894. //sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) = SYS___OPENAT2_A
  895. func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
  896. if how.Flags&O_ACCMODE == 0 {
  897. how.Flags |= O_RDONLY
  898. }
  899. return openat2(dirfd, path, how, SizeofOpenHow)
  900. }
  901. func ZosFdToPath(dirfd int) (path string, err error) {
  902. var buffer [1024]byte
  903. runtime.EnterSyscall()
  904. ret, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_IOCTL<<4, uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0])))
  905. runtime.ExitSyscall()
  906. if ret == 0 {
  907. zb := bytes.IndexByte(buffer[:], 0)
  908. if zb == -1 {
  909. zb = len(buffer)
  910. }
  911. CallLeFuncWithErr(GetZosLibVec()+SYS___E2A_L<<4, uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb))
  912. return string(buffer[:zb]), nil
  913. }
  914. return "", errnoErr2(e1, e2)
  915. }
  916. //sys remove(path string) (err error)
  917. func Remove(path string) error {
  918. return remove(path)
  919. }
  920. const ImplementsGetwd = true
  921. func Getcwd(buf []byte) (n int, err error) {
  922. var p unsafe.Pointer
  923. if len(buf) > 0 {
  924. p = unsafe.Pointer(&buf[0])
  925. } else {
  926. p = unsafe.Pointer(&_zero)
  927. }
  928. runtime.EnterSyscall()
  929. r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___GETCWD_A<<4, uintptr(p), uintptr(len(buf)))
  930. runtime.ExitSyscall()
  931. n = clen(buf) + 1
  932. if r0 == 0 {
  933. err = errnoErr2(e1, e2)
  934. }
  935. return
  936. }
  937. func Getwd() (wd string, err error) {
  938. var buf [PathMax]byte
  939. n, err := Getcwd(buf[0:])
  940. if err != nil {
  941. return "", err
  942. }
  943. // Getcwd returns the number of bytes written to buf, including the NUL.
  944. if n < 1 || n > len(buf) || buf[n-1] != 0 {
  945. return "", EINVAL
  946. }
  947. return string(buf[0 : n-1]), nil
  948. }
  949. func Getgroups() (gids []int, err error) {
  950. n, err := getgroups(0, nil)
  951. if err != nil {
  952. return nil, err
  953. }
  954. if n == 0 {
  955. return nil, nil
  956. }
  957. // Sanity check group count. Max is 1<<16 on Linux.
  958. if n < 0 || n > 1<<20 {
  959. return nil, EINVAL
  960. }
  961. a := make([]_Gid_t, n)
  962. n, err = getgroups(n, &a[0])
  963. if err != nil {
  964. return nil, err
  965. }
  966. gids = make([]int, n)
  967. for i, v := range a[0:n] {
  968. gids[i] = int(v)
  969. }
  970. return
  971. }
  972. func Setgroups(gids []int) (err error) {
  973. if len(gids) == 0 {
  974. return setgroups(0, nil)
  975. }
  976. a := make([]_Gid_t, len(gids))
  977. for i, v := range gids {
  978. a[i] = _Gid_t(v)
  979. }
  980. return setgroups(len(a), &a[0])
  981. }
  982. func gettid() uint64
  983. func Gettid() (tid int) {
  984. return int(gettid())
  985. }
  986. type WaitStatus uint32
  987. // Wait status is 7 bits at bottom, either 0 (exited),
  988. // 0x7F (stopped), or a signal number that caused an exit.
  989. // The 0x80 bit is whether there was a core dump.
  990. // An extra number (exit code, signal causing a stop)
  991. // is in the high bits. At least that's the idea.
  992. // There are various irregularities. For example, the
  993. // "continued" status is 0xFFFF, distinguishing itself
  994. // from stopped via the core dump bit.
  995. const (
  996. mask = 0x7F
  997. core = 0x80
  998. exited = 0x00
  999. stopped = 0x7F
  1000. shift = 8
  1001. )
  1002. func (w WaitStatus) Exited() bool { return w&mask == exited }
  1003. func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
  1004. func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
  1005. func (w WaitStatus) Continued() bool { return w == 0xFFFF }
  1006. func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
  1007. func (w WaitStatus) ExitStatus() int {
  1008. if !w.Exited() {
  1009. return -1
  1010. }
  1011. return int(w>>shift) & 0xFF
  1012. }
  1013. func (w WaitStatus) Signal() Signal {
  1014. if !w.Signaled() {
  1015. return -1
  1016. }
  1017. return Signal(w & mask)
  1018. }
  1019. func (w WaitStatus) StopSignal() Signal {
  1020. if !w.Stopped() {
  1021. return -1
  1022. }
  1023. return Signal(w>>shift) & 0xFF
  1024. }
  1025. func (w WaitStatus) TrapCause() int { return -1 }
  1026. //sys waitid(idType int, id int, info *Siginfo, options int) (err error)
  1027. func Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) {
  1028. return waitid(idType, id, info, options)
  1029. }
  1030. //sys waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
  1031. func impl_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  1032. runtime.EnterSyscall()
  1033. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAIT4<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)))
  1034. runtime.ExitSyscall()
  1035. wpid = int(r0)
  1036. if int64(r0) == -1 {
  1037. err = errnoErr2(e1, e2)
  1038. }
  1039. return
  1040. }
  1041. //go:nosplit
  1042. func get_Wait4Addr() *(func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error))
  1043. var Wait4 = enter_Wait4
  1044. func enter_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  1045. funcref := get_Wait4Addr()
  1046. if funcptrtest(GetZosLibVec()+SYS_WAIT4<<4, "") == 0 {
  1047. *funcref = impl_Wait4
  1048. } else {
  1049. *funcref = legacyWait4
  1050. }
  1051. return (*funcref)(pid, wstatus, options, rusage)
  1052. }
  1053. func legacyWait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  1054. // TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
  1055. // At the moment rusage will not be touched.
  1056. var status _C_int
  1057. wpid, err = waitpid(pid, &status, options)
  1058. if wstatus != nil {
  1059. *wstatus = WaitStatus(status)
  1060. }
  1061. return
  1062. }
  1063. //sysnb gettimeofday(tv *timeval_zos) (err error)
  1064. func Gettimeofday(tv *Timeval) (err error) {
  1065. var tvz timeval_zos
  1066. err = gettimeofday(&tvz)
  1067. tv.Sec = tvz.Sec
  1068. tv.Usec = int64(tvz.Usec)
  1069. return
  1070. }
  1071. func Time(t *Time_t) (tt Time_t, err error) {
  1072. var tv Timeval
  1073. err = Gettimeofday(&tv)
  1074. if err != nil {
  1075. return 0, err
  1076. }
  1077. if t != nil {
  1078. *t = Time_t(tv.Sec)
  1079. }
  1080. return Time_t(tv.Sec), nil
  1081. }
  1082. func setTimespec(sec, nsec int64) Timespec {
  1083. return Timespec{Sec: sec, Nsec: nsec}
  1084. }
  1085. func setTimeval(sec, usec int64) Timeval { //fix
  1086. return Timeval{Sec: sec, Usec: usec}
  1087. }
  1088. //sysnb pipe(p *[2]_C_int) (err error)
  1089. func Pipe(p []int) (err error) {
  1090. if len(p) != 2 {
  1091. return EINVAL
  1092. }
  1093. var pp [2]_C_int
  1094. err = pipe(&pp)
  1095. p[0] = int(pp[0])
  1096. p[1] = int(pp[1])
  1097. return
  1098. }
  1099. //sys utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
  1100. func Utimes(path string, tv []Timeval) (err error) {
  1101. if tv == nil {
  1102. return utimes(path, nil)
  1103. }
  1104. if len(tv) != 2 {
  1105. return EINVAL
  1106. }
  1107. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  1108. }
  1109. //sys utimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) = SYS___UTIMENSAT_A
  1110. func validUtimensat() bool {
  1111. if funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, "") == 0 {
  1112. if name, err := getLeFuncName(GetZosLibVec() + SYS___UTIMENSAT_A<<4); err == nil {
  1113. return name == "__utimensat_a"
  1114. }
  1115. }
  1116. return false
  1117. }
  1118. // Begin UtimesNano
  1119. //go:nosplit
  1120. func get_UtimesNanoAddr() *(func(path string, ts []Timespec) (err error))
  1121. var UtimesNano = enter_UtimesNano
  1122. func enter_UtimesNano(path string, ts []Timespec) (err error) {
  1123. funcref := get_UtimesNanoAddr()
  1124. if validUtimensat() {
  1125. *funcref = utimesNanoImpl
  1126. } else {
  1127. *funcref = legacyUtimesNano
  1128. }
  1129. return (*funcref)(path, ts)
  1130. }
  1131. func utimesNanoImpl(path string, ts []Timespec) (err error) {
  1132. if ts == nil {
  1133. return utimensat(AT_FDCWD, path, nil, 0)
  1134. }
  1135. if len(ts) != 2 {
  1136. return EINVAL
  1137. }
  1138. return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
  1139. }
  1140. func legacyUtimesNano(path string, ts []Timespec) (err error) {
  1141. if len(ts) != 2 {
  1142. return EINVAL
  1143. }
  1144. // Not as efficient as it could be because Timespec and
  1145. // Timeval have different types in the different OSes
  1146. tv := [2]Timeval{
  1147. NsecToTimeval(TimespecToNsec(ts[0])),
  1148. NsecToTimeval(TimespecToNsec(ts[1])),
  1149. }
  1150. return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  1151. }
  1152. // End UtimesNano
  1153. // Begin UtimesNanoAt
  1154. //go:nosplit
  1155. func get_UtimesNanoAtAddr() *(func(dirfd int, path string, ts []Timespec, flags int) (err error))
  1156. var UtimesNanoAt = enter_UtimesNanoAt
  1157. func enter_UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
  1158. funcref := get_UtimesNanoAtAddr()
  1159. if validUtimensat() {
  1160. *funcref = utimesNanoAtImpl
  1161. } else {
  1162. *funcref = legacyUtimesNanoAt
  1163. }
  1164. return (*funcref)(dirfd, path, ts, flags)
  1165. }
  1166. func utimesNanoAtImpl(dirfd int, path string, ts []Timespec, flags int) (err error) {
  1167. if ts == nil {
  1168. return utimensat(dirfd, path, nil, flags)
  1169. }
  1170. if len(ts) != 2 {
  1171. return EINVAL
  1172. }
  1173. return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
  1174. }
  1175. func legacyUtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
  1176. if path[0] != '/' {
  1177. dirPath, err := ZosFdToPath(dirfd)
  1178. if err != nil {
  1179. return err
  1180. }
  1181. path = dirPath + "/" + path
  1182. }
  1183. if flags == AT_SYMLINK_NOFOLLOW {
  1184. if len(ts) != 2 {
  1185. return EINVAL
  1186. }
  1187. if ts[0].Nsec >= 5e8 {
  1188. ts[0].Sec++
  1189. }
  1190. ts[0].Nsec = 0
  1191. if ts[1].Nsec >= 5e8 {
  1192. ts[1].Sec++
  1193. }
  1194. ts[1].Nsec = 0
  1195. // Not as efficient as it could be because Timespec and
  1196. // Timeval have different types in the different OSes
  1197. tv := []Timeval{
  1198. NsecToTimeval(TimespecToNsec(ts[0])),
  1199. NsecToTimeval(TimespecToNsec(ts[1])),
  1200. }
  1201. return Lutimes(path, tv)
  1202. }
  1203. return UtimesNano(path, ts)
  1204. }
  1205. // End UtimesNanoAt
  1206. func Getsockname(fd int) (sa Sockaddr, err error) {
  1207. var rsa RawSockaddrAny
  1208. var len _Socklen = SizeofSockaddrAny
  1209. if err = getsockname(fd, &rsa, &len); err != nil {
  1210. return
  1211. }
  1212. // TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
  1213. return anyToSockaddr(0, &rsa)
  1214. }
  1215. const (
  1216. // identifier constants
  1217. nwmHeaderIdentifier = 0xd5e6d4c8
  1218. nwmFilterIdentifier = 0xd5e6d4c6
  1219. nwmTCPConnIdentifier = 0xd5e6d4c3
  1220. nwmRecHeaderIdentifier = 0xd5e6d4d9
  1221. nwmIPStatsIdentifier = 0xd5e6d4c9d7e2e340
  1222. nwmIPGStatsIdentifier = 0xd5e6d4c9d7c7e2e3
  1223. nwmTCPStatsIdentifier = 0xd5e6d4e3c3d7e2e3
  1224. nwmUDPStatsIdentifier = 0xd5e6d4e4c4d7e2e3
  1225. nwmICMPGStatsEntry = 0xd5e6d4c9c3d4d7c7
  1226. nwmICMPTStatsEntry = 0xd5e6d4c9c3d4d7e3
  1227. // nwmHeader constants
  1228. nwmVersion1 = 1
  1229. nwmVersion2 = 2
  1230. nwmCurrentVer = 2
  1231. nwmTCPConnType = 1
  1232. nwmGlobalStatsType = 14
  1233. // nwmFilter constants
  1234. nwmFilterLclAddrMask = 0x20000000 // Local address
  1235. nwmFilterSrcAddrMask = 0x20000000 // Source address
  1236. nwmFilterLclPortMask = 0x10000000 // Local port
  1237. nwmFilterSrcPortMask = 0x10000000 // Source port
  1238. // nwmConnEntry constants
  1239. nwmTCPStateClosed = 1
  1240. nwmTCPStateListen = 2
  1241. nwmTCPStateSynSent = 3
  1242. nwmTCPStateSynRcvd = 4
  1243. nwmTCPStateEstab = 5
  1244. nwmTCPStateFinWait1 = 6
  1245. nwmTCPStateFinWait2 = 7
  1246. nwmTCPStateClosWait = 8
  1247. nwmTCPStateLastAck = 9
  1248. nwmTCPStateClosing = 10
  1249. nwmTCPStateTimeWait = 11
  1250. nwmTCPStateDeletTCB = 12
  1251. // Existing constants on linux
  1252. BPF_TCP_CLOSE = 1
  1253. BPF_TCP_LISTEN = 2
  1254. BPF_TCP_SYN_SENT = 3
  1255. BPF_TCP_SYN_RECV = 4
  1256. BPF_TCP_ESTABLISHED = 5
  1257. BPF_TCP_FIN_WAIT1 = 6
  1258. BPF_TCP_FIN_WAIT2 = 7
  1259. BPF_TCP_CLOSE_WAIT = 8
  1260. BPF_TCP_LAST_ACK = 9
  1261. BPF_TCP_CLOSING = 10
  1262. BPF_TCP_TIME_WAIT = 11
  1263. BPF_TCP_NEW_SYN_RECV = -1
  1264. BPF_TCP_MAX_STATES = -2
  1265. )
  1266. type nwmTriplet struct {
  1267. offset uint32
  1268. length uint32
  1269. number uint32
  1270. }
  1271. type nwmQuadruplet struct {
  1272. offset uint32
  1273. length uint32
  1274. number uint32
  1275. match uint32
  1276. }
  1277. type nwmHeader struct {
  1278. ident uint32
  1279. length uint32
  1280. version uint16
  1281. nwmType uint16
  1282. bytesNeeded uint32
  1283. options uint32
  1284. _ [16]byte
  1285. inputDesc nwmTriplet
  1286. outputDesc nwmQuadruplet
  1287. }
  1288. type nwmFilter struct {
  1289. ident uint32
  1290. flags uint32
  1291. resourceName [8]byte
  1292. resourceId uint32
  1293. listenerId uint32
  1294. local [28]byte // union of sockaddr4 and sockaddr6
  1295. remote [28]byte // union of sockaddr4 and sockaddr6
  1296. _ uint16
  1297. _ uint16
  1298. asid uint16
  1299. _ [2]byte
  1300. tnLuName [8]byte
  1301. tnMonGrp uint32
  1302. tnAppl [8]byte
  1303. applData [40]byte
  1304. nInterface [16]byte
  1305. dVipa [16]byte
  1306. dVipaPfx uint16
  1307. dVipaPort uint16
  1308. dVipaFamily byte
  1309. _ [3]byte
  1310. destXCF [16]byte
  1311. destXCFPfx uint16
  1312. destXCFFamily byte
  1313. _ [1]byte
  1314. targIP [16]byte
  1315. targIPPfx uint16
  1316. targIPFamily byte
  1317. _ [1]byte
  1318. _ [20]byte
  1319. }
  1320. type nwmRecHeader struct {
  1321. ident uint32
  1322. length uint32
  1323. number byte
  1324. _ [3]byte
  1325. }
  1326. type nwmTCPStatsEntry struct {
  1327. ident uint64
  1328. currEstab uint32
  1329. activeOpened uint32
  1330. passiveOpened uint32
  1331. connClosed uint32
  1332. estabResets uint32
  1333. attemptFails uint32
  1334. passiveDrops uint32
  1335. timeWaitReused uint32
  1336. inSegs uint64
  1337. predictAck uint32
  1338. predictData uint32
  1339. inDupAck uint32
  1340. inBadSum uint32
  1341. inBadLen uint32
  1342. inShort uint32
  1343. inDiscOldTime uint32
  1344. inAllBeforeWin uint32
  1345. inSomeBeforeWin uint32
  1346. inAllAfterWin uint32
  1347. inSomeAfterWin uint32
  1348. inOutOfOrder uint32
  1349. inAfterClose uint32
  1350. inWinProbes uint32
  1351. inWinUpdates uint32
  1352. outWinUpdates uint32
  1353. outSegs uint64
  1354. outDelayAcks uint32
  1355. outRsts uint32
  1356. retransSegs uint32
  1357. retransTimeouts uint32
  1358. retransDrops uint32
  1359. pmtuRetrans uint32
  1360. pmtuErrors uint32
  1361. outWinProbes uint32
  1362. probeDrops uint32
  1363. keepAliveProbes uint32
  1364. keepAliveDrops uint32
  1365. finwait2Drops uint32
  1366. acceptCount uint64
  1367. inBulkQSegs uint64
  1368. inDiscards uint64
  1369. connFloods uint32
  1370. connStalls uint32
  1371. cfgEphemDef uint16
  1372. ephemInUse uint16
  1373. ephemHiWater uint16
  1374. flags byte
  1375. _ [1]byte
  1376. ephemExhaust uint32
  1377. smcRCurrEstabLnks uint32
  1378. smcRLnkActTimeOut uint32
  1379. smcRActLnkOpened uint32
  1380. smcRPasLnkOpened uint32
  1381. smcRLnksClosed uint32
  1382. smcRCurrEstab uint32
  1383. smcRActiveOpened uint32
  1384. smcRPassiveOpened uint32
  1385. smcRConnClosed uint32
  1386. smcRInSegs uint64
  1387. smcROutSegs uint64
  1388. smcRInRsts uint32
  1389. smcROutRsts uint32
  1390. smcDCurrEstabLnks uint32
  1391. smcDActLnkOpened uint32
  1392. smcDPasLnkOpened uint32
  1393. smcDLnksClosed uint32
  1394. smcDCurrEstab uint32
  1395. smcDActiveOpened uint32
  1396. smcDPassiveOpened uint32
  1397. smcDConnClosed uint32
  1398. smcDInSegs uint64
  1399. smcDOutSegs uint64
  1400. smcDInRsts uint32
  1401. smcDOutRsts uint32
  1402. }
  1403. type nwmConnEntry struct {
  1404. ident uint32
  1405. local [28]byte // union of sockaddr4 and sockaddr6
  1406. remote [28]byte // union of sockaddr4 and sockaddr6
  1407. startTime [8]byte // uint64, changed to prevent padding from being inserted
  1408. lastActivity [8]byte // uint64
  1409. bytesIn [8]byte // uint64
  1410. bytesOut [8]byte // uint64
  1411. inSegs [8]byte // uint64
  1412. outSegs [8]byte // uint64
  1413. state uint16
  1414. activeOpen byte
  1415. flag01 byte
  1416. outBuffered uint32
  1417. inBuffered uint32
  1418. maxSndWnd uint32
  1419. reXmtCount uint32
  1420. congestionWnd uint32
  1421. ssThresh uint32
  1422. roundTripTime uint32
  1423. roundTripVar uint32
  1424. sendMSS uint32
  1425. sndWnd uint32
  1426. rcvBufSize uint32
  1427. sndBufSize uint32
  1428. outOfOrderCount uint32
  1429. lcl0WindowCount uint32
  1430. rmt0WindowCount uint32
  1431. dupacks uint32
  1432. flag02 byte
  1433. sockOpt6Cont byte
  1434. asid uint16
  1435. resourceName [8]byte
  1436. resourceId uint32
  1437. subtask uint32
  1438. sockOpt byte
  1439. sockOpt6 byte
  1440. clusterConnFlag byte
  1441. proto byte
  1442. targetAppl [8]byte
  1443. luName [8]byte
  1444. clientUserId [8]byte
  1445. logMode [8]byte
  1446. timeStamp uint32
  1447. timeStampAge uint32
  1448. serverResourceId uint32
  1449. intfName [16]byte
  1450. ttlsStatPol byte
  1451. ttlsStatConn byte
  1452. ttlsSSLProt uint16
  1453. ttlsNegCiph [2]byte
  1454. ttlsSecType byte
  1455. ttlsFIPS140Mode byte
  1456. ttlsUserID [8]byte
  1457. applData [40]byte
  1458. inOldestTime [8]byte // uint64
  1459. outOldestTime [8]byte // uint64
  1460. tcpTrustedPartner byte
  1461. _ [3]byte
  1462. bulkDataIntfName [16]byte
  1463. ttlsNegCiph4 [4]byte
  1464. smcReason uint32
  1465. lclSMCLinkId uint32
  1466. rmtSMCLinkId uint32
  1467. smcStatus byte
  1468. smcFlags byte
  1469. _ [2]byte
  1470. rcvWnd uint32
  1471. lclSMCBufSz uint32
  1472. rmtSMCBufSz uint32
  1473. ttlsSessID [32]byte
  1474. ttlsSessIDLen int16
  1475. _ [1]byte
  1476. smcDStatus byte
  1477. smcDReason uint32
  1478. }
  1479. var svcNameTable [][]byte = [][]byte{
  1480. []byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
  1481. }
  1482. const (
  1483. svc_EZBNMIF4 = 0
  1484. )
  1485. func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
  1486. jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
  1487. responseBuffer := [4096]byte{0}
  1488. var bufferAlet, reasonCode uint32 = 0, 0
  1489. var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
  1490. dsa := [18]uint64{0}
  1491. var argv [7]unsafe.Pointer
  1492. argv[0] = unsafe.Pointer(&jobname[0])
  1493. argv[1] = unsafe.Pointer(&responseBuffer[0])
  1494. argv[2] = unsafe.Pointer(&bufferAlet)
  1495. argv[3] = unsafe.Pointer(&bufferLen)
  1496. argv[4] = unsafe.Pointer(&returnValue)
  1497. argv[5] = unsafe.Pointer(&returnCode)
  1498. argv[6] = unsafe.Pointer(&reasonCode)
  1499. request := (*struct {
  1500. header nwmHeader
  1501. filter nwmFilter
  1502. })(unsafe.Pointer(&responseBuffer[0]))
  1503. EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
  1504. if EZBNMIF4 == nil {
  1505. return nil, errnoErr(EINVAL)
  1506. }
  1507. // GetGlobalStats EZBNMIF4 call
  1508. request.header.ident = nwmHeaderIdentifier
  1509. request.header.length = uint32(unsafe.Sizeof(request.header))
  1510. request.header.version = nwmCurrentVer
  1511. request.header.nwmType = nwmGlobalStatsType
  1512. request.header.options = 0x80000000
  1513. svcCall(EZBNMIF4, &argv[0], &dsa[0])
  1514. // outputDesc field is filled by EZBNMIF4 on success
  1515. if returnCode != 0 || request.header.outputDesc.offset == 0 {
  1516. return nil, errnoErr(EINVAL)
  1517. }
  1518. // Check that EZBNMIF4 returned a nwmRecHeader
  1519. recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  1520. if recHeader.ident != nwmRecHeaderIdentifier {
  1521. return nil, errnoErr(EINVAL)
  1522. }
  1523. // Parse nwmTriplets to get offsets of returned entries
  1524. var sections []*uint64
  1525. var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
  1526. for i := uint32(0); i < uint32(recHeader.number); i++ {
  1527. offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
  1528. sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
  1529. for j := uint32(0); j < sectionDesc.number; j++ {
  1530. offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
  1531. sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
  1532. }
  1533. }
  1534. // Find nwmTCPStatsEntry in returned entries
  1535. var tcpStats *nwmTCPStatsEntry = nil
  1536. for _, ptr := range sections {
  1537. switch *ptr {
  1538. case nwmTCPStatsIdentifier:
  1539. if tcpStats != nil {
  1540. return nil, errnoErr(EINVAL)
  1541. }
  1542. tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
  1543. case nwmIPStatsIdentifier:
  1544. case nwmIPGStatsIdentifier:
  1545. case nwmUDPStatsIdentifier:
  1546. case nwmICMPGStatsEntry:
  1547. case nwmICMPTStatsEntry:
  1548. default:
  1549. return nil, errnoErr(EINVAL)
  1550. }
  1551. }
  1552. if tcpStats == nil {
  1553. return nil, errnoErr(EINVAL)
  1554. }
  1555. // GetConnectionDetail EZBNMIF4 call
  1556. responseBuffer = [4096]byte{0}
  1557. dsa = [18]uint64{0}
  1558. bufferAlet, reasonCode = 0, 0
  1559. bufferLen, returnValue, returnCode = 4096, 0, 0
  1560. nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
  1561. nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
  1562. argv[0] = unsafe.Pointer(uintptr(*nameptr))
  1563. request.header.ident = nwmHeaderIdentifier
  1564. request.header.length = uint32(unsafe.Sizeof(request.header))
  1565. request.header.version = nwmCurrentVer
  1566. request.header.nwmType = nwmTCPConnType
  1567. request.header.options = 0x80000000
  1568. request.filter.ident = nwmFilterIdentifier
  1569. var localSockaddr RawSockaddrAny
  1570. socklen := _Socklen(SizeofSockaddrAny)
  1571. err := getsockname(fd, &localSockaddr, &socklen)
  1572. if err != nil {
  1573. return nil, errnoErr(EINVAL)
  1574. }
  1575. if localSockaddr.Addr.Family == AF_INET {
  1576. localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
  1577. localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
  1578. localSockFilter.Family = AF_INET
  1579. var i int
  1580. for i = 0; i < 4; i++ {
  1581. if localSockaddr.Addr[i] != 0 {
  1582. break
  1583. }
  1584. }
  1585. if i != 4 {
  1586. request.filter.flags |= nwmFilterLclAddrMask
  1587. for i = 0; i < 4; i++ {
  1588. localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1589. }
  1590. }
  1591. if localSockaddr.Port != 0 {
  1592. request.filter.flags |= nwmFilterLclPortMask
  1593. localSockFilter.Port = localSockaddr.Port
  1594. }
  1595. } else if localSockaddr.Addr.Family == AF_INET6 {
  1596. localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
  1597. localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
  1598. localSockFilter.Family = AF_INET6
  1599. var i int
  1600. for i = 0; i < 16; i++ {
  1601. if localSockaddr.Addr[i] != 0 {
  1602. break
  1603. }
  1604. }
  1605. if i != 16 {
  1606. request.filter.flags |= nwmFilterLclAddrMask
  1607. for i = 0; i < 16; i++ {
  1608. localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1609. }
  1610. }
  1611. if localSockaddr.Port != 0 {
  1612. request.filter.flags |= nwmFilterLclPortMask
  1613. localSockFilter.Port = localSockaddr.Port
  1614. }
  1615. }
  1616. svcCall(EZBNMIF4, &argv[0], &dsa[0])
  1617. // outputDesc field is filled by EZBNMIF4 on success
  1618. if returnCode != 0 || request.header.outputDesc.offset == 0 {
  1619. return nil, errnoErr(EINVAL)
  1620. }
  1621. // Check that EZBNMIF4 returned a nwmConnEntry
  1622. conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  1623. if conn.ident != nwmTCPConnIdentifier {
  1624. return nil, errnoErr(EINVAL)
  1625. }
  1626. // Copy data from the returned data structures into tcpInfo
  1627. // Stats from nwmConnEntry are specific to that connection.
  1628. // Stats from nwmTCPStatsEntry are global (to the interface?)
  1629. // Fields may not be an exact match. Some fields have no equivalent.
  1630. var tcpinfo TCPInfo
  1631. tcpinfo.State = uint8(conn.state)
  1632. tcpinfo.Ca_state = 0 // dummy
  1633. tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
  1634. tcpinfo.Probes = uint8(tcpStats.outWinProbes)
  1635. tcpinfo.Backoff = 0 // dummy
  1636. tcpinfo.Options = 0 // dummy
  1637. tcpinfo.Rto = tcpStats.retransTimeouts
  1638. tcpinfo.Ato = tcpStats.outDelayAcks
  1639. tcpinfo.Snd_mss = conn.sendMSS
  1640. tcpinfo.Rcv_mss = conn.sendMSS // dummy
  1641. tcpinfo.Unacked = 0 // dummy
  1642. tcpinfo.Sacked = 0 // dummy
  1643. tcpinfo.Lost = 0 // dummy
  1644. tcpinfo.Retrans = conn.reXmtCount
  1645. tcpinfo.Fackets = 0 // dummy
  1646. tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
  1647. tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
  1648. tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1649. tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1650. tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
  1651. tcpinfo.Rcv_ssthresh = conn.ssThresh
  1652. tcpinfo.Rtt = conn.roundTripTime
  1653. tcpinfo.Rttvar = conn.roundTripVar
  1654. tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
  1655. tcpinfo.Snd_cwnd = conn.congestionWnd
  1656. tcpinfo.Advmss = conn.sendMSS // dummy
  1657. tcpinfo.Reordering = 0 // dummy
  1658. tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
  1659. tcpinfo.Rcv_space = conn.sendMSS // dummy
  1660. tcpinfo.Total_retrans = conn.reXmtCount
  1661. svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
  1662. return &tcpinfo, nil
  1663. }
  1664. // GetsockoptString returns the string value of the socket option opt for the
  1665. // socket associated with fd at the given socket level.
  1666. func GetsockoptString(fd, level, opt int) (string, error) {
  1667. buf := make([]byte, 256)
  1668. vallen := _Socklen(len(buf))
  1669. err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
  1670. if err != nil {
  1671. return "", err
  1672. }
  1673. return ByteSliceToString(buf[:vallen]), nil
  1674. }
  1675. func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  1676. var msg Msghdr
  1677. var rsa RawSockaddrAny
  1678. msg.Name = (*byte)(unsafe.Pointer(&rsa))
  1679. msg.Namelen = SizeofSockaddrAny
  1680. var iov Iovec
  1681. if len(p) > 0 {
  1682. iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1683. iov.SetLen(len(p))
  1684. }
  1685. var dummy byte
  1686. if len(oob) > 0 {
  1687. // receive at least one normal byte
  1688. if len(p) == 0 {
  1689. iov.Base = &dummy
  1690. iov.SetLen(1)
  1691. }
  1692. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1693. msg.SetControllen(len(oob))
  1694. }
  1695. msg.Iov = &iov
  1696. msg.Iovlen = 1
  1697. if n, err = recvmsg(fd, &msg, flags); err != nil {
  1698. return
  1699. }
  1700. oobn = int(msg.Controllen)
  1701. recvflags = int(msg.Flags)
  1702. // source address is only specified if the socket is unconnected
  1703. if rsa.Addr.Family != AF_UNSPEC {
  1704. // TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
  1705. from, err = anyToSockaddr(0, &rsa)
  1706. }
  1707. return
  1708. }
  1709. func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
  1710. _, err = SendmsgN(fd, p, oob, to, flags)
  1711. return
  1712. }
  1713. func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
  1714. var ptr unsafe.Pointer
  1715. var salen _Socklen
  1716. if to != nil {
  1717. var err error
  1718. ptr, salen, err = to.sockaddr()
  1719. if err != nil {
  1720. return 0, err
  1721. }
  1722. }
  1723. var msg Msghdr
  1724. msg.Name = (*byte)(unsafe.Pointer(ptr))
  1725. msg.Namelen = int32(salen)
  1726. var iov Iovec
  1727. if len(p) > 0 {
  1728. iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1729. iov.SetLen(len(p))
  1730. }
  1731. var dummy byte
  1732. if len(oob) > 0 {
  1733. // send at least one normal byte
  1734. if len(p) == 0 {
  1735. iov.Base = &dummy
  1736. iov.SetLen(1)
  1737. }
  1738. msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1739. msg.SetControllen(len(oob))
  1740. }
  1741. msg.Iov = &iov
  1742. msg.Iovlen = 1
  1743. if n, err = sendmsg(fd, &msg, flags); err != nil {
  1744. return 0, err
  1745. }
  1746. if len(oob) > 0 && len(p) == 0 {
  1747. n = 0
  1748. }
  1749. return n, nil
  1750. }
  1751. func Opendir(name string) (uintptr, error) {
  1752. p, err := BytePtrFromString(name)
  1753. if err != nil {
  1754. return 0, err
  1755. }
  1756. err = nil
  1757. runtime.EnterSyscall()
  1758. dir, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___OPENDIR_A<<4, uintptr(unsafe.Pointer(p)))
  1759. runtime.ExitSyscall()
  1760. runtime.KeepAlive(unsafe.Pointer(p))
  1761. if dir == 0 {
  1762. err = errnoErr2(e1, e2)
  1763. }
  1764. return dir, err
  1765. }
  1766. // clearsyscall.Errno resets the errno value to 0.
  1767. func clearErrno()
  1768. func Closedir(dir uintptr) error {
  1769. runtime.EnterSyscall()
  1770. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSEDIR<<4, dir)
  1771. runtime.ExitSyscall()
  1772. if r0 != 0 {
  1773. return errnoErr2(e1, e2)
  1774. }
  1775. return nil
  1776. }
  1777. func Seekdir(dir uintptr, pos int) {
  1778. runtime.EnterSyscall()
  1779. CallLeFuncWithErr(GetZosLibVec()+SYS_SEEKDIR<<4, dir, uintptr(pos))
  1780. runtime.ExitSyscall()
  1781. }
  1782. func Telldir(dir uintptr) (int, error) {
  1783. p, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TELLDIR<<4, dir)
  1784. pos := int(p)
  1785. if int64(p) == -1 {
  1786. return pos, errnoErr2(e1, e2)
  1787. }
  1788. return pos, nil
  1789. }
  1790. // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
  1791. func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
  1792. // struct flock is packed on z/OS. We can't emulate that in Go so
  1793. // instead we pack it here.
  1794. var flock [24]byte
  1795. *(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
  1796. *(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
  1797. *(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
  1798. *(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
  1799. *(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
  1800. runtime.EnterSyscall()
  1801. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
  1802. runtime.ExitSyscall()
  1803. lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
  1804. lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
  1805. lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
  1806. lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
  1807. lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
  1808. if r0 == 0 {
  1809. return nil
  1810. }
  1811. return errnoErr2(e1, e2)
  1812. }
  1813. func impl_Flock(fd int, how int) (err error) {
  1814. runtime.EnterSyscall()
  1815. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FLOCK<<4, uintptr(fd), uintptr(how))
  1816. runtime.ExitSyscall()
  1817. if int64(r0) == -1 {
  1818. err = errnoErr2(e1, e2)
  1819. }
  1820. return
  1821. }
  1822. //go:nosplit
  1823. func get_FlockAddr() *(func(fd int, how int) (err error))
  1824. var Flock = enter_Flock
  1825. func validFlock(fp uintptr) bool {
  1826. if funcptrtest(GetZosLibVec()+SYS_FLOCK<<4, "") == 0 {
  1827. if name, err := getLeFuncName(GetZosLibVec() + SYS_FLOCK<<4); err == nil {
  1828. return name == "flock"
  1829. }
  1830. }
  1831. return false
  1832. }
  1833. func enter_Flock(fd int, how int) (err error) {
  1834. funcref := get_FlockAddr()
  1835. if validFlock(GetZosLibVec() + SYS_FLOCK<<4) {
  1836. *funcref = impl_Flock
  1837. } else {
  1838. *funcref = legacyFlock
  1839. }
  1840. return (*funcref)(fd, how)
  1841. }
  1842. func legacyFlock(fd int, how int) error {
  1843. var flock_type int16
  1844. var fcntl_cmd int
  1845. switch how {
  1846. case LOCK_SH | LOCK_NB:
  1847. flock_type = F_RDLCK
  1848. fcntl_cmd = F_SETLK
  1849. case LOCK_EX | LOCK_NB:
  1850. flock_type = F_WRLCK
  1851. fcntl_cmd = F_SETLK
  1852. case LOCK_EX:
  1853. flock_type = F_WRLCK
  1854. fcntl_cmd = F_SETLKW
  1855. case LOCK_UN:
  1856. flock_type = F_UNLCK
  1857. fcntl_cmd = F_SETLKW
  1858. default:
  1859. }
  1860. flock := Flock_t{
  1861. Type: int16(flock_type),
  1862. Whence: int16(0),
  1863. Start: int64(0),
  1864. Len: int64(0),
  1865. Pid: int32(Getppid()),
  1866. }
  1867. err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
  1868. return err
  1869. }
  1870. func Mlock(b []byte) (err error) {
  1871. runtime.EnterSyscall()
  1872. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
  1873. runtime.ExitSyscall()
  1874. if r0 != 0 {
  1875. err = errnoErr2(e1, e2)
  1876. }
  1877. return
  1878. }
  1879. func Mlock2(b []byte, flags int) (err error) {
  1880. runtime.EnterSyscall()
  1881. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
  1882. runtime.ExitSyscall()
  1883. if r0 != 0 {
  1884. err = errnoErr2(e1, e2)
  1885. }
  1886. return
  1887. }
  1888. func Mlockall(flags int) (err error) {
  1889. runtime.EnterSyscall()
  1890. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
  1891. runtime.ExitSyscall()
  1892. if r0 != 0 {
  1893. err = errnoErr2(e1, e2)
  1894. }
  1895. return
  1896. }
  1897. func Munlock(b []byte) (err error) {
  1898. runtime.EnterSyscall()
  1899. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
  1900. runtime.ExitSyscall()
  1901. if r0 != 0 {
  1902. err = errnoErr2(e1, e2)
  1903. }
  1904. return
  1905. }
  1906. func Munlockall() (err error) {
  1907. runtime.EnterSyscall()
  1908. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
  1909. runtime.ExitSyscall()
  1910. if r0 != 0 {
  1911. err = errnoErr2(e1, e2)
  1912. }
  1913. return
  1914. }
  1915. func ClockGettime(clockid int32, ts *Timespec) error {
  1916. var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
  1917. var nsec_per_sec int64 = 1000000000
  1918. if ts == nil {
  1919. return EFAULT
  1920. }
  1921. if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
  1922. var nanotime int64 = runtime.Nanotime1()
  1923. ts.Sec = nanotime / nsec_per_sec
  1924. ts.Nsec = nanotime % nsec_per_sec
  1925. } else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
  1926. var tm Tms
  1927. _, err := Times(&tm)
  1928. if err != nil {
  1929. return EFAULT
  1930. }
  1931. ts.Sec = int64(tm.Utime / ticks_per_sec)
  1932. ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
  1933. } else {
  1934. return EINVAL
  1935. }
  1936. return nil
  1937. }
  1938. // Chtag
  1939. //go:nosplit
  1940. func get_ChtagAddr() *(func(path string, ccsid uint64, textbit uint64) error)
  1941. var Chtag = enter_Chtag
  1942. func enter_Chtag(path string, ccsid uint64, textbit uint64) error {
  1943. funcref := get_ChtagAddr()
  1944. if validSetxattr() {
  1945. *funcref = impl_Chtag
  1946. } else {
  1947. *funcref = legacy_Chtag
  1948. }
  1949. return (*funcref)(path, ccsid, textbit)
  1950. }
  1951. func legacy_Chtag(path string, ccsid uint64, textbit uint64) error {
  1952. tag := ccsid<<16 | textbit<<15
  1953. var tag_buff [8]byte
  1954. DecodeData(tag_buff[:], 8, tag)
  1955. return Setxattr(path, "filetag", tag_buff[:], XATTR_REPLACE)
  1956. }
  1957. func impl_Chtag(path string, ccsid uint64, textbit uint64) error {
  1958. tag := ccsid<<16 | textbit<<15
  1959. var tag_buff [4]byte
  1960. DecodeData(tag_buff[:], 4, tag)
  1961. return Setxattr(path, "system.filetag", tag_buff[:], XATTR_REPLACE)
  1962. }
  1963. // End of Chtag
  1964. // Nanosleep
  1965. //go:nosplit
  1966. func get_NanosleepAddr() *(func(time *Timespec, leftover *Timespec) error)
  1967. var Nanosleep = enter_Nanosleep
  1968. func enter_Nanosleep(time *Timespec, leftover *Timespec) error {
  1969. funcref := get_NanosleepAddr()
  1970. if funcptrtest(GetZosLibVec()+SYS_NANOSLEEP<<4, "") == 0 {
  1971. *funcref = impl_Nanosleep
  1972. } else {
  1973. *funcref = legacyNanosleep
  1974. }
  1975. return (*funcref)(time, leftover)
  1976. }
  1977. func impl_Nanosleep(time *Timespec, leftover *Timespec) error {
  1978. runtime.EnterSyscall()
  1979. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_NANOSLEEP<<4, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))
  1980. runtime.ExitSyscall()
  1981. if int64(r0) == -1 {
  1982. return errnoErr2(e1, e2)
  1983. }
  1984. return nil
  1985. }
  1986. func legacyNanosleep(time *Timespec, leftover *Timespec) error {
  1987. t0 := runtime.Nanotime1()
  1988. var secrem uint32
  1989. var nsecrem uint32
  1990. total := time.Sec*1000000000 + time.Nsec
  1991. elapsed := runtime.Nanotime1() - t0
  1992. var rv int32
  1993. var rc int32
  1994. var err error
  1995. // repeatedly sleep for 1 second until less than 1 second left
  1996. for total-elapsed > 1000000000 {
  1997. rv, rc, _ = BpxCondTimedWait(uint32(1), uint32(0), uint32(CW_CONDVAR), &secrem, &nsecrem)
  1998. if rv != 0 && rc != 112 { // 112 is EAGAIN
  1999. if leftover != nil && rc == 120 { // 120 is EINTR
  2000. leftover.Sec = int64(secrem)
  2001. leftover.Nsec = int64(nsecrem)
  2002. }
  2003. err = Errno(rc)
  2004. return err
  2005. }
  2006. elapsed = runtime.Nanotime1() - t0
  2007. }
  2008. // sleep the remainder
  2009. if total > elapsed {
  2010. rv, rc, _ = BpxCondTimedWait(uint32(0), uint32(total-elapsed), uint32(CW_CONDVAR), &secrem, &nsecrem)
  2011. }
  2012. if leftover != nil && rc == 120 {
  2013. leftover.Sec = int64(secrem)
  2014. leftover.Nsec = int64(nsecrem)
  2015. }
  2016. if rv != 0 && rc != 112 {
  2017. err = Errno(rc)
  2018. }
  2019. return err
  2020. }
  2021. // End of Nanosleep
  2022. var (
  2023. Stdin = 0
  2024. Stdout = 1
  2025. Stderr = 2
  2026. )
  2027. // Do the interface allocations only once for common
  2028. // Errno values.
  2029. var (
  2030. errEAGAIN error = syscall.EAGAIN
  2031. errEINVAL error = syscall.EINVAL
  2032. errENOENT error = syscall.ENOENT
  2033. )
  2034. var ZosTraceLevel int
  2035. var ZosTracefile *os.File
  2036. var (
  2037. signalNameMapOnce sync.Once
  2038. signalNameMap map[string]syscall.Signal
  2039. )
  2040. // errnoErr returns common boxed Errno values, to prevent
  2041. // allocations at runtime.
  2042. func errnoErr(e Errno) error {
  2043. switch e {
  2044. case 0:
  2045. return nil
  2046. case EAGAIN:
  2047. return errEAGAIN
  2048. case EINVAL:
  2049. return errEINVAL
  2050. case ENOENT:
  2051. return errENOENT
  2052. }
  2053. return e
  2054. }
  2055. var reg *regexp.Regexp
  2056. // enhanced with zos specific errno2
  2057. func errnoErr2(e Errno, e2 uintptr) error {
  2058. switch e {
  2059. case 0:
  2060. return nil
  2061. case EAGAIN:
  2062. return errEAGAIN
  2063. /*
  2064. Allow the retrieval of errno2 for EINVAL and ENOENT on zos
  2065. case EINVAL:
  2066. return errEINVAL
  2067. case ENOENT:
  2068. return errENOENT
  2069. */
  2070. }
  2071. if ZosTraceLevel > 0 {
  2072. var name string
  2073. if reg == nil {
  2074. reg = regexp.MustCompile("(^unix\\.[^/]+$|.*\\/unix\\.[^/]+$)")
  2075. }
  2076. i := 1
  2077. pc, file, line, ok := runtime.Caller(i)
  2078. if ok {
  2079. name = runtime.FuncForPC(pc).Name()
  2080. }
  2081. for ok && reg.MatchString(runtime.FuncForPC(pc).Name()) {
  2082. i += 1
  2083. pc, file, line, ok = runtime.Caller(i)
  2084. }
  2085. if ok {
  2086. if ZosTracefile == nil {
  2087. ZosConsolePrintf("From %s:%d\n", file, line)
  2088. ZosConsolePrintf("%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
  2089. } else {
  2090. fmt.Fprintf(ZosTracefile, "From %s:%d\n", file, line)
  2091. fmt.Fprintf(ZosTracefile, "%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
  2092. }
  2093. } else {
  2094. if ZosTracefile == nil {
  2095. ZosConsolePrintf("%s (errno2=0x%x)\n", e.Error(), e2)
  2096. } else {
  2097. fmt.Fprintf(ZosTracefile, "%s (errno2=0x%x)\n", e.Error(), e2)
  2098. }
  2099. }
  2100. }
  2101. return e
  2102. }
  2103. // ErrnoName returns the error name for error number e.
  2104. func ErrnoName(e Errno) string {
  2105. i := sort.Search(len(errorList), func(i int) bool {
  2106. return errorList[i].num >= e
  2107. })
  2108. if i < len(errorList) && errorList[i].num == e {
  2109. return errorList[i].name
  2110. }
  2111. return ""
  2112. }
  2113. // SignalName returns the signal name for signal number s.
  2114. func SignalName(s syscall.Signal) string {
  2115. i := sort.Search(len(signalList), func(i int) bool {
  2116. return signalList[i].num >= s
  2117. })
  2118. if i < len(signalList) && signalList[i].num == s {
  2119. return signalList[i].name
  2120. }
  2121. return ""
  2122. }
  2123. // SignalNum returns the syscall.Signal for signal named s,
  2124. // or 0 if a signal with such name is not found.
  2125. // The signal name should start with "SIG".
  2126. func SignalNum(s string) syscall.Signal {
  2127. signalNameMapOnce.Do(func() {
  2128. signalNameMap = make(map[string]syscall.Signal, len(signalList))
  2129. for _, signal := range signalList {
  2130. signalNameMap[signal.name] = signal.num
  2131. }
  2132. })
  2133. return signalNameMap[s]
  2134. }
  2135. // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
  2136. func clen(n []byte) int {
  2137. i := bytes.IndexByte(n, 0)
  2138. if i == -1 {
  2139. i = len(n)
  2140. }
  2141. return i
  2142. }
  2143. // Mmap manager, for use by operating system-specific implementations.
  2144. type mmapper struct {
  2145. sync.Mutex
  2146. active map[*byte][]byte // active mappings; key is last byte in mapping
  2147. mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
  2148. munmap func(addr uintptr, length uintptr) error
  2149. }
  2150. func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  2151. if length <= 0 {
  2152. return nil, EINVAL
  2153. }
  2154. // Set __MAP_64 by default
  2155. flags |= __MAP_64
  2156. // Map the requested memory.
  2157. addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
  2158. if errno != nil {
  2159. return nil, errno
  2160. }
  2161. // Slice memory layout
  2162. var sl = struct {
  2163. addr uintptr
  2164. len int
  2165. cap int
  2166. }{addr, length, length}
  2167. // Use unsafe to turn sl into a []byte.
  2168. b := *(*[]byte)(unsafe.Pointer(&sl))
  2169. // Register mapping in m and return it.
  2170. p := &b[cap(b)-1]
  2171. m.Lock()
  2172. defer m.Unlock()
  2173. m.active[p] = b
  2174. return b, nil
  2175. }
  2176. func (m *mmapper) Munmap(data []byte) (err error) {
  2177. if len(data) == 0 || len(data) != cap(data) {
  2178. return EINVAL
  2179. }
  2180. // Find the base of the mapping.
  2181. p := &data[cap(data)-1]
  2182. m.Lock()
  2183. defer m.Unlock()
  2184. b := m.active[p]
  2185. if b == nil || &b[0] != &data[0] {
  2186. return EINVAL
  2187. }
  2188. // Unmap the memory and update m.
  2189. if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
  2190. return errno
  2191. }
  2192. delete(m.active, p)
  2193. return nil
  2194. }
  2195. func Read(fd int, p []byte) (n int, err error) {
  2196. n, err = read(fd, p)
  2197. if raceenabled {
  2198. if n > 0 {
  2199. raceWriteRange(unsafe.Pointer(&p[0]), n)
  2200. }
  2201. if err == nil {
  2202. raceAcquire(unsafe.Pointer(&ioSync))
  2203. }
  2204. }
  2205. return
  2206. }
  2207. func Write(fd int, p []byte) (n int, err error) {
  2208. if raceenabled {
  2209. raceReleaseMerge(unsafe.Pointer(&ioSync))
  2210. }
  2211. n, err = write(fd, p)
  2212. if raceenabled && n > 0 {
  2213. raceReadRange(unsafe.Pointer(&p[0]), n)
  2214. }
  2215. return
  2216. }
  2217. // For testing: clients can set this flag to force
  2218. // creation of IPv6 sockets to return EAFNOSUPPORT.
  2219. var SocketDisableIPv6 bool
  2220. // Sockaddr represents a socket address.
  2221. type Sockaddr interface {
  2222. sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
  2223. }
  2224. // SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
  2225. type SockaddrInet4 struct {
  2226. Port int
  2227. Addr [4]byte
  2228. raw RawSockaddrInet4
  2229. }
  2230. // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
  2231. type SockaddrInet6 struct {
  2232. Port int
  2233. ZoneId uint32
  2234. Addr [16]byte
  2235. raw RawSockaddrInet6
  2236. }
  2237. // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
  2238. type SockaddrUnix struct {
  2239. Name string
  2240. raw RawSockaddrUnix
  2241. }
  2242. func Bind(fd int, sa Sockaddr) (err error) {
  2243. ptr, n, err := sa.sockaddr()
  2244. if err != nil {
  2245. return err
  2246. }
  2247. return bind(fd, ptr, n)
  2248. }
  2249. func Connect(fd int, sa Sockaddr) (err error) {
  2250. ptr, n, err := sa.sockaddr()
  2251. if err != nil {
  2252. return err
  2253. }
  2254. return connect(fd, ptr, n)
  2255. }
  2256. func Getpeername(fd int) (sa Sockaddr, err error) {
  2257. var rsa RawSockaddrAny
  2258. var len _Socklen = SizeofSockaddrAny
  2259. if err = getpeername(fd, &rsa, &len); err != nil {
  2260. return
  2261. }
  2262. return anyToSockaddr(fd, &rsa)
  2263. }
  2264. func GetsockoptByte(fd, level, opt int) (value byte, err error) {
  2265. var n byte
  2266. vallen := _Socklen(1)
  2267. err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  2268. return n, err
  2269. }
  2270. func GetsockoptInt(fd, level, opt int) (value int, err error) {
  2271. var n int32
  2272. vallen := _Socklen(4)
  2273. err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  2274. return int(n), err
  2275. }
  2276. func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
  2277. vallen := _Socklen(4)
  2278. err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
  2279. return value, err
  2280. }
  2281. func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
  2282. var value IPMreq
  2283. vallen := _Socklen(SizeofIPMreq)
  2284. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2285. return &value, err
  2286. }
  2287. func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
  2288. var value IPv6Mreq
  2289. vallen := _Socklen(SizeofIPv6Mreq)
  2290. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2291. return &value, err
  2292. }
  2293. func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
  2294. var value IPv6MTUInfo
  2295. vallen := _Socklen(SizeofIPv6MTUInfo)
  2296. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2297. return &value, err
  2298. }
  2299. func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
  2300. var value ICMPv6Filter
  2301. vallen := _Socklen(SizeofICMPv6Filter)
  2302. err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2303. return &value, err
  2304. }
  2305. func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
  2306. var linger Linger
  2307. vallen := _Socklen(SizeofLinger)
  2308. err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
  2309. return &linger, err
  2310. }
  2311. func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
  2312. var tv Timeval
  2313. vallen := _Socklen(unsafe.Sizeof(tv))
  2314. err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
  2315. return &tv, err
  2316. }
  2317. func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
  2318. var n uint64
  2319. vallen := _Socklen(8)
  2320. err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  2321. return n, err
  2322. }
  2323. func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
  2324. var rsa RawSockaddrAny
  2325. var len _Socklen = SizeofSockaddrAny
  2326. if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
  2327. return
  2328. }
  2329. if rsa.Addr.Family != AF_UNSPEC {
  2330. from, err = anyToSockaddr(fd, &rsa)
  2331. }
  2332. return
  2333. }
  2334. func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
  2335. ptr, n, err := to.sockaddr()
  2336. if err != nil {
  2337. return err
  2338. }
  2339. return sendto(fd, p, flags, ptr, n)
  2340. }
  2341. func SetsockoptByte(fd, level, opt int, value byte) (err error) {
  2342. return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
  2343. }
  2344. func SetsockoptInt(fd, level, opt int, value int) (err error) {
  2345. var n = int32(value)
  2346. return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
  2347. }
  2348. func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
  2349. return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
  2350. }
  2351. func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
  2352. return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
  2353. }
  2354. func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
  2355. return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
  2356. }
  2357. func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
  2358. return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
  2359. }
  2360. func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
  2361. return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
  2362. }
  2363. func SetsockoptString(fd, level, opt int, s string) (err error) {
  2364. var p unsafe.Pointer
  2365. if len(s) > 0 {
  2366. p = unsafe.Pointer(&[]byte(s)[0])
  2367. }
  2368. return setsockopt(fd, level, opt, p, uintptr(len(s)))
  2369. }
  2370. func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
  2371. return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
  2372. }
  2373. func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
  2374. return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
  2375. }
  2376. func Socket(domain, typ, proto int) (fd int, err error) {
  2377. if domain == AF_INET6 && SocketDisableIPv6 {
  2378. return -1, EAFNOSUPPORT
  2379. }
  2380. fd, err = socket(domain, typ, proto)
  2381. return
  2382. }
  2383. func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
  2384. var fdx [2]int32
  2385. err = socketpair(domain, typ, proto, &fdx)
  2386. if err == nil {
  2387. fd[0] = int(fdx[0])
  2388. fd[1] = int(fdx[1])
  2389. }
  2390. return
  2391. }
  2392. var ioSync int64
  2393. func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
  2394. func SetNonblock(fd int, nonblocking bool) (err error) {
  2395. flag, err := fcntl(fd, F_GETFL, 0)
  2396. if err != nil {
  2397. return err
  2398. }
  2399. if nonblocking {
  2400. flag |= O_NONBLOCK
  2401. } else {
  2402. flag &= ^O_NONBLOCK
  2403. }
  2404. _, err = fcntl(fd, F_SETFL, flag)
  2405. return err
  2406. }
  2407. // Exec calls execve(2), which replaces the calling executable in the process
  2408. // tree. argv0 should be the full path to an executable ("/bin/ls") and the
  2409. // executable name should also be the first argument in argv (["ls", "-l"]).
  2410. // envv are the environment variables that should be passed to the new
  2411. // process (["USER=go", "PWD=/tmp"]).
  2412. func Exec(argv0 string, argv []string, envv []string) error {
  2413. return syscall.Exec(argv0, argv, envv)
  2414. }
  2415. func Getag(path string) (ccsid uint16, flag uint16, err error) {
  2416. var val [8]byte
  2417. sz, err := Getxattr(path, "ccsid", val[:])
  2418. if err != nil {
  2419. return
  2420. }
  2421. ccsid = uint16(EncodeData(val[0:sz]))
  2422. sz, err = Getxattr(path, "flags", val[:])
  2423. if err != nil {
  2424. return
  2425. }
  2426. flag = uint16(EncodeData(val[0:sz]) >> 15)
  2427. return
  2428. }
  2429. // Mount begin
  2430. func impl_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  2431. var _p0 *byte
  2432. _p0, err = BytePtrFromString(source)
  2433. if err != nil {
  2434. return
  2435. }
  2436. var _p1 *byte
  2437. _p1, err = BytePtrFromString(target)
  2438. if err != nil {
  2439. return
  2440. }
  2441. var _p2 *byte
  2442. _p2, err = BytePtrFromString(fstype)
  2443. if err != nil {
  2444. return
  2445. }
  2446. var _p3 *byte
  2447. _p3, err = BytePtrFromString(data)
  2448. if err != nil {
  2449. return
  2450. }
  2451. runtime.EnterSyscall()
  2452. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MOUNT1_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(_p3)))
  2453. runtime.ExitSyscall()
  2454. if int64(r0) == -1 {
  2455. err = errnoErr2(e1, e2)
  2456. }
  2457. return
  2458. }
  2459. //go:nosplit
  2460. func get_MountAddr() *(func(source string, target string, fstype string, flags uintptr, data string) (err error))
  2461. var Mount = enter_Mount
  2462. func enter_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  2463. funcref := get_MountAddr()
  2464. if validMount() {
  2465. *funcref = impl_Mount
  2466. } else {
  2467. *funcref = legacyMount
  2468. }
  2469. return (*funcref)(source, target, fstype, flags, data)
  2470. }
  2471. func legacyMount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  2472. if needspace := 8 - len(fstype); needspace <= 0 {
  2473. fstype = fstype[0:8]
  2474. } else {
  2475. fstype += " "[0:needspace]
  2476. }
  2477. return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
  2478. }
  2479. func validMount() bool {
  2480. if funcptrtest(GetZosLibVec()+SYS___MOUNT1_A<<4, "") == 0 {
  2481. if name, err := getLeFuncName(GetZosLibVec() + SYS___MOUNT1_A<<4); err == nil {
  2482. return name == "__mount1_a"
  2483. }
  2484. }
  2485. return false
  2486. }
  2487. // Mount end
  2488. // Unmount begin
  2489. func impl_Unmount(target string, flags int) (err error) {
  2490. var _p0 *byte
  2491. _p0, err = BytePtrFromString(target)
  2492. if err != nil {
  2493. return
  2494. }
  2495. runtime.EnterSyscall()
  2496. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT2_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(flags))
  2497. runtime.ExitSyscall()
  2498. if int64(r0) == -1 {
  2499. err = errnoErr2(e1, e2)
  2500. }
  2501. return
  2502. }
  2503. //go:nosplit
  2504. func get_UnmountAddr() *(func(target string, flags int) (err error))
  2505. var Unmount = enter_Unmount
  2506. func enter_Unmount(target string, flags int) (err error) {
  2507. funcref := get_UnmountAddr()
  2508. if funcptrtest(GetZosLibVec()+SYS___UMOUNT2_A<<4, "") == 0 {
  2509. *funcref = impl_Unmount
  2510. } else {
  2511. *funcref = legacyUnmount
  2512. }
  2513. return (*funcref)(target, flags)
  2514. }
  2515. func legacyUnmount(name string, mtm int) (err error) {
  2516. // mountpoint is always a full path and starts with a '/'
  2517. // check if input string is not a mountpoint but a filesystem name
  2518. if name[0] != '/' {
  2519. return unmount_LE(name, mtm)
  2520. }
  2521. // treat name as mountpoint
  2522. b2s := func(arr []byte) string {
  2523. var str string
  2524. for i := 0; i < len(arr); i++ {
  2525. if arr[i] == 0 {
  2526. str = string(arr[:i])
  2527. break
  2528. }
  2529. }
  2530. return str
  2531. }
  2532. var buffer struct {
  2533. header W_Mnth
  2534. fsinfo [64]W_Mntent
  2535. }
  2536. fs_count, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
  2537. if err == nil {
  2538. err = EINVAL
  2539. for i := 0; i < fs_count; i++ {
  2540. if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
  2541. err = unmount_LE(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
  2542. break
  2543. }
  2544. }
  2545. } else if fs_count == 0 {
  2546. err = EINVAL
  2547. }
  2548. return err
  2549. }
  2550. // Unmount end
  2551. func direntIno(buf []byte) (uint64, bool) {
  2552. return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
  2553. }
  2554. func direntReclen(buf []byte) (uint64, bool) {
  2555. return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
  2556. }
  2557. func direntNamlen(buf []byte) (uint64, bool) {
  2558. reclen, ok := direntReclen(buf)
  2559. if !ok {
  2560. return 0, false
  2561. }
  2562. return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
  2563. }
  2564. func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
  2565. var d Dirent
  2566. d.Ino = uint64(dirent.Ino)
  2567. offset, err := Telldir(dir)
  2568. if err != nil {
  2569. return d, err
  2570. }
  2571. d.Off = int64(offset)
  2572. s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
  2573. copy(d.Name[:], s)
  2574. d.Reclen = uint16(24 + len(d.NameString()))
  2575. var st Stat_t
  2576. path = path + "/" + s
  2577. err = Lstat(path, &st)
  2578. if err != nil {
  2579. return d, err
  2580. }
  2581. d.Type = uint8(st.Mode >> 24)
  2582. return d, err
  2583. }
  2584. func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
  2585. // Simulation of Getdirentries port from the Darwin implementation.
  2586. // COMMENTS FROM DARWIN:
  2587. // It's not the full required semantics, but should handle the case
  2588. // of calling Getdirentries or ReadDirent repeatedly.
  2589. // It won't handle assigning the results of lseek to *basep, or handle
  2590. // the directory being edited underfoot.
  2591. skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
  2592. if err != nil {
  2593. return 0, err
  2594. }
  2595. // Get path from fd to avoid unavailable call (fdopendir)
  2596. path, err := ZosFdToPath(fd)
  2597. if err != nil {
  2598. return 0, err
  2599. }
  2600. d, err := Opendir(path)
  2601. if err != nil {
  2602. return 0, err
  2603. }
  2604. defer Closedir(d)
  2605. var cnt int64
  2606. for {
  2607. var entryLE direntLE
  2608. var entrypLE *direntLE
  2609. e := Readdir_r(d, &entryLE, &entrypLE)
  2610. if e != nil {
  2611. return n, e
  2612. }
  2613. if entrypLE == nil {
  2614. break
  2615. }
  2616. if skip > 0 {
  2617. skip--
  2618. cnt++
  2619. continue
  2620. }
  2621. // Dirent on zos has a different structure
  2622. entry, e := direntLeToDirentUnix(&entryLE, d, path)
  2623. if e != nil {
  2624. return n, e
  2625. }
  2626. reclen := int(entry.Reclen)
  2627. if reclen > len(buf) {
  2628. // Not enough room. Return for now.
  2629. // The counter will let us know where we should start up again.
  2630. // Note: this strategy for suspending in the middle and
  2631. // restarting is O(n^2) in the length of the directory. Oh well.
  2632. break
  2633. }
  2634. // Copy entry into return buffer.
  2635. s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
  2636. copy(buf, s)
  2637. buf = buf[reclen:]
  2638. n += reclen
  2639. cnt++
  2640. }
  2641. // Set the seek offset of the input fd to record
  2642. // how many files we've already returned.
  2643. _, err = Seek(fd, cnt, 0 /* SEEK_SET */)
  2644. if err != nil {
  2645. return n, err
  2646. }
  2647. return n, nil
  2648. }
  2649. func Err2ad() (eadd *int) {
  2650. r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)
  2651. eadd = (*int)(unsafe.Pointer(r0))
  2652. return
  2653. }
  2654. func ZosConsolePrintf(format string, v ...interface{}) (int, error) {
  2655. type __cmsg struct {
  2656. _ uint16
  2657. _ [2]uint8
  2658. __msg_length uint32
  2659. __msg uintptr
  2660. _ [4]uint8
  2661. }
  2662. msg := fmt.Sprintf(format, v...)
  2663. strptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)
  2664. len := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len
  2665. cmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}
  2666. cmd := uint32(0)
  2667. runtime.EnterSyscall()
  2668. rc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))
  2669. runtime.ExitSyscall()
  2670. if rc != 0 {
  2671. return 0, fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
  2672. }
  2673. return 0, nil
  2674. }
  2675. func ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {
  2676. if nullterm {
  2677. ebcdicBytes = []byte(str + "\x00")
  2678. } else {
  2679. ebcdicBytes = []byte(str)
  2680. }
  2681. A2e(ebcdicBytes)
  2682. return
  2683. }
  2684. func ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {
  2685. res := make([]byte, len(b))
  2686. copy(res, b)
  2687. E2a(res)
  2688. if trimRight {
  2689. str = string(bytes.TrimRight(res, " \x00"))
  2690. } else {
  2691. str = string(res)
  2692. }
  2693. return
  2694. }
  2695. func fdToPath(dirfd int) (path string, err error) {
  2696. var buffer [1024]byte
  2697. // w_ctrl()
  2698. ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
  2699. []uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
  2700. if ret == 0 {
  2701. zb := bytes.IndexByte(buffer[:], 0)
  2702. if zb == -1 {
  2703. zb = len(buffer)
  2704. }
  2705. // __e2a_l()
  2706. runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
  2707. []uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
  2708. return string(buffer[:zb]), nil
  2709. }
  2710. // __errno()
  2711. errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
  2712. []uintptr{}))))
  2713. // __errno2()
  2714. errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
  2715. []uintptr{}))
  2716. // strerror_r()
  2717. ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
  2718. []uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
  2719. if ret == 0 {
  2720. zb := bytes.IndexByte(buffer[:], 0)
  2721. if zb == -1 {
  2722. zb = len(buffer)
  2723. }
  2724. return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
  2725. } else {
  2726. return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
  2727. }
  2728. }
  2729. func impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
  2730. var _p0 *byte
  2731. _p0, err = BytePtrFromString(path)
  2732. if err != nil {
  2733. return
  2734. }
  2735. runtime.EnterSyscall()
  2736. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
  2737. runtime.ExitSyscall()
  2738. if int64(r0) == -1 {
  2739. err = errnoErr2(e1, e2)
  2740. }
  2741. return
  2742. }
  2743. //go:nosplit
  2744. func get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))
  2745. var Mkfifoat = enter_Mkfifoat
  2746. func enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
  2747. funcref := get_MkfifoatAddr()
  2748. if funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, "") == 0 {
  2749. *funcref = impl_Mkfifoat
  2750. } else {
  2751. *funcref = legacy_Mkfifoat
  2752. }
  2753. return (*funcref)(dirfd, path, mode)
  2754. }
  2755. func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
  2756. dirname, err := ZosFdToPath(dirfd)
  2757. if err != nil {
  2758. return err
  2759. }
  2760. return Mkfifo(dirname+"/"+path, mode)
  2761. }
  2762. //sys Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT
  2763. //sys Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT
  2764. //sys Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT
  2765. func fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) {
  2766. runtime.EnterSyscall()
  2767. r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg)
  2768. runtime.ExitSyscall()
  2769. val = int(r0)
  2770. if int64(r0) == -1 {
  2771. err = errnoErr2(e1, e2)
  2772. }
  2773. return
  2774. }
  2775. func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) {
  2776. switch op.(type) {
  2777. case *Flock_t:
  2778. err = FcntlFlock(fd, cmd, op.(*Flock_t))
  2779. if err != nil {
  2780. ret = -1
  2781. }
  2782. return
  2783. case int:
  2784. return FcntlInt(fd, cmd, op.(int))
  2785. case *F_cnvrt:
  2786. return fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt))))
  2787. case unsafe.Pointer:
  2788. return fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer)))
  2789. default:
  2790. return -1, EINVAL
  2791. }
  2792. return
  2793. }
  2794. func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
  2795. if raceenabled {
  2796. raceReleaseMerge(unsafe.Pointer(&ioSync))
  2797. }
  2798. return sendfile(outfd, infd, offset, count)
  2799. }
  2800. func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
  2801. // TODO: use LE call instead if the call is implemented
  2802. originalOffset, err := Seek(infd, 0, SEEK_CUR)
  2803. if err != nil {
  2804. return -1, err
  2805. }
  2806. //start reading data from in_fd
  2807. if offset != nil {
  2808. _, err := Seek(infd, *offset, SEEK_SET)
  2809. if err != nil {
  2810. return -1, err
  2811. }
  2812. }
  2813. buf := make([]byte, count)
  2814. readBuf := make([]byte, 0)
  2815. var n int = 0
  2816. for i := 0; i < count; i += n {
  2817. n, err := Read(infd, buf)
  2818. if n == 0 {
  2819. if err != nil {
  2820. return -1, err
  2821. } else { // EOF
  2822. break
  2823. }
  2824. }
  2825. readBuf = append(readBuf, buf...)
  2826. buf = buf[0:0]
  2827. }
  2828. n2, err := Write(outfd, readBuf)
  2829. if err != nil {
  2830. return -1, err
  2831. }
  2832. //When sendfile() returns, this variable will be set to the
  2833. // offset of the byte following the last byte that was read.
  2834. if offset != nil {
  2835. *offset = *offset + int64(n)
  2836. // If offset is not NULL, then sendfile() does not modify the file
  2837. // offset of in_fd
  2838. _, err := Seek(infd, originalOffset, SEEK_SET)
  2839. if err != nil {
  2840. return -1, err
  2841. }
  2842. }
  2843. return n2, nil
  2844. }