all repos

rss-tools @ master

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go (view raw)

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