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