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