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