mirror of
https://github.com/golang/sys.git
synced 2026-02-08 11:46:04 +03:00
unix: add support for zos/s390x
This adds sys/unix support for zos/s390x. These changes should not affect other platforms. Fixes golang/go#43230 Change-Id: If1c1d9df134fbc44f95ca1b214e836508696da93 Reviewed-on: https://go-review.googlesource.com/c/sys/+/275992 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Tobias Klauser <tobias.klauser@gmail.com> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
committed by
Emmanuel Odeke
parent
eede4237b3
commit
5640770f5e
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && go1.9
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
// +build go1.9
|
||||
|
||||
package unix
|
||||
|
||||
426
unix/asm_zos_s390x.s
Normal file
426
unix/asm_zos_s390x.s
Normal file
@@ -0,0 +1,426 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x && gc
|
||||
// +build zos
|
||||
// +build s390x
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define PSALAA 1208(R0)
|
||||
#define GTAB64(x) 80(x)
|
||||
#define LCA64(x) 88(x)
|
||||
#define CAA(x) 8(x)
|
||||
#define EDCHPXV(x) 1016(x) // in the CAA
|
||||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
||||
|
||||
// SS_*, where x=SAVSTACK_ASYNC
|
||||
#define SS_LE(x) 0(x)
|
||||
#define SS_GO(x) 8(x)
|
||||
#define SS_ERRNO(x) 16(x)
|
||||
#define SS_ERRNOJR(x) 20(x)
|
||||
|
||||
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
|
||||
|
||||
TEXT ·clearErrno(SB),NOSPLIT,$0-0
|
||||
BL addrerrno<>(SB)
|
||||
MOVD $0, 0(R3)
|
||||
RET
|
||||
|
||||
// Returns the address of errno in R3.
|
||||
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get __errno FuncDesc.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
ADD $(0x156*16), R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Switch to saved LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Call __errno function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
|
||||
// Switch back to Go stack.
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
RET
|
||||
|
||||
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R0, r2+40(FP)
|
||||
MOVD R0, err+48(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+48(FP)
|
||||
done:
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R0, r2+40(FP)
|
||||
MOVD R0, err+48(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+48(FP)
|
||||
done:
|
||||
RET
|
||||
|
||||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+56(FP)
|
||||
MOVD R0, r2+64(FP)
|
||||
MOVD R0, err+72(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+72(FP)
|
||||
done:
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+56(FP)
|
||||
MOVD R0, r2+64(FP)
|
||||
MOVD R0, err+72(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL ·rrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+72(FP)
|
||||
done:
|
||||
RET
|
||||
|
||||
TEXT ·syscall_syscall9(SB),NOSPLIT,$0
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
MOVD a7+56(FP), R12
|
||||
MOVD R12, (2176+48)(R4)
|
||||
MOVD a8+64(FP), R12
|
||||
MOVD R12, (2176+56)(R4)
|
||||
MOVD a9+72(FP), R12
|
||||
MOVD R12, (2176+64)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+80(FP)
|
||||
MOVD R0, r2+88(FP)
|
||||
MOVD R0, err+96(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+96(FP)
|
||||
done:
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
MOVD a7+56(FP), R12
|
||||
MOVD R12, (2176+48)(R4)
|
||||
MOVD a8+64(FP), R12
|
||||
MOVD R12, (2176+56)(R4)
|
||||
MOVD a9+72(FP), R12
|
||||
MOVD R12, (2176+64)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+80(FP)
|
||||
MOVD R0, r2+88(FP)
|
||||
MOVD R0, err+96(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+96(FP)
|
||||
done:
|
||||
RET
|
||||
|
||||
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
|
||||
TEXT ·svcCall(SB),NOSPLIT,$0
|
||||
BL runtime·save_g(SB) // Save g and stack pointer
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD R15, 0(R9)
|
||||
|
||||
MOVD argv+8(FP), R1 // Move function arguments into registers
|
||||
MOVD dsa+16(FP), g
|
||||
MOVD fnptr+0(FP), R15
|
||||
|
||||
BYTE $0x0D // Branch to function
|
||||
BYTE $0xEF
|
||||
|
||||
BL runtime·load_g(SB) // Restore g and stack pointer
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R15
|
||||
|
||||
RET
|
||||
|
||||
// func svcLoad(name *byte) unsafe.Pointer
|
||||
TEXT ·svcLoad(SB),NOSPLIT,$0
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||
MOVD $0x80000000, R1
|
||||
MOVD $0, R15
|
||||
BYTE $0x0A // SVC 08 LOAD
|
||||
BYTE $0x08
|
||||
MOVW R15, R3 // Save return code from SVC
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
CMP R3, $0 // Check SVC return code
|
||||
BNE error
|
||||
|
||||
MOVD $-2, R3 // Reset last bit of entry point to zero
|
||||
AND R0, R3
|
||||
MOVD R3, addr+8(FP) // Return entry point returned by SVC
|
||||
CMP R0, R3 // Check if last bit of entry point was set
|
||||
BNE done
|
||||
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
||||
BYTE $0x0A // SVC 09 DELETE
|
||||
BYTE $0x09
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
|
||||
error:
|
||||
MOVD $0, addr+8(FP) // Return 0 on failure
|
||||
done:
|
||||
XOR R0, R0 // Reset r0 to 0
|
||||
RET
|
||||
|
||||
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
|
||||
TEXT ·svcUnload(SB),NOSPLIT,$0
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||
MOVD addr+8(FP), R15
|
||||
BYTE $0x0A // SVC 09
|
||||
BYTE $0x09
|
||||
XOR R0, R0 // Reset r0 to 0
|
||||
MOVD R15, R1 // Save SVC return code
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
MOVD R1, rc+0(FP) // Return SVC return code
|
||||
RET
|
||||
|
||||
// func gettid() uint64
|
||||
TEXT ·gettid(SB), NOSPLIT, $0
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get CEECAATHDID
|
||||
MOVD CAA(R8), R9
|
||||
MOVD 0x3D0(R9), R9
|
||||
MOVD R9, ret+0(FP)
|
||||
|
||||
RET
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
29
unix/dev_zos.go
Normal file
29
unix/dev_zos.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by z/OS.
|
||||
//
|
||||
// The information below is extracted and adapted from <sys/stat.h> macros.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a z/OS device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 16) & 0x0000FFFF)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a z/OS device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0x0000FFFF)
|
||||
}
|
||||
|
||||
// Mkdev returns a z/OS device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return (uint64(major) << 16) | uint64(minor)
|
||||
}
|
||||
57
unix/dev_zos_test.go
Normal file
57
unix/dev_zos_test.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix_test
|
||||
|
||||
// Modified from Linux tests for device numbers.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDevices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
major uint32
|
||||
minor uint32
|
||||
}{
|
||||
// Device nums found using ls -l on z/OS
|
||||
{"/dev/null", 4, 0},
|
||||
{"/dev/zero", 4, 1},
|
||||
{"/dev/random", 4, 2},
|
||||
{"/dev/urandom", 4, 2},
|
||||
{"/dev/tty", 3, 0},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
|
||||
var stat unix.Stat_t
|
||||
err := unix.Stat(tc.path, &stat)
|
||||
if err != nil {
|
||||
if err == unix.EACCES {
|
||||
t.Skip("no permission to stat device, skipping test")
|
||||
}
|
||||
t.Errorf("failed to stat device: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
dev := uint64(stat.Rdev)
|
||||
if unix.Major(dev) != tc.major {
|
||||
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
|
||||
}
|
||||
if unix.Minor(dev) != tc.minor {
|
||||
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
|
||||
}
|
||||
if unix.Mkdev(tc.major, tc.minor) != dev {
|
||||
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
// Unix environment variables.
|
||||
|
||||
|
||||
221
unix/epoll_zos.go
Normal file
221
unix/epoll_zos.go
Normal file
@@ -0,0 +1,221 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// This file simulates epoll on z/OS using poll.
|
||||
|
||||
// Analogous to epoll_event on Linux.
|
||||
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
|
||||
type EpollEvent struct {
|
||||
Events uint32
|
||||
Fd int32
|
||||
Pad int32
|
||||
}
|
||||
|
||||
const (
|
||||
EPOLLERR = 0x8
|
||||
EPOLLHUP = 0x10
|
||||
EPOLLIN = 0x1
|
||||
EPOLLMSG = 0x400
|
||||
EPOLLOUT = 0x4
|
||||
EPOLLPRI = 0x2
|
||||
EPOLLRDBAND = 0x80
|
||||
EPOLLRDNORM = 0x40
|
||||
EPOLLWRBAND = 0x200
|
||||
EPOLLWRNORM = 0x100
|
||||
EPOLL_CTL_ADD = 0x1
|
||||
EPOLL_CTL_DEL = 0x2
|
||||
EPOLL_CTL_MOD = 0x3
|
||||
// The following constants are part of the epoll API, but represent
|
||||
// currently unsupported functionality on z/OS.
|
||||
// EPOLL_CLOEXEC = 0x80000
|
||||
// EPOLLET = 0x80000000
|
||||
// EPOLLONESHOT = 0x40000000
|
||||
// EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis
|
||||
// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
|
||||
// EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
|
||||
)
|
||||
|
||||
// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
|
||||
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
|
||||
|
||||
// epToPollEvt converts epoll event field to poll equivalent.
|
||||
// In epoll, Events is a 32-bit field, while poll uses 16 bits.
|
||||
func epToPollEvt(events uint32) int16 {
|
||||
var ep2p = map[uint32]int16{
|
||||
EPOLLIN: POLLIN,
|
||||
EPOLLOUT: POLLOUT,
|
||||
EPOLLHUP: POLLHUP,
|
||||
EPOLLPRI: POLLPRI,
|
||||
EPOLLERR: POLLERR,
|
||||
}
|
||||
|
||||
var pollEvts int16 = 0
|
||||
for epEvt, pEvt := range ep2p {
|
||||
if (events & epEvt) != 0 {
|
||||
pollEvts |= pEvt
|
||||
}
|
||||
}
|
||||
|
||||
return pollEvts
|
||||
}
|
||||
|
||||
// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
|
||||
func pToEpollEvt(revents int16) uint32 {
|
||||
var p2ep = map[int16]uint32{
|
||||
POLLIN: EPOLLIN,
|
||||
POLLOUT: EPOLLOUT,
|
||||
POLLHUP: EPOLLHUP,
|
||||
POLLPRI: EPOLLPRI,
|
||||
POLLERR: EPOLLERR,
|
||||
}
|
||||
|
||||
var epollEvts uint32 = 0
|
||||
for pEvt, epEvt := range p2ep {
|
||||
if (revents & pEvt) != 0 {
|
||||
epollEvts |= epEvt
|
||||
}
|
||||
}
|
||||
|
||||
return epollEvts
|
||||
}
|
||||
|
||||
// Per-process epoll implementation.
|
||||
type epollImpl struct {
|
||||
mu sync.Mutex
|
||||
epfd2ep map[int]*eventPoll
|
||||
nextEpfd int
|
||||
}
|
||||
|
||||
// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
|
||||
// On Linux, this is an in-kernel data structure accessed through a fd.
|
||||
type eventPoll struct {
|
||||
mu sync.Mutex
|
||||
fds map[int]*EpollEvent
|
||||
}
|
||||
|
||||
// epoll impl for this process.
|
||||
var impl epollImpl = epollImpl{
|
||||
epfd2ep: make(map[int]*eventPoll),
|
||||
nextEpfd: 0,
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
epfd = e.nextEpfd
|
||||
e.nextEpfd++
|
||||
|
||||
e.epfd2ep[epfd] = &eventPoll{
|
||||
fds: make(map[int]*EpollEvent),
|
||||
}
|
||||
return epfd, nil
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
|
||||
return e.epollcreate(4)
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
ep, ok := e.epfd2ep[epfd]
|
||||
if !ok {
|
||||
|
||||
return EBADF
|
||||
}
|
||||
|
||||
switch op {
|
||||
case EPOLL_CTL_ADD:
|
||||
// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
|
||||
// loops here (instances watching each other) and return ELOOP.
|
||||
if _, ok := ep.fds[fd]; ok {
|
||||
return EEXIST
|
||||
}
|
||||
ep.fds[fd] = event
|
||||
case EPOLL_CTL_MOD:
|
||||
if _, ok := ep.fds[fd]; !ok {
|
||||
return ENOENT
|
||||
}
|
||||
ep.fds[fd] = event
|
||||
case EPOLL_CTL_DEL:
|
||||
if _, ok := ep.fds[fd]; !ok {
|
||||
return ENOENT
|
||||
}
|
||||
delete(ep.fds, fd)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Must be called while holding ep.mu
|
||||
func (ep *eventPoll) getFds() []int {
|
||||
fds := make([]int, len(ep.fds))
|
||||
for fd := range ep.fds {
|
||||
fds = append(fds, fd)
|
||||
}
|
||||
return fds
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
||||
e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
|
||||
ep, ok := e.epfd2ep[epfd]
|
||||
|
||||
if !ok {
|
||||
e.mu.Unlock()
|
||||
return 0, EBADF
|
||||
}
|
||||
|
||||
pollfds := make([]PollFd, 4)
|
||||
for fd, epollevt := range ep.fds {
|
||||
pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
|
||||
}
|
||||
e.mu.Unlock()
|
||||
|
||||
n, err = Poll(pollfds, msec)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
i := 0
|
||||
for _, pFd := range pollfds {
|
||||
if pFd.Revents != 0 {
|
||||
events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
|
||||
i++
|
||||
}
|
||||
|
||||
if i == n {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func EpollCreate(size int) (fd int, err error) {
|
||||
return impl.epollcreate(size)
|
||||
}
|
||||
|
||||
func EpollCreate1(flag int) (fd int, err error) {
|
||||
return impl.epollcreate1(flag)
|
||||
}
|
||||
|
||||
func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
|
||||
return impl.epollctl(epfd, op, fd, event)
|
||||
}
|
||||
|
||||
// Because EpollWait mutates events, the caller is expected to coordinate
|
||||
// concurrent access if calling with the same epfd from multiple goroutines.
|
||||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
||||
return impl.epollwait(epfd, events, msec)
|
||||
}
|
||||
277
unix/epoll_zos_test.go
Normal file
277
unix/epoll_zos_test.go
Normal file
@@ -0,0 +1,277 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix_test
|
||||
|
||||
// Modified from Linux tests for epoll.
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestEpollIn(t *testing.T) {
|
||||
efd, err := unix.EpollCreate1(0) // no CLOEXEC equivalent on z/OS
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCreate1: %v", err)
|
||||
}
|
||||
// no need to defer a close on efd, as it's not a real file descriptor on zos
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
|
||||
fd := int(r.Fd())
|
||||
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
|
||||
|
||||
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCtl: %v", err)
|
||||
}
|
||||
|
||||
if _, err := w.Write([]byte("HELLO GOPHER")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
events := make([]unix.EpollEvent, 128)
|
||||
n, err := unix.EpollWait(efd, events, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollWait: %v", err)
|
||||
}
|
||||
|
||||
if n != 1 {
|
||||
t.Errorf("EpollWait: wrong number of events: got %v, expected 1", n)
|
||||
}
|
||||
|
||||
got := int(events[0].Fd)
|
||||
if got != fd {
|
||||
t.Errorf("EpollWait: wrong Fd in event: got %v, expected %v", got, fd)
|
||||
}
|
||||
|
||||
if events[0].Events&unix.EPOLLIN == 0 {
|
||||
t.Errorf("Expected EPOLLIN flag to be set, got %b", events[0].Events)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEpollHup(t *testing.T) {
|
||||
efd, err := unix.EpollCreate1(0)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCreate1: %v", err)
|
||||
}
|
||||
// no need to defer a close on efd, as it's not a real file descriptor on zos
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
fd := int(r.Fd())
|
||||
// EPOLLHUP should be reported even if not explicitly requested
|
||||
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
|
||||
|
||||
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCtl: %v", err)
|
||||
}
|
||||
|
||||
events := make([]unix.EpollEvent, 128)
|
||||
n, err := unix.EpollWait(efd, events, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollWait: %v", err)
|
||||
}
|
||||
|
||||
if events[0].Events&unix.EPOLLHUP != 0 {
|
||||
t.Errorf("EPOLLHUP flag aset without hangup event; got n=%d, flags=%b", n, events[0].Events)
|
||||
}
|
||||
|
||||
w.Close()
|
||||
|
||||
events = make([]unix.EpollEvent, 128)
|
||||
n, err = unix.EpollWait(efd, events, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollWait: %v", err)
|
||||
}
|
||||
|
||||
if n < 1 || events[0].Events&unix.EPOLLHUP == 0 {
|
||||
t.Errorf("Expected EPOLLHUP flag to be set, got n=%d, flags=%b", n, events[0].Events)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestEpollInManyFds(t *testing.T) {
|
||||
efd, err := unix.EpollCreate1(4) // Like on Linux, size arg is ignored.
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCreate: %v", err)
|
||||
}
|
||||
// no need to defer a close on efd, as it's not a real file descriptor on zos
|
||||
|
||||
rFds := make([]int, 10)
|
||||
wPipes := make([]*os.File, 10)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
|
||||
rFds[i] = int(r.Fd())
|
||||
wPipes[i] = w
|
||||
}
|
||||
|
||||
// Monitor all 10 read pipes
|
||||
for _, fd := range rFds {
|
||||
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
|
||||
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCtl: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Write to only 5 odd-numbered pipes
|
||||
for i, w := range wPipes {
|
||||
if i%2 == 0 {
|
||||
continue
|
||||
}
|
||||
if _, err := w.Write([]byte("HELLO")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
events := make([]unix.EpollEvent, 128)
|
||||
n, err := unix.EpollWait(efd, events, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollWait: %v", err)
|
||||
}
|
||||
|
||||
if n != 5 {
|
||||
t.Errorf("EpollWait: wrong number of events: got %v, expected 5", n)
|
||||
}
|
||||
|
||||
// Check level triggering here
|
||||
if _, err := wPipes[0].Write([]byte("HELLO")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Now, a total of 6 pipes have been written to - level triggered notifis should number 6
|
||||
events = make([]unix.EpollEvent, 128)
|
||||
n, err = unix.EpollWait(efd, events, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollWait: %v", err)
|
||||
}
|
||||
|
||||
if n != 6 {
|
||||
t.Errorf("EpollWait: wrong number of events: got %v, expected 6", n)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMultipleEpolls(t *testing.T) {
|
||||
efd1, err := unix.EpollCreate1(4)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCreate: %v", err)
|
||||
}
|
||||
// no need to defer a close on efd1, as it's not a real file descriptor on zos
|
||||
|
||||
efd2, err := unix.EpollCreate1(4)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCreate: %v", err)
|
||||
}
|
||||
// no need to defer a close on efd2, as it's not a real file descriptor on zos
|
||||
|
||||
rFds := make([]int, 10)
|
||||
wPipes := make([]*os.File, 10)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
|
||||
rFds[i] = int(r.Fd())
|
||||
wPipes[i] = w
|
||||
}
|
||||
|
||||
// Monitor first 7 read pipes on epoll1, last 3 on epoll2
|
||||
for i, fd := range rFds {
|
||||
var efd int
|
||||
if i < 7 {
|
||||
efd = efd1
|
||||
} else {
|
||||
efd = efd2
|
||||
}
|
||||
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
|
||||
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCtl: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Write to all 10 pipes
|
||||
for _, w := range wPipes {
|
||||
if _, err := w.Write([]byte("HELLO")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
events := make([]unix.EpollEvent, 128)
|
||||
n, err := unix.EpollWait(efd1, events, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollWait: %v", err)
|
||||
}
|
||||
if n != 7 {
|
||||
t.Errorf("EpollWait: wrong number of events on ep1: got %v, expected 7", n)
|
||||
}
|
||||
|
||||
events = make([]unix.EpollEvent, 128)
|
||||
n, err = unix.EpollWait(efd2, events, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollWait: %v", err)
|
||||
}
|
||||
if n != 3 {
|
||||
t.Errorf("EpollWait: wrong number of events on ep2: got %v, expected 3", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEpollErrors(t *testing.T) {
|
||||
efd, err := unix.EpollCreate1(4)
|
||||
if err != nil {
|
||||
t.Fatalf("EpollCreate: %v", err)
|
||||
}
|
||||
// no need to defer a close on efd, as it's not a real file descriptor on zos
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
|
||||
fd := int(r.Fd())
|
||||
|
||||
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
|
||||
if err = unix.EpollCtl(efd+1, unix.EPOLL_CTL_ADD, fd, &ev); err != unix.EBADF {
|
||||
t.Errorf("EpollCtl: got %v when EpollCtl ADD called with invalid epfd, expected EBADF", err)
|
||||
}
|
||||
|
||||
if err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev); err != nil {
|
||||
t.Fatalf("EpollCtl: %v", err)
|
||||
}
|
||||
|
||||
if err = unix.EpollCtl(efd, unix.EPOLL_CTL_MOD, -2, &ev); err != unix.ENOENT {
|
||||
t.Errorf("EpollCtl: got %v when EpollCtl MOD called with invalid fd, expected ENOENT", err)
|
||||
}
|
||||
}
|
||||
164
unix/fstatfs_zos.go
Normal file
164
unix/fstatfs_zos.go
Normal file
@@ -0,0 +1,164 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
|
||||
|
||||
func Fstatfs(fd int, stat *Statfs_t) (err error) {
|
||||
var stat_v Statvfs_t
|
||||
err = Fstatvfs(fd, &stat_v)
|
||||
if err == nil {
|
||||
// populate stat
|
||||
stat.Type = 0
|
||||
stat.Bsize = stat_v.Bsize
|
||||
stat.Blocks = stat_v.Blocks
|
||||
stat.Bfree = stat_v.Bfree
|
||||
stat.Bavail = stat_v.Bavail
|
||||
stat.Files = stat_v.Files
|
||||
stat.Ffree = stat_v.Ffree
|
||||
stat.Fsid = stat_v.Fsid
|
||||
stat.Namelen = stat_v.Namemax
|
||||
stat.Frsize = stat_v.Frsize
|
||||
stat.Flags = stat_v.Flag
|
||||
for passn := 0; passn < 5; passn++ {
|
||||
switch passn {
|
||||
case 0:
|
||||
err = tryGetmntent64(stat)
|
||||
break
|
||||
case 1:
|
||||
err = tryGetmntent128(stat)
|
||||
break
|
||||
case 2:
|
||||
err = tryGetmntent256(stat)
|
||||
break
|
||||
case 3:
|
||||
err = tryGetmntent512(stat)
|
||||
break
|
||||
case 4:
|
||||
err = tryGetmntent1024(stat)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
|
||||
if err == nil || err != nil && err != ERANGE {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func tryGetmntent64(stat *Statfs_t) (err error) {
|
||||
var mnt_ent_buffer struct {
|
||||
header W_Mnth
|
||||
filesys_info [64]W_Mntent
|
||||
}
|
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ {
|
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func tryGetmntent128(stat *Statfs_t) (err error) {
|
||||
var mnt_ent_buffer struct {
|
||||
header W_Mnth
|
||||
filesys_info [128]W_Mntent
|
||||
}
|
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ {
|
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func tryGetmntent256(stat *Statfs_t) (err error) {
|
||||
var mnt_ent_buffer struct {
|
||||
header W_Mnth
|
||||
filesys_info [256]W_Mntent
|
||||
}
|
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ {
|
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func tryGetmntent512(stat *Statfs_t) (err error) {
|
||||
var mnt_ent_buffer struct {
|
||||
header W_Mnth
|
||||
filesys_info [512]W_Mntent
|
||||
}
|
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ {
|
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func tryGetmntent1024(stat *Statfs_t) (err error) {
|
||||
var mnt_ent_buffer struct {
|
||||
header W_Mnth
|
||||
filesys_info [1024]W_Mntent
|
||||
}
|
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ {
|
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
73
unix/fstatfs_zos_test.go
Normal file
73
unix/fstatfs_zos_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestFstatfs(t *testing.T) {
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := os.Open(wd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
//Query Statfs_t and Statvfs_t from wd, check content
|
||||
var stat unix.Statfs_t
|
||||
err = unix.Fstatfs(int(file.Fd()), &stat)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var stat_v unix.Statvfs_t
|
||||
err = unix.Fstatvfs(int(file.Fd()), &stat_v)
|
||||
if stat.Bsize != stat_v.Bsize ||
|
||||
stat.Blocks != stat_v.Blocks ||
|
||||
stat.Bfree != stat_v.Bfree ||
|
||||
stat.Bavail != stat_v.Bavail ||
|
||||
stat.Files != stat_v.Files ||
|
||||
stat.Ffree != stat_v.Ffree ||
|
||||
stat.Fsid != stat_v.Fsid ||
|
||||
stat.Namelen != stat_v.Namemax ||
|
||||
stat.Frsize != stat_v.Frsize ||
|
||||
stat.Flags != stat_v.Flag {
|
||||
t.Errorf("Mismatching fields in Statfs_t and Statvfs_t.\nStatfs_t = %+v\nStatvfs_t = %+v", stat, stat_v)
|
||||
}
|
||||
|
||||
//Initialize W_Mntent, find corresponding device and check filesystem type
|
||||
var mnt_ent_buffer struct {
|
||||
header unix.W_Mnth
|
||||
filesys_info [128]unix.W_Mntent
|
||||
}
|
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
||||
var fs_count int = -1
|
||||
for fs_count < 0 {
|
||||
fs_count, err = unix.W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i := 0; i < fs_count; i++ {
|
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
||||
correct_type := uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
||||
if stat.Type != correct_type {
|
||||
t.Errorf("File system type is 0x%x. Should be 0x%x instead", stat.Type, correct_type)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
74
unix/ioctl_zos.go
Normal file
74
unix/ioctl_zos.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ioctl itself should not be exposed directly, but additional get/set
|
||||
// functions for specific types are permissible.
|
||||
|
||||
// IoctlSetInt performs an ioctl operation which sets an integer value
|
||||
// on fd, using the specified request number.
|
||||
func IoctlSetInt(fd int, req uint, value int) error {
|
||||
return ioctl(fd, req, uintptr(value))
|
||||
}
|
||||
|
||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
||||
//
|
||||
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
||||
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
|
||||
// TODO: if we get the chance, remove the req parameter and
|
||||
// hardcode TIOCSWINSZ.
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
|
||||
runtime.KeepAlive(value)
|
||||
return err
|
||||
}
|
||||
|
||||
// IoctlSetTermios performs an ioctl on fd with a *Termios.
|
||||
//
|
||||
// The req value is expected to be TCSETS, TCSETSW, or TCSETSF
|
||||
func IoctlSetTermios(fd int, req uint, value *Termios) error {
|
||||
if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) {
|
||||
return ENOSYS
|
||||
}
|
||||
err := Tcsetattr(fd, int(req), value)
|
||||
runtime.KeepAlive(value)
|
||||
return err
|
||||
}
|
||||
|
||||
// IoctlGetInt performs an ioctl operation which gets an integer value
|
||||
// from fd, using the specified request number.
|
||||
//
|
||||
// A few ioctl requests use the return value as an output parameter;
|
||||
// for those, IoctlRetInt should be used instead of this function.
|
||||
func IoctlGetInt(fd int, req uint) (int, error) {
|
||||
var value int
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
||||
return value, err
|
||||
}
|
||||
|
||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
|
||||
var value Winsize
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
||||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlGetTermios performs an ioctl on fd with a *Termios.
|
||||
//
|
||||
// The req value is expected to be TCGETS
|
||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
|
||||
var value Termios
|
||||
if req != TCGETS {
|
||||
return &value, ENOSYS
|
||||
}
|
||||
err := Tcgetattr(fd, &value)
|
||||
return &value, err
|
||||
}
|
||||
87
unix/mmap_zos_test.go
Normal file
87
unix/mmap_zos_test.go
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
// This test is based on mmap_unix_test, but tweaked for z/OS, which does not support memadvise
|
||||
// or anonymous mmapping.
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestMmap(t *testing.T) {
|
||||
tmpdir := mktmpdir(t)
|
||||
filename := filepath.Join(filepath.Join(tmpdir, "testdata"), "memmapped_file")
|
||||
destination, err := os.Create(filename)
|
||||
if err != nil {
|
||||
t.Fatal("os.Create:", err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
fmt.Fprintf(destination, "%s\n", "0 <- Flipped between 0 and 1 when test runs successfully")
|
||||
fmt.Fprintf(destination, "%s\n", "//Do not change contents - mmap test relies on this")
|
||||
destination.Close()
|
||||
fd, err := unix.Open(filename, unix.O_RDWR, 0o777)
|
||||
if err != nil {
|
||||
t.Fatalf("Open: %v", err)
|
||||
}
|
||||
|
||||
b, err := unix.Mmap(fd, 0, 8, unix.PROT_READ, unix.MAP_SHARED)
|
||||
if err != nil {
|
||||
t.Fatalf("Mmap: %v", err)
|
||||
}
|
||||
|
||||
if err := unix.Mprotect(b, unix.PROT_READ|unix.PROT_WRITE); err != nil {
|
||||
t.Fatalf("Mprotect: %v", err)
|
||||
}
|
||||
|
||||
// Flip flag in test file via mapped memory
|
||||
flagWasZero := true
|
||||
if b[0] == '0' {
|
||||
b[0] = '1'
|
||||
} else if b[0] == '1' {
|
||||
b[0] = '0'
|
||||
flagWasZero = false
|
||||
}
|
||||
|
||||
if err := unix.Msync(b, unix.MS_SYNC); err != nil {
|
||||
t.Fatalf("Msync: %v", err)
|
||||
}
|
||||
|
||||
// Read file from FS to ensure flag flipped after msync
|
||||
buf, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not read mmapped file from disc for test: %v", err)
|
||||
}
|
||||
if flagWasZero && buf[0] != '1' || !flagWasZero && buf[0] != '0' {
|
||||
t.Error("Flag flip in MAP_SHARED mmapped file not visible")
|
||||
}
|
||||
|
||||
if err := unix.Munmap(b); err != nil {
|
||||
t.Fatalf("Munmap: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func mktmpdir(t *testing.T) string {
|
||||
tmpdir, err := ioutil.TempDir("", "memmapped_file")
|
||||
if err != nil {
|
||||
t.Fatal("mktmpdir:", err)
|
||||
}
|
||||
if err := os.Mkdir(filepath.Join(tmpdir, "testdata"), 0700); err != nil {
|
||||
os.RemoveAll(tmpdir)
|
||||
t.Fatal("mktmpdir:", err)
|
||||
}
|
||||
return tmpdir
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || (darwin && !race) || (linux && !race) || (freebsd && !race) || netbsd || openbsd || solaris || dragonfly
|
||||
// +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly
|
||||
//go:build aix || (darwin && !race) || (linux && !race) || (freebsd && !race) || netbsd || openbsd || solaris || dragonfly || zos
|
||||
// +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly zos
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
// Socket control messages
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin freebsd linux netbsd openbsd solaris
|
||||
//go:build aix || darwin || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
package unix
|
||||
|
||||
@@ -37,6 +37,10 @@ func cmsgAlignOf(salen int) int {
|
||||
if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm64" {
|
||||
salign = 16
|
||||
}
|
||||
case "zos":
|
||||
// z/OS socket macros use [32-bit] sizeof(int) alignment,
|
||||
// not pointer width.
|
||||
salign = SizeofInt
|
||||
}
|
||||
|
||||
return (salen + salign - 1) & ^(salign - 1)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
// Package unix contains an interface to the low-level operating system
|
||||
// primitives. OS details vary depending on the underlying system, and
|
||||
|
||||
1781
unix/syscall_zos_s390x.go
Normal file
1781
unix/syscall_zos_s390x.go
Normal file
File diff suppressed because it is too large
Load Diff
608
unix/syscall_zos_test.go
Normal file
608
unix/syscall_zos_test.go
Normal file
@@ -0,0 +1,608 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Tests that below functions, structures and constants are consistent
|
||||
// on all Unix-like systems.
|
||||
func _() {
|
||||
// program scheduling priority functions and constants
|
||||
var (
|
||||
_ func(int, int, int) error = unix.Setpriority
|
||||
_ func(int, int) (int, error) = unix.Getpriority
|
||||
)
|
||||
const (
|
||||
_ int = unix.PRIO_USER
|
||||
_ int = unix.PRIO_PROCESS
|
||||
_ int = unix.PRIO_PGRP
|
||||
)
|
||||
|
||||
// termios constants
|
||||
const (
|
||||
_ int = unix.TCIFLUSH
|
||||
_ int = unix.TCIOFLUSH
|
||||
_ int = unix.TCOFLUSH
|
||||
)
|
||||
|
||||
// fcntl file locking structure and constants
|
||||
var (
|
||||
_ = unix.Flock_t{
|
||||
Type: int16(0),
|
||||
Whence: int16(0),
|
||||
Start: int64(0),
|
||||
Len: int64(0),
|
||||
Pid: int32(0),
|
||||
}
|
||||
)
|
||||
const (
|
||||
_ = unix.F_GETLK
|
||||
_ = unix.F_SETLK
|
||||
_ = unix.F_SETLKW
|
||||
)
|
||||
}
|
||||
|
||||
func TestErrnoSignalName(t *testing.T) {
|
||||
testErrors := []struct {
|
||||
num syscall.Errno
|
||||
name string
|
||||
}{
|
||||
{syscall.EPERM, "EDC5139I"},
|
||||
{syscall.EINVAL, "EDC5121I"},
|
||||
{syscall.ENOENT, "EDC5129I"},
|
||||
}
|
||||
|
||||
for _, te := range testErrors {
|
||||
t.Run(fmt.Sprintf("%d/%s", te.num, te.name), func(t *testing.T) {
|
||||
e := unix.ErrnoName(te.num)
|
||||
if e != te.name {
|
||||
t.Errorf("ErrnoName(%d) returned %s, want %s", te.num, e, te.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
testSignals := []struct {
|
||||
num syscall.Signal
|
||||
name string
|
||||
}{
|
||||
{syscall.SIGHUP, "SIGHUP"},
|
||||
{syscall.SIGPIPE, "SIGPIPE"},
|
||||
{syscall.SIGSEGV, "SIGSEGV"},
|
||||
}
|
||||
|
||||
for _, ts := range testSignals {
|
||||
t.Run(fmt.Sprintf("%d/%s", ts.num, ts.name), func(t *testing.T) {
|
||||
s := unix.SignalName(ts.num)
|
||||
if s != ts.name {
|
||||
t.Errorf("SignalName(%d) returned %s, want %s", ts.num, s, ts.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignalNum(t *testing.T) {
|
||||
testSignals := []struct {
|
||||
name string
|
||||
want syscall.Signal
|
||||
}{
|
||||
{"SIGHUP", syscall.SIGHUP},
|
||||
{"SIGPIPE", syscall.SIGPIPE},
|
||||
{"SIGSEGV", syscall.SIGSEGV},
|
||||
{"NONEXISTS", 0},
|
||||
}
|
||||
for _, ts := range testSignals {
|
||||
t.Run(fmt.Sprintf("%s/%d", ts.name, ts.want), func(t *testing.T) {
|
||||
got := unix.SignalNum(ts.name)
|
||||
if got != ts.want {
|
||||
t.Errorf("SignalNum(%s) returned %d, want %d", ts.name, got, ts.want)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestFcntlInt(t *testing.T) {
|
||||
t.Parallel()
|
||||
file, err := ioutil.TempFile("", "TestFnctlInt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(file.Name())
|
||||
defer file.Close()
|
||||
f := file.Fd()
|
||||
flags, err := unix.FcntlInt(f, unix.F_GETFD, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if flags&unix.FD_CLOEXEC == 0 {
|
||||
t.Errorf("flags %#x do not include FD_CLOEXEC", flags)
|
||||
}
|
||||
}
|
||||
|
||||
// TestFcntlFlock tests whether the file locking structure matches
|
||||
// the calling convention of each kernel.
|
||||
func TestFcntlFlock(t *testing.T) {
|
||||
name := filepath.Join(os.TempDir(), "TestFcntlFlock")
|
||||
fd, err := unix.Open(name, unix.O_CREAT|unix.O_RDWR|unix.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Open failed: %v", err)
|
||||
}
|
||||
defer unix.Unlink(name)
|
||||
defer unix.Close(fd)
|
||||
flock := unix.Flock_t{
|
||||
Type: unix.F_RDLCK,
|
||||
Start: 0, Len: 0, Whence: 1,
|
||||
}
|
||||
if err := unix.FcntlFlock(uintptr(fd), unix.F_GETLK, &flock); err != nil {
|
||||
t.Fatalf("FcntlFlock failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestPassFD tests passing a file descriptor over a Unix socket.
|
||||
//
|
||||
// This test involved both a parent and child process. The parent
|
||||
// process is invoked as a normal test, with "go test", which then
|
||||
// runs the child process by running the current test binary with args
|
||||
// "-test.run=^TestPassFD$" and an environment variable used to signal
|
||||
// that the test should become the child process instead.
|
||||
func TestPassFD(t *testing.T) {
|
||||
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
|
||||
t.Skip("cannot exec subprocess on iOS, skipping test")
|
||||
}
|
||||
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
|
||||
passFDChild()
|
||||
return
|
||||
}
|
||||
|
||||
if runtime.GOOS == "aix" {
|
||||
// Unix network isn't properly working on AIX
|
||||
// 7.2 with Technical Level < 2
|
||||
out, err := exec.Command("oslevel", "-s").Output()
|
||||
if err != nil {
|
||||
t.Skipf("skipping on AIX because oslevel -s failed: %v", err)
|
||||
}
|
||||
|
||||
if len(out) < len("7200-XX-ZZ-YYMM") { // AIX 7.2, Tech Level XX, Service Pack ZZ, date YYMM
|
||||
t.Skip("skipping on AIX because oslevel -s hasn't the right length")
|
||||
}
|
||||
aixVer := string(out[:4])
|
||||
tl, err := strconv.Atoi(string(out[5:7]))
|
||||
if err != nil {
|
||||
t.Skipf("skipping on AIX because oslevel -s output cannot be parsed: %v", err)
|
||||
}
|
||||
if aixVer < "7200" || (aixVer == "7200" && tl < 2) {
|
||||
t.Skip("skipped on AIX versions previous to 7.2 TL 2")
|
||||
}
|
||||
}
|
||||
|
||||
tempDir, err := ioutil.TempDir("", "TestPassFD")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Socketpair: %v", err)
|
||||
}
|
||||
defer unix.Close(fds[0])
|
||||
defer unix.Close(fds[1])
|
||||
writeFile := os.NewFile(uintptr(fds[0]), "child-writes")
|
||||
readFile := os.NewFile(uintptr(fds[1]), "parent-reads")
|
||||
defer writeFile.Close()
|
||||
defer readFile.Close()
|
||||
|
||||
cmd := exec.Command(os.Args[0], "-test.run=^TestPassFD$", "--", tempDir)
|
||||
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
|
||||
if lp := os.Getenv("LD_LIBRARY_PATH"); lp != "" {
|
||||
cmd.Env = append(cmd.Env, "LD_LIBRARY_PATH="+lp)
|
||||
}
|
||||
cmd.ExtraFiles = []*os.File{writeFile}
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
if len(out) > 0 || err != nil {
|
||||
t.Fatalf("child process: %q, %v", out, err)
|
||||
}
|
||||
|
||||
c, err := net.FileConn(readFile)
|
||||
if err != nil {
|
||||
t.Fatalf("FileConn: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
uc, ok := c.(*net.UnixConn)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected FileConn type; expected UnixConn, got %T", c)
|
||||
}
|
||||
|
||||
buf := make([]byte, 32) // expect 1 byte
|
||||
oob := make([]byte, 32) // expect 24 bytes
|
||||
closeUnix := time.AfterFunc(5*time.Second, func() {
|
||||
t.Logf("timeout reading from unix socket")
|
||||
uc.Close()
|
||||
})
|
||||
_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadMsgUnix: %v", err)
|
||||
}
|
||||
closeUnix.Stop()
|
||||
|
||||
scms, err := unix.ParseSocketControlMessage(oob[:oobn])
|
||||
if err != nil {
|
||||
t.Fatalf("ParseSocketControlMessage: %v", err)
|
||||
}
|
||||
if len(scms) != 1 {
|
||||
t.Fatalf("expected 1 SocketControlMessage; got scms = %#v", scms)
|
||||
}
|
||||
scm := scms[0]
|
||||
gotFds, err := unix.ParseUnixRights(&scm)
|
||||
if err != nil {
|
||||
t.Fatalf("unix.ParseUnixRights: %v", err)
|
||||
}
|
||||
if len(gotFds) != 1 {
|
||||
t.Fatalf("wanted 1 fd; got %#v", gotFds)
|
||||
}
|
||||
|
||||
f := os.NewFile(uintptr(gotFds[0]), "fd-from-child")
|
||||
defer f.Close()
|
||||
|
||||
got, err := ioutil.ReadAll(f)
|
||||
want := "Hello from child process!\n"
|
||||
if string(got) != want {
|
||||
t.Errorf("child process ReadAll: %q, %v; want %q", got, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
// passFDChild is the child process used by TestPassFD.
|
||||
func passFDChild() {
|
||||
defer os.Exit(0)
|
||||
|
||||
// Look for our fd. It should be fd 3, but we work around an fd leak
|
||||
// bug here (http://golang.org/issue/2603) to let it be elsewhere.
|
||||
var uc *net.UnixConn
|
||||
for fd := uintptr(3); fd <= 10; fd++ {
|
||||
f := os.NewFile(fd, "unix-conn")
|
||||
var ok bool
|
||||
netc, _ := net.FileConn(f)
|
||||
uc, ok = netc.(*net.UnixConn)
|
||||
if ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if uc == nil {
|
||||
fmt.Println("failed to find unix fd")
|
||||
return
|
||||
}
|
||||
|
||||
// Make a file f to send to our parent process on uc.
|
||||
// We make it in tempDir, which our parent will clean up.
|
||||
flag.Parse()
|
||||
tempDir := flag.Arg(0)
|
||||
f, err := ioutil.TempFile(tempDir, "")
|
||||
if err != nil {
|
||||
fmt.Printf("TempFile: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
f.Write([]byte("Hello from child process!\n"))
|
||||
f.Seek(0, 0)
|
||||
|
||||
rights := unix.UnixRights(int(f.Fd()))
|
||||
dummyByte := []byte("x")
|
||||
n, oobn, err := uc.WriteMsgUnix(dummyByte, rights, nil)
|
||||
if err != nil {
|
||||
fmt.Printf("WriteMsgUnix: %v", err)
|
||||
return
|
||||
}
|
||||
if n != 1 || oobn != len(rights) {
|
||||
fmt.Printf("WriteMsgUnix = %d, %d; want 1, %d", n, oobn, len(rights))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
|
||||
// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
|
||||
func TestUnixRightsRoundtrip(t *testing.T) {
|
||||
testCases := [...][][]int{
|
||||
{{42}},
|
||||
{{1, 2}},
|
||||
{{3, 4, 5}},
|
||||
{{}},
|
||||
{{1, 2}, {3, 4, 5}, {}, {7}},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
b := []byte{}
|
||||
var n int
|
||||
for _, fds := range testCase {
|
||||
// Last assignment to n wins
|
||||
n = len(b) + unix.CmsgLen(4*len(fds))
|
||||
b = append(b, unix.UnixRights(fds...)...)
|
||||
}
|
||||
// Truncate b
|
||||
b = b[:n]
|
||||
|
||||
scms, err := unix.ParseSocketControlMessage(b)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseSocketControlMessage: %v", err)
|
||||
}
|
||||
if len(scms) != len(testCase) {
|
||||
t.Fatalf("expected %v SocketControlMessage; got scms = %#v", len(testCase), scms)
|
||||
}
|
||||
for i, scm := range scms {
|
||||
gotFds, err := unix.ParseUnixRights(&scm)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseUnixRights: %v", err)
|
||||
}
|
||||
wantFds := testCase[i]
|
||||
if len(gotFds) != len(wantFds) {
|
||||
t.Fatalf("expected %v fds, got %#v", len(wantFds), gotFds)
|
||||
}
|
||||
for j, fd := range gotFds {
|
||||
if fd != wantFds[j] {
|
||||
t.Fatalf("expected fd %v, got %v", wantFds[j], fd)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRlimit(t *testing.T) {
|
||||
var rlimit, zero unix.Rlimit
|
||||
err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit)
|
||||
if err != nil {
|
||||
t.Fatalf("Getrlimit: save failed: %v", err)
|
||||
}
|
||||
if zero == rlimit {
|
||||
t.Fatalf("Getrlimit: save failed: got zero value %#v", rlimit)
|
||||
}
|
||||
set := rlimit
|
||||
set.Cur = set.Max - 1
|
||||
if runtime.GOOS == "darwin" && set.Cur > 10240 {
|
||||
// The max file limit is 10240, even though
|
||||
// the max returned by Getrlimit is 1<<63-1.
|
||||
// This is OPEN_MAX in sys/syslimits.h.
|
||||
set.Cur = 10240
|
||||
}
|
||||
err = unix.Setrlimit(unix.RLIMIT_NOFILE, &set)
|
||||
if err != nil {
|
||||
t.Fatalf("Setrlimit: set failed: %#v %v", set, err)
|
||||
}
|
||||
var get unix.Rlimit
|
||||
err = unix.Getrlimit(unix.RLIMIT_NOFILE, &get)
|
||||
if err != nil {
|
||||
t.Fatalf("Getrlimit: get failed: %v", err)
|
||||
}
|
||||
set = rlimit
|
||||
set.Cur = set.Max - 1
|
||||
if set != get {
|
||||
// Seems like Darwin requires some privilege to
|
||||
// increase the soft limit of rlimit sandbox, though
|
||||
// Setrlimit never reports an error.
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
default:
|
||||
t.Fatalf("Rlimit: change failed: wanted %#v got %#v", set, get)
|
||||
}
|
||||
}
|
||||
err = unix.Setrlimit(unix.RLIMIT_NOFILE, &rlimit)
|
||||
if err != nil {
|
||||
t.Fatalf("Setrlimit: restore failed: %#v %v", rlimit, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeekFailure(t *testing.T) {
|
||||
_, err := unix.Seek(-1, 0, 0)
|
||||
if err == nil {
|
||||
t.Fatalf("Seek(-1, 0, 0) did not fail")
|
||||
}
|
||||
str := err.Error() // used to crash on Linux
|
||||
t.Logf("Seek: %v", str)
|
||||
if str == "" {
|
||||
t.Fatalf("Seek(-1, 0, 0) return error with empty message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetsockoptString(t *testing.T) {
|
||||
// should not panic on empty string, see issue #31277
|
||||
err := unix.SetsockoptString(-1, 0, 0, "")
|
||||
if err == nil {
|
||||
t.Fatalf("SetsockoptString: did not fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDup(t *testing.T) {
|
||||
file, err := ioutil.TempFile("", "TestDup")
|
||||
if err != nil {
|
||||
t.Fatalf("Tempfile failed: %v", err)
|
||||
}
|
||||
defer os.Remove(file.Name())
|
||||
defer file.Close()
|
||||
f := int(file.Fd())
|
||||
|
||||
newFd, err := unix.Dup(f)
|
||||
if err != nil {
|
||||
t.Fatalf("Dup: %v", err)
|
||||
}
|
||||
|
||||
// Create and reserve a file descriptor.
|
||||
// Dup2 automatically closes it before reusing it.
|
||||
nullFile, err := os.Open("/dev/null")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dupFd := int(file.Fd())
|
||||
err = unix.Dup2(newFd, dupFd)
|
||||
if err != nil {
|
||||
t.Fatalf("Dup2: %v", err)
|
||||
}
|
||||
// Keep the dummy file open long enough to not be closed in
|
||||
// its finalizer.
|
||||
runtime.KeepAlive(nullFile)
|
||||
|
||||
b1 := []byte("Test123")
|
||||
b2 := make([]byte, 7)
|
||||
_, err = unix.Write(dupFd, b1)
|
||||
if err != nil {
|
||||
t.Fatalf("Write to dup2 fd failed: %v", err)
|
||||
}
|
||||
_, err = unix.Seek(f, 0, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Seek failed: %v", err)
|
||||
}
|
||||
_, err = unix.Read(f, b2)
|
||||
if err != nil {
|
||||
t.Fatalf("Read back failed: %v", err)
|
||||
}
|
||||
if string(b1) != string(b2) {
|
||||
t.Errorf("Dup: stdout write not in file, expected %v, got %v", string(b1), string(b2))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetwd(t *testing.T) {
|
||||
fd, err := os.Open(".")
|
||||
if err != nil {
|
||||
t.Fatalf("Open .: %s", err)
|
||||
}
|
||||
defer fd.Close()
|
||||
// Directory list for test. Do not worry if any are symlinks or do not
|
||||
// exist on some common unix desktop environments. That will be checked.
|
||||
dirs := []string{"/", "/usr/bin", "/etc", "/var", "/opt"}
|
||||
switch runtime.GOOS {
|
||||
case "android":
|
||||
dirs = []string{"/", "/system/bin"}
|
||||
case "darwin":
|
||||
switch runtime.GOARCH {
|
||||
case "arm", "arm64":
|
||||
d1, err := ioutil.TempDir("", "d1")
|
||||
if err != nil {
|
||||
t.Fatalf("TempDir: %v", err)
|
||||
}
|
||||
d2, err := ioutil.TempDir("", "d2")
|
||||
if err != nil {
|
||||
t.Fatalf("TempDir: %v", err)
|
||||
}
|
||||
dirs = []string{d1, d2}
|
||||
}
|
||||
}
|
||||
oldwd := os.Getenv("PWD")
|
||||
for _, d := range dirs {
|
||||
// Check whether d exists, is a dir and that d's path does not contain a symlink
|
||||
fi, err := os.Stat(d)
|
||||
if err != nil || !fi.IsDir() {
|
||||
t.Logf("Test dir %s stat error (%v) or not a directory, skipping", d, err)
|
||||
continue
|
||||
}
|
||||
check, err := filepath.EvalSymlinks(d)
|
||||
if err != nil || check != d {
|
||||
t.Logf("Test dir %s (%s) is symlink or other error (%v), skipping", d, check, err)
|
||||
continue
|
||||
}
|
||||
err = os.Chdir(d)
|
||||
if err != nil {
|
||||
t.Fatalf("Chdir: %v", err)
|
||||
}
|
||||
pwd, err := unix.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("Getwd in %s: %s", d, err)
|
||||
}
|
||||
os.Setenv("PWD", oldwd)
|
||||
err = fd.Chdir()
|
||||
if err != nil {
|
||||
// We changed the current directory and cannot go back.
|
||||
// Don't let the tests continue; they'll scribble
|
||||
// all over some other directory.
|
||||
fmt.Fprintf(os.Stderr, "fchdir back to dot failed: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if pwd != d {
|
||||
t.Fatalf("Getwd returned %q want %q", pwd, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMkdev(t *testing.T) {
|
||||
major := uint32(42)
|
||||
minor := uint32(7)
|
||||
dev := unix.Mkdev(major, minor)
|
||||
|
||||
if unix.Major(dev) != major {
|
||||
t.Errorf("Major(%#x) == %d, want %d", dev, unix.Major(dev), major)
|
||||
}
|
||||
if unix.Minor(dev) != minor {
|
||||
t.Errorf("Minor(%#x) == %d, want %d", dev, unix.Minor(dev), minor)
|
||||
}
|
||||
}
|
||||
|
||||
// mktmpfifo creates a temporary FIFO and provides a cleanup function.
|
||||
func mktmpfifo(t *testing.T) (*os.File, func()) {
|
||||
err := unix.Mkfifo("fifo", 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("mktmpfifo: failed to create FIFO: %v", err)
|
||||
}
|
||||
|
||||
f, err := os.OpenFile("fifo", os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
os.Remove("fifo")
|
||||
t.Fatalf("mktmpfifo: failed to open FIFO: %v", err)
|
||||
}
|
||||
|
||||
return f, func() {
|
||||
f.Close()
|
||||
os.Remove("fifo")
|
||||
}
|
||||
}
|
||||
|
||||
// utilities taken from os/os_test.go
|
||||
|
||||
func touch(t *testing.T, name string) {
|
||||
f, err := os.Create(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// chtmpdir changes the working directory to a new temporary directory and
|
||||
// provides a cleanup function. Used when PWD is read-only.
|
||||
func chtmpdir(t *testing.T) func() {
|
||||
oldwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("chtmpdir: %v", err)
|
||||
}
|
||||
d, err := ioutil.TempDir("", "test")
|
||||
if err != nil {
|
||||
t.Fatalf("chtmpdir: %v", err)
|
||||
}
|
||||
if err := os.Chdir(d); err != nil {
|
||||
t.Fatalf("chtmpdir: %v", err)
|
||||
}
|
||||
return func() {
|
||||
if err := os.Chdir(oldwd); err != nil {
|
||||
t.Fatalf("chtmpdir: %v", err)
|
||||
}
|
||||
os.RemoveAll(d)
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
831
unix/zerrors_zos_s390x.go
Normal file
831
unix/zerrors_zos_s390x.go
Normal file
@@ -0,0 +1,831 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
// Hand edited based on zerrors_linux_s390x.go
|
||||
// TODO: auto-generate.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
BRKINT = 0x0001
|
||||
CLOCK_MONOTONIC = 0x1
|
||||
CLOCK_PROCESS_CPUTIME_ID = 0x2
|
||||
CLOCK_REALTIME = 0x0
|
||||
CLOCK_THREAD_CPUTIME_ID = 0x3
|
||||
CS8 = 0x0030
|
||||
CSIZE = 0x0030
|
||||
ECHO = 0x00000008
|
||||
ECHONL = 0x00000001
|
||||
FD_CLOEXEC = 0x01
|
||||
FD_CLOFORK = 0x02
|
||||
FNDELAY = 0x04
|
||||
F_CLOSFD = 9
|
||||
F_CONTROL_CVT = 13
|
||||
F_DUPFD = 0
|
||||
F_DUPFD2 = 8
|
||||
F_GETFD = 1
|
||||
F_GETFL = 259
|
||||
F_GETLK = 5
|
||||
F_GETOWN = 10
|
||||
F_OK = 0x0
|
||||
F_RDLCK = 1
|
||||
F_SETFD = 2
|
||||
F_SETFL = 4
|
||||
F_SETLK = 6
|
||||
F_SETLKW = 7
|
||||
F_SETOWN = 11
|
||||
F_SETTAG = 12
|
||||
F_UNLCK = 3
|
||||
F_WRLCK = 2
|
||||
FSTYPE_ZFS = 0xe9 //"Z"
|
||||
FSTYPE_HFS = 0xc8 //"H"
|
||||
FSTYPE_NFS = 0xd5 //"N"
|
||||
FSTYPE_TFS = 0xe3 //"T"
|
||||
FSTYPE_AUTOMOUNT = 0xc1 //"A"
|
||||
IP6F_MORE_FRAG = 0x0001
|
||||
IP6F_OFF_MASK = 0xfff8
|
||||
IP6F_RESERVED_MASK = 0x0006
|
||||
IP6OPT_JUMBO = 0xc2
|
||||
IP6OPT_JUMBO_LEN = 6
|
||||
IP6OPT_MUTABLE = 0x20
|
||||
IP6OPT_NSAP_ADDR = 0xc3
|
||||
IP6OPT_PAD1 = 0x00
|
||||
IP6OPT_PADN = 0x01
|
||||
IP6OPT_ROUTER_ALERT = 0x05
|
||||
IP6OPT_TUNNEL_LIMIT = 0x04
|
||||
IP6OPT_TYPE_DISCARD = 0x40
|
||||
IP6OPT_TYPE_FORCEICMP = 0x80
|
||||
IP6OPT_TYPE_ICMP = 0xc0
|
||||
IP6OPT_TYPE_SKIP = 0x00
|
||||
IP6_ALERT_AN = 0x0002
|
||||
IP6_ALERT_MLD = 0x0000
|
||||
IP6_ALERT_RSVP = 0x0001
|
||||
IPPORT_RESERVED = 1024
|
||||
IPPORT_USERRESERVED = 5000
|
||||
IPPROTO_AH = 51
|
||||
IPPROTO_DSTOPTS = 60
|
||||
IPPROTO_EGP = 8
|
||||
IPPROTO_ESP = 50
|
||||
IPPROTO_FRAGMENT = 44
|
||||
IPPROTO_GGP = 2
|
||||
IPPROTO_HOPOPTS = 0
|
||||
IPPROTO_ICMP = 1
|
||||
IPPROTO_ICMPV6 = 58
|
||||
IPPROTO_IDP = 22
|
||||
IPPROTO_IP = 0
|
||||
IPPROTO_IPV6 = 41
|
||||
IPPROTO_MAX = 256
|
||||
IPPROTO_NONE = 59
|
||||
IPPROTO_PUP = 12
|
||||
IPPROTO_RAW = 255
|
||||
IPPROTO_ROUTING = 43
|
||||
IPPROTO_TCP = 6
|
||||
IPPROTO_UDP = 17
|
||||
IPV6_ADDR_PREFERENCES = 32
|
||||
IPV6_CHECKSUM = 19
|
||||
IPV6_DONTFRAG = 29
|
||||
IPV6_DSTOPTS = 23
|
||||
IPV6_HOPLIMIT = 11
|
||||
IPV6_HOPOPTS = 22
|
||||
IPV6_JOIN_GROUP = 5
|
||||
IPV6_LEAVE_GROUP = 6
|
||||
IPV6_MULTICAST_HOPS = 9
|
||||
IPV6_MULTICAST_IF = 7
|
||||
IPV6_MULTICAST_LOOP = 4
|
||||
IPV6_NEXTHOP = 20
|
||||
IPV6_PATHMTU = 12
|
||||
IPV6_PKTINFO = 13
|
||||
IPV6_PREFER_SRC_CGA = 0x10
|
||||
IPV6_PREFER_SRC_COA = 0x02
|
||||
IPV6_PREFER_SRC_HOME = 0x01
|
||||
IPV6_PREFER_SRC_NONCGA = 0x20
|
||||
IPV6_PREFER_SRC_PUBLIC = 0x08
|
||||
IPV6_PREFER_SRC_TMP = 0x04
|
||||
IPV6_RECVDSTOPTS = 28
|
||||
IPV6_RECVHOPLIMIT = 14
|
||||
IPV6_RECVHOPOPTS = 26
|
||||
IPV6_RECVPATHMTU = 16
|
||||
IPV6_RECVPKTINFO = 15
|
||||
IPV6_RECVRTHDR = 25
|
||||
IPV6_RECVTCLASS = 31
|
||||
IPV6_RTHDR = 21
|
||||
IPV6_RTHDRDSTOPTS = 24
|
||||
IPV6_RTHDR_TYPE_0 = 0
|
||||
IPV6_TCLASS = 30
|
||||
IPV6_UNICAST_HOPS = 3
|
||||
IPV6_USE_MIN_MTU = 18
|
||||
IPV6_V6ONLY = 10
|
||||
IP_ADD_MEMBERSHIP = 5
|
||||
IP_ADD_SOURCE_MEMBERSHIP = 12
|
||||
IP_BLOCK_SOURCE = 10
|
||||
IP_DEFAULT_MULTICAST_LOOP = 1
|
||||
IP_DEFAULT_MULTICAST_TTL = 1
|
||||
IP_DROP_MEMBERSHIP = 6
|
||||
IP_DROP_SOURCE_MEMBERSHIP = 13
|
||||
IP_MAX_MEMBERSHIPS = 20
|
||||
IP_MULTICAST_IF = 7
|
||||
IP_MULTICAST_LOOP = 4
|
||||
IP_MULTICAST_TTL = 3
|
||||
IP_OPTIONS = 1
|
||||
IP_PKTINFO = 101
|
||||
IP_RECVPKTINFO = 102
|
||||
IP_TOS = 2
|
||||
IP_TTL = 3
|
||||
IP_UNBLOCK_SOURCE = 11
|
||||
ICANON = 0x0010
|
||||
ICRNL = 0x0002
|
||||
IEXTEN = 0x0020
|
||||
IGNBRK = 0x0004
|
||||
IGNCR = 0x0008
|
||||
INLCR = 0x0020
|
||||
ISIG = 0x0040
|
||||
ISTRIP = 0x0080
|
||||
IXON = 0x0200
|
||||
IXOFF = 0x0100
|
||||
LOCK_SH = 0x1 // Not exist on zOS
|
||||
LOCK_EX = 0x2 // Not exist on zOS
|
||||
LOCK_NB = 0x4 // Not exist on zOS
|
||||
LOCK_UN = 0x8 // Not exist on zOS
|
||||
POLLIN = 0x0003
|
||||
POLLOUT = 0x0004
|
||||
POLLPRI = 0x0010
|
||||
POLLERR = 0x0020
|
||||
POLLHUP = 0x0040
|
||||
POLLNVAL = 0x0080
|
||||
PROT_READ = 0x1 // mmap - page can be read
|
||||
PROT_WRITE = 0x2 // page can be written
|
||||
PROT_NONE = 0x4 // can't be accessed
|
||||
PROT_EXEC = 0x8 // can be executed
|
||||
MAP_PRIVATE = 0x1 // changes are private
|
||||
MAP_SHARED = 0x2 // changes are shared
|
||||
MAP_FIXED = 0x4 // place exactly
|
||||
MS_SYNC = 0x1 // msync - synchronous writes
|
||||
MS_ASYNC = 0x2 // asynchronous writes
|
||||
MS_INVALIDATE = 0x4 // invalidate mappings
|
||||
MTM_RDONLY = 0x80000000
|
||||
MTM_RDWR = 0x40000000
|
||||
MTM_UMOUNT = 0x10000000
|
||||
MTM_IMMED = 0x08000000
|
||||
MTM_FORCE = 0x04000000
|
||||
MTM_DRAIN = 0x02000000
|
||||
MTM_RESET = 0x01000000
|
||||
MTM_SAMEMODE = 0x00100000
|
||||
MTM_UNQSEFORCE = 0x00040000
|
||||
MTM_NOSUID = 0x00000400
|
||||
MTM_SYNCHONLY = 0x00000200
|
||||
MTM_REMOUNT = 0x00000100
|
||||
MTM_NOSECURITY = 0x00000080
|
||||
O_ACCMODE = 0x03
|
||||
O_APPEND = 0x08
|
||||
O_ASYNCSIG = 0x0200
|
||||
O_CREAT = 0x80
|
||||
O_EXCL = 0x40
|
||||
O_GETFL = 0x0F
|
||||
O_LARGEFILE = 0x0400
|
||||
O_NONBLOCK = 0x04
|
||||
O_RDONLY = 0x02
|
||||
O_RDWR = 0x03
|
||||
O_SYNC = 0x0100
|
||||
O_TRUNC = 0x10
|
||||
O_WRONLY = 0x01
|
||||
O_NOCTTY = 0x20
|
||||
OPOST = 0x0001
|
||||
ONLCR = 0x0004
|
||||
PARENB = 0x0200
|
||||
PARMRK = 0x0400
|
||||
QUERYCVT = 3
|
||||
RUSAGE_CHILDREN = -0x1
|
||||
RUSAGE_SELF = 0x0 // RUSAGE_THREAD unsupported on z/OS
|
||||
SEEK_CUR = 1
|
||||
SEEK_END = 2
|
||||
SEEK_SET = 0
|
||||
SETAUTOCVTALL = 5
|
||||
SETAUTOCVTON = 2
|
||||
SETCVTALL = 4
|
||||
SETCVTOFF = 0
|
||||
SETCVTON = 1
|
||||
AF_APPLETALK = 16
|
||||
AF_CCITT = 10
|
||||
AF_CHAOS = 5
|
||||
AF_DATAKIT = 9
|
||||
AF_DLI = 13
|
||||
AF_ECMA = 8
|
||||
AF_HYLINK = 15
|
||||
AF_IMPLINK = 3
|
||||
AF_INET = 2
|
||||
AF_INET6 = 19
|
||||
AF_INTF = 20
|
||||
AF_IUCV = 17
|
||||
AF_LAT = 14
|
||||
AF_LINK = 18
|
||||
AF_MAX = 30
|
||||
AF_NBS = 7
|
||||
AF_NDD = 23
|
||||
AF_NETWARE = 22
|
||||
AF_NS = 6
|
||||
AF_PUP = 4
|
||||
AF_RIF = 21
|
||||
AF_ROUTE = 20
|
||||
AF_SNA = 11
|
||||
AF_UNIX = 1
|
||||
AF_UNSPEC = 0
|
||||
IBMTCP_IMAGE = 1
|
||||
MSG_ACK_EXPECTED = 0x10
|
||||
MSG_ACK_GEN = 0x40
|
||||
MSG_ACK_TIMEOUT = 0x20
|
||||
MSG_CONNTERM = 0x80
|
||||
MSG_CTRUNC = 0x20
|
||||
MSG_DONTROUTE = 0x4
|
||||
MSG_EOF = 0x8000
|
||||
MSG_EOR = 0x8
|
||||
MSG_MAXIOVLEN = 16
|
||||
MSG_NONBLOCK = 0x4000
|
||||
MSG_OOB = 0x1
|
||||
MSG_PEEK = 0x2
|
||||
MSG_TRUNC = 0x10
|
||||
MSG_WAITALL = 0x40
|
||||
PRIO_PROCESS = 1
|
||||
PRIO_PGRP = 2
|
||||
PRIO_USER = 3
|
||||
RLIMIT_CPU = 0
|
||||
RLIMIT_FSIZE = 1
|
||||
RLIMIT_DATA = 2
|
||||
RLIMIT_STACK = 3
|
||||
RLIMIT_CORE = 4
|
||||
RLIMIT_AS = 5
|
||||
RLIMIT_NOFILE = 6
|
||||
RLIMIT_MEMLIMIT = 7
|
||||
RLIM_INFINITY = 2147483647
|
||||
SCM_RIGHTS = 0x01
|
||||
SF_CLOSE = 0x00000002
|
||||
SF_REUSE = 0x00000001
|
||||
SHUT_RD = 0
|
||||
SHUT_RDWR = 2
|
||||
SHUT_WR = 1
|
||||
SOCK_CONN_DGRAM = 6
|
||||
SOCK_DGRAM = 2
|
||||
SOCK_RAW = 3
|
||||
SOCK_RDM = 4
|
||||
SOCK_SEQPACKET = 5
|
||||
SOCK_STREAM = 1
|
||||
SOL_SOCKET = 0xffff
|
||||
SOMAXCONN = 10
|
||||
SO_ACCEPTCONN = 0x0002
|
||||
SO_ACCEPTECONNABORTED = 0x0006
|
||||
SO_ACKNOW = 0x7700
|
||||
SO_BROADCAST = 0x0020
|
||||
SO_BULKMODE = 0x8000
|
||||
SO_CKSUMRECV = 0x0800
|
||||
SO_CLOSE = 0x01
|
||||
SO_CLUSTERCONNTYPE = 0x00004001
|
||||
SO_CLUSTERCONNTYPE_INTERNAL = 8
|
||||
SO_CLUSTERCONNTYPE_NOCONN = 0
|
||||
SO_CLUSTERCONNTYPE_NONE = 1
|
||||
SO_CLUSTERCONNTYPE_SAME_CLUSTER = 2
|
||||
SO_CLUSTERCONNTYPE_SAME_IMAGE = 4
|
||||
SO_DEBUG = 0x0001
|
||||
SO_DONTROUTE = 0x0010
|
||||
SO_ERROR = 0x1007
|
||||
SO_IGNOREINCOMINGPUSH = 0x1
|
||||
SO_IGNORESOURCEVIPA = 0x0002
|
||||
SO_KEEPALIVE = 0x0008
|
||||
SO_LINGER = 0x0080
|
||||
SO_NONBLOCKLOCAL = 0x8001
|
||||
SO_NOREUSEADDR = 0x1000
|
||||
SO_OOBINLINE = 0x0100
|
||||
SO_OPTACK = 0x8004
|
||||
SO_OPTMSS = 0x8003
|
||||
SO_RCVBUF = 0x1002
|
||||
SO_RCVLOWAT = 0x1004
|
||||
SO_RCVTIMEO = 0x1006
|
||||
SO_REUSEADDR = 0x0004
|
||||
SO_REUSEPORT = 0x0200
|
||||
SO_SECINFO = 0x00004002
|
||||
SO_SET = 0x0200
|
||||
SO_SNDBUF = 0x1001
|
||||
SO_SNDLOWAT = 0x1003
|
||||
SO_SNDTIMEO = 0x1005
|
||||
SO_TYPE = 0x1008
|
||||
SO_UNSET = 0x0400
|
||||
SO_USELOOPBACK = 0x0040
|
||||
SO_USE_IFBUFS = 0x0400
|
||||
S_ISUID = 0x0800
|
||||
S_ISGID = 0x0400
|
||||
S_ISVTX = 0x0200
|
||||
S_IRUSR = 0x0100
|
||||
S_IWUSR = 0x0080
|
||||
S_IXUSR = 0x0040
|
||||
S_IRWXU = 0x01C0
|
||||
S_IRGRP = 0x0020
|
||||
S_IWGRP = 0x0010
|
||||
S_IXGRP = 0x0008
|
||||
S_IRWXG = 0x0038
|
||||
S_IROTH = 0x0004
|
||||
S_IWOTH = 0x0002
|
||||
S_IXOTH = 0x0001
|
||||
S_IRWXO = 0x0007
|
||||
S_IREAD = S_IRUSR
|
||||
S_IWRITE = S_IWUSR
|
||||
S_IEXEC = S_IXUSR
|
||||
S_IFDIR = 0x01000000
|
||||
S_IFCHR = 0x02000000
|
||||
S_IFREG = 0x03000000
|
||||
S_IFFIFO = 0x04000000
|
||||
S_IFIFO = 0x04000000
|
||||
S_IFLNK = 0x05000000
|
||||
S_IFBLK = 0x06000000
|
||||
S_IFSOCK = 0x07000000
|
||||
S_IFVMEXTL = 0xFE000000
|
||||
S_IFVMEXTL_EXEC = 0x00010000
|
||||
S_IFVMEXTL_DATA = 0x00020000
|
||||
S_IFVMEXTL_MEL = 0x00030000
|
||||
S_IFEXTL = 0x00000001
|
||||
S_IFPROGCTL = 0x00000002
|
||||
S_IFAPFCTL = 0x00000004
|
||||
S_IFNOSHARE = 0x00000008
|
||||
S_IFSHARELIB = 0x00000010
|
||||
S_IFMT = 0xFF000000
|
||||
S_IFMST = 0x00FF0000
|
||||
TCP_KEEPALIVE = 0x8
|
||||
TCP_NODELAY = 0x1
|
||||
TIOCGWINSZ = 0x4008a368
|
||||
TIOCSWINSZ = 0x8008a367
|
||||
TIOCSBRK = 0x2000a77b
|
||||
TIOCCBRK = 0x2000a77a
|
||||
TIOCSTI = 0x8001a772
|
||||
TIOCGPGRP = 0x4004a777 // _IOR(167, 119, int)
|
||||
TCSANOW = 0
|
||||
TCSETS = 0 // equivalent to TCSANOW for tcsetattr
|
||||
TCSADRAIN = 1
|
||||
TCSETSW = 1 // equivalent to TCSADRAIN for tcsetattr
|
||||
TCSAFLUSH = 2
|
||||
TCSETSF = 2 // equivalent to TCSAFLUSH for tcsetattr
|
||||
TCGETS = 3 // not defined in ioctl.h -- zos golang only
|
||||
TCIFLUSH = 0
|
||||
TCOFLUSH = 1
|
||||
TCIOFLUSH = 2
|
||||
TCOOFF = 0
|
||||
TCOON = 1
|
||||
TCIOFF = 2
|
||||
TCION = 3
|
||||
TIOCSPGRP = 0x8004a776
|
||||
TIOCNOTTY = 0x2000a771
|
||||
TIOCEXCL = 0x2000a70d
|
||||
TIOCNXCL = 0x2000a70e
|
||||
TIOCGETD = 0x4004a700
|
||||
TIOCSETD = 0x8004a701
|
||||
TIOCPKT = 0x8004a770
|
||||
TIOCSTOP = 0x2000a76f
|
||||
TIOCSTART = 0x2000a76e
|
||||
TIOCUCNTL = 0x8004a766
|
||||
TIOCREMOTE = 0x8004a769
|
||||
TIOCMGET = 0x4004a76a
|
||||
TIOCMSET = 0x8004a76d
|
||||
TIOCMBIC = 0x8004a76b
|
||||
TIOCMBIS = 0x8004a76c
|
||||
VINTR = 0
|
||||
VQUIT = 1
|
||||
VERASE = 2
|
||||
VKILL = 3
|
||||
VEOF = 4
|
||||
VEOL = 5
|
||||
VMIN = 6
|
||||
VSTART = 7
|
||||
VSTOP = 8
|
||||
VSUSP = 9
|
||||
VTIME = 10
|
||||
WCONTINUED = 0x4
|
||||
WNOHANG = 0x1
|
||||
WUNTRACED = 0x2
|
||||
_BPX_SWAP = 1
|
||||
_BPX_NONSWAP = 2
|
||||
MCL_CURRENT = 1 // for Linux compatibility -- no zos semantics
|
||||
MCL_FUTURE = 2 // for Linux compatibility -- no zos semantics
|
||||
MCL_ONFAULT = 3 // for Linux compatibility -- no zos semantics
|
||||
MADV_NORMAL = 0 // for Linux compatibility -- no zos semantics
|
||||
MADV_RANDOM = 1 // for Linux compatibility -- no zos semantics
|
||||
MADV_SEQUENTIAL = 2 // for Linux compatibility -- no zos semantics
|
||||
MADV_WILLNEED = 3 // for Linux compatibility -- no zos semantics
|
||||
MADV_REMOVE = 4 // for Linux compatibility -- no zos semantics
|
||||
MADV_DONTFORK = 5 // for Linux compatibility -- no zos semantics
|
||||
MADV_DOFORK = 6 // for Linux compatibility -- no zos semantics
|
||||
MADV_HWPOISON = 7 // for Linux compatibility -- no zos semantics
|
||||
MADV_MERGEABLE = 8 // for Linux compatibility -- no zos semantics
|
||||
MADV_UNMERGEABLE = 9 // for Linux compatibility -- no zos semantics
|
||||
MADV_SOFT_OFFLINE = 10 // for Linux compatibility -- no zos semantics
|
||||
MADV_HUGEPAGE = 11 // for Linux compatibility -- no zos semantics
|
||||
MADV_NOHUGEPAGE = 12 // for Linux compatibility -- no zos semantics
|
||||
MADV_DONTDUMP = 13 // for Linux compatibility -- no zos semantics
|
||||
MADV_DODUMP = 14 // for Linux compatibility -- no zos semantics
|
||||
MADV_FREE = 15 // for Linux compatibility -- no zos semantics
|
||||
MADV_WIPEONFORK = 16 // for Linux compatibility -- no zos semantics
|
||||
MADV_KEEPONFORK = 17 // for Linux compatibility -- no zos semantics
|
||||
AT_SYMLINK_NOFOLLOW = 1 // for Unix compatibility -- no zos semantics
|
||||
AT_FDCWD = 2 // for Unix compatibility -- no zos semantics
|
||||
)
|
||||
|
||||
const (
|
||||
EDOM = Errno(1)
|
||||
ERANGE = Errno(2)
|
||||
EACCES = Errno(111)
|
||||
EAGAIN = Errno(112)
|
||||
EBADF = Errno(113)
|
||||
EBUSY = Errno(114)
|
||||
ECHILD = Errno(115)
|
||||
EDEADLK = Errno(116)
|
||||
EEXIST = Errno(117)
|
||||
EFAULT = Errno(118)
|
||||
EFBIG = Errno(119)
|
||||
EINTR = Errno(120)
|
||||
EINVAL = Errno(121)
|
||||
EIO = Errno(122)
|
||||
EISDIR = Errno(123)
|
||||
EMFILE = Errno(124)
|
||||
EMLINK = Errno(125)
|
||||
ENAMETOOLONG = Errno(126)
|
||||
ENFILE = Errno(127)
|
||||
ENODEV = Errno(128)
|
||||
ENOENT = Errno(129)
|
||||
ENOEXEC = Errno(130)
|
||||
ENOLCK = Errno(131)
|
||||
ENOMEM = Errno(132)
|
||||
ENOSPC = Errno(133)
|
||||
ENOSYS = Errno(134)
|
||||
ENOTDIR = Errno(135)
|
||||
ENOTEMPTY = Errno(136)
|
||||
ENOTTY = Errno(137)
|
||||
ENXIO = Errno(138)
|
||||
EPERM = Errno(139)
|
||||
EPIPE = Errno(140)
|
||||
EROFS = Errno(141)
|
||||
ESPIPE = Errno(142)
|
||||
ESRCH = Errno(143)
|
||||
EXDEV = Errno(144)
|
||||
E2BIG = Errno(145)
|
||||
ELOOP = Errno(146)
|
||||
EILSEQ = Errno(147)
|
||||
ENODATA = Errno(148)
|
||||
EOVERFLOW = Errno(149)
|
||||
EMVSNOTUP = Errno(150)
|
||||
ECMSSTORAGE = Errno(151)
|
||||
EMVSDYNALC = Errno(151)
|
||||
EMVSCVAF = Errno(152)
|
||||
EMVSCATLG = Errno(153)
|
||||
ECMSINITIAL = Errno(156)
|
||||
EMVSINITIAL = Errno(156)
|
||||
ECMSERR = Errno(157)
|
||||
EMVSERR = Errno(157)
|
||||
EMVSPARM = Errno(158)
|
||||
ECMSPFSFILE = Errno(159)
|
||||
EMVSPFSFILE = Errno(159)
|
||||
EMVSBADCHAR = Errno(160)
|
||||
ECMSPFSPERM = Errno(162)
|
||||
EMVSPFSPERM = Errno(162)
|
||||
EMVSSAFEXTRERR = Errno(163)
|
||||
EMVSSAF2ERR = Errno(164)
|
||||
EMVSTODNOTSET = Errno(165)
|
||||
EMVSPATHOPTS = Errno(166)
|
||||
EMVSNORTL = Errno(167)
|
||||
EMVSEXPIRE = Errno(168)
|
||||
EMVSPASSWORD = Errno(169)
|
||||
EMVSWLMERROR = Errno(170)
|
||||
EMVSCPLERROR = Errno(171)
|
||||
EMVSARMERROR = Errno(172)
|
||||
ELENOFORK = Errno(200)
|
||||
ELEMSGERR = Errno(201)
|
||||
EFPMASKINV = Errno(202)
|
||||
EFPMODEINV = Errno(203)
|
||||
EBUFLEN = Errno(227)
|
||||
EEXTLINK = Errno(228)
|
||||
ENODD = Errno(229)
|
||||
ECMSESMERR = Errno(230)
|
||||
ECPERR = Errno(231)
|
||||
ELEMULTITHREAD = Errno(232)
|
||||
ELEFENCE = Errno(244)
|
||||
EBADDATA = Errno(245)
|
||||
EUNKNOWN = Errno(246)
|
||||
ENOTSUP = Errno(247)
|
||||
EBADNAME = Errno(248)
|
||||
ENOTSAFE = Errno(249)
|
||||
ELEMULTITHREADFORK = Errno(257)
|
||||
ECUNNOENV = Errno(258)
|
||||
ECUNNOCONV = Errno(259)
|
||||
ECUNNOTALIGNED = Errno(260)
|
||||
ECUNERR = Errno(262)
|
||||
EIBMBADCALL = Errno(1000)
|
||||
EIBMBADPARM = Errno(1001)
|
||||
EIBMSOCKOUTOFRANGE = Errno(1002)
|
||||
EIBMSOCKINUSE = Errno(1003)
|
||||
EIBMIUCVERR = Errno(1004)
|
||||
EOFFLOADboxERROR = Errno(1005)
|
||||
EOFFLOADboxRESTART = Errno(1006)
|
||||
EOFFLOADboxDOWN = Errno(1007)
|
||||
EIBMCONFLICT = Errno(1008)
|
||||
EIBMCANCELLED = Errno(1009)
|
||||
EIBMBADTCPNAME = Errno(1011)
|
||||
ENOTBLK = Errno(1100)
|
||||
ETXTBSY = Errno(1101)
|
||||
EWOULDBLOCK = Errno(1102)
|
||||
EINPROGRESS = Errno(1103)
|
||||
EALREADY = Errno(1104)
|
||||
ENOTSOCK = Errno(1105)
|
||||
EDESTADDRREQ = Errno(1106)
|
||||
EMSGSIZE = Errno(1107)
|
||||
EPROTOTYPE = Errno(1108)
|
||||
ENOPROTOOPT = Errno(1109)
|
||||
EPROTONOSUPPORT = Errno(1110)
|
||||
ESOCKTNOSUPPORT = Errno(1111)
|
||||
EOPNOTSUPP = Errno(1112)
|
||||
EPFNOSUPPORT = Errno(1113)
|
||||
EAFNOSUPPORT = Errno(1114)
|
||||
EADDRINUSE = Errno(1115)
|
||||
EADDRNOTAVAIL = Errno(1116)
|
||||
ENETDOWN = Errno(1117)
|
||||
ENETUNREACH = Errno(1118)
|
||||
ENETRESET = Errno(1119)
|
||||
ECONNABORTED = Errno(1120)
|
||||
ECONNRESET = Errno(1121)
|
||||
ENOBUFS = Errno(1122)
|
||||
EISCONN = Errno(1123)
|
||||
ENOTCONN = Errno(1124)
|
||||
ESHUTDOWN = Errno(1125)
|
||||
ETOOMANYREFS = Errno(1126)
|
||||
ETIMEDOUT = Errno(1127)
|
||||
ECONNREFUSED = Errno(1128)
|
||||
EHOSTDOWN = Errno(1129)
|
||||
EHOSTUNREACH = Errno(1130)
|
||||
EPROCLIM = Errno(1131)
|
||||
EUSERS = Errno(1132)
|
||||
EDQUOT = Errno(1133)
|
||||
ESTALE = Errno(1134)
|
||||
EREMOTE = Errno(1135)
|
||||
ENOSTR = Errno(1136)
|
||||
ETIME = Errno(1137)
|
||||
ENOSR = Errno(1138)
|
||||
ENOMSG = Errno(1139)
|
||||
EBADMSG = Errno(1140)
|
||||
EIDRM = Errno(1141)
|
||||
ENONET = Errno(1142)
|
||||
ERREMOTE = Errno(1143)
|
||||
ENOLINK = Errno(1144)
|
||||
EADV = Errno(1145)
|
||||
ESRMNT = Errno(1146)
|
||||
ECOMM = Errno(1147)
|
||||
EPROTO = Errno(1148)
|
||||
EMULTIHOP = Errno(1149)
|
||||
EDOTDOT = Errno(1150)
|
||||
EREMCHG = Errno(1151)
|
||||
ECANCELED = Errno(1152)
|
||||
EINTRNODATA = Errno(1159)
|
||||
ENOREUSE = Errno(1160)
|
||||
ENOMOVE = Errno(1161)
|
||||
)
|
||||
|
||||
// Signals
|
||||
const (
|
||||
SIGHUP = Signal(1)
|
||||
SIGINT = Signal(2)
|
||||
SIGABRT = Signal(3)
|
||||
SIGILL = Signal(4)
|
||||
SIGPOLL = Signal(5)
|
||||
SIGURG = Signal(6)
|
||||
SIGSTOP = Signal(7)
|
||||
SIGFPE = Signal(8)
|
||||
SIGKILL = Signal(9)
|
||||
SIGBUS = Signal(10)
|
||||
SIGSEGV = Signal(11)
|
||||
SIGSYS = Signal(12)
|
||||
SIGPIPE = Signal(13)
|
||||
SIGALRM = Signal(14)
|
||||
SIGTERM = Signal(15)
|
||||
SIGUSR1 = Signal(16)
|
||||
SIGUSR2 = Signal(17)
|
||||
SIGABND = Signal(18)
|
||||
SIGCONT = Signal(19)
|
||||
SIGCHLD = Signal(20)
|
||||
SIGTTIN = Signal(21)
|
||||
SIGTTOU = Signal(22)
|
||||
SIGIO = Signal(23)
|
||||
SIGQUIT = Signal(24)
|
||||
SIGTSTP = Signal(25)
|
||||
SIGTRAP = Signal(26)
|
||||
SIGIOERR = Signal(27)
|
||||
SIGWINCH = Signal(28)
|
||||
SIGXCPU = Signal(29)
|
||||
SIGXFSZ = Signal(30)
|
||||
SIGVTALRM = Signal(31)
|
||||
SIGPROF = Signal(32)
|
||||
SIGDANGER = Signal(33)
|
||||
SIGTHSTOP = Signal(34)
|
||||
SIGTHCONT = Signal(35)
|
||||
SIGTRACE = Signal(37)
|
||||
SIGDCE = Signal(38)
|
||||
SIGDUMP = Signal(39)
|
||||
)
|
||||
|
||||
// Error table
|
||||
var errorList = [...]struct {
|
||||
num Errno
|
||||
name string
|
||||
desc string
|
||||
}{
|
||||
{1, "EDC5001I", "A domain error occurred."},
|
||||
{2, "EDC5002I", "A range error occurred."},
|
||||
{111, "EDC5111I", "Permission denied."},
|
||||
{112, "EDC5112I", "Resource temporarily unavailable."},
|
||||
{113, "EDC5113I", "Bad file descriptor."},
|
||||
{114, "EDC5114I", "Resource busy."},
|
||||
{115, "EDC5115I", "No child processes."},
|
||||
{116, "EDC5116I", "Resource deadlock avoided."},
|
||||
{117, "EDC5117I", "File exists."},
|
||||
{118, "EDC5118I", "Incorrect address."},
|
||||
{119, "EDC5119I", "File too large."},
|
||||
{120, "EDC5120I", "Interrupted function call."},
|
||||
{121, "EDC5121I", "Invalid argument."},
|
||||
{122, "EDC5122I", "Input/output error."},
|
||||
{123, "EDC5123I", "Is a directory."},
|
||||
{124, "EDC5124I", "Too many open files."},
|
||||
{125, "EDC5125I", "Too many links."},
|
||||
{126, "EDC5126I", "Filename too long."},
|
||||
{127, "EDC5127I", "Too many open files in system."},
|
||||
{128, "EDC5128I", "No such device."},
|
||||
{129, "EDC5129I", "No such file or directory."},
|
||||
{130, "EDC5130I", "Exec format error."},
|
||||
{131, "EDC5131I", "No locks available."},
|
||||
{132, "EDC5132I", "Not enough memory."},
|
||||
{133, "EDC5133I", "No space left on device."},
|
||||
{134, "EDC5134I", "Function not implemented."},
|
||||
{135, "EDC5135I", "Not a directory."},
|
||||
{136, "EDC5136I", "Directory not empty."},
|
||||
{137, "EDC5137I", "Inappropriate I/O control operation."},
|
||||
{138, "EDC5138I", "No such device or address."},
|
||||
{139, "EDC5139I", "Operation not permitted."},
|
||||
{140, "EDC5140I", "Broken pipe."},
|
||||
{141, "EDC5141I", "Read-only file system."},
|
||||
{142, "EDC5142I", "Invalid seek."},
|
||||
{143, "EDC5143I", "No such process."},
|
||||
{144, "EDC5144I", "Improper link."},
|
||||
{145, "EDC5145I", "The parameter list is too long, or the message to receive was too large for the buffer."},
|
||||
{146, "EDC5146I", "Too many levels of symbolic links."},
|
||||
{147, "EDC5147I", "Illegal byte sequence."},
|
||||
{148, "", ""},
|
||||
{149, "EDC5149I", "Value Overflow Error."},
|
||||
{150, "EDC5150I", "UNIX System Services is not active."},
|
||||
{151, "EDC5151I", "Dynamic allocation error."},
|
||||
{152, "EDC5152I", "Common VTOC access facility (CVAF) error."},
|
||||
{153, "EDC5153I", "Catalog obtain error."},
|
||||
{156, "EDC5156I", "Process initialization error."},
|
||||
{157, "EDC5157I", "An internal error has occurred."},
|
||||
{158, "EDC5158I", "Bad parameters were passed to the service."},
|
||||
{159, "EDC5159I", "The Physical File System encountered a permanent file error."},
|
||||
{160, "EDC5160I", "Bad character in environment variable name."},
|
||||
{162, "EDC5162I", "The Physical File System encountered a system error."},
|
||||
{163, "EDC5163I", "SAF/RACF extract error."},
|
||||
{164, "EDC5164I", "SAF/RACF error."},
|
||||
{165, "EDC5165I", "System TOD clock not set."},
|
||||
{166, "EDC5166I", "Access mode argument on function call conflicts with PATHOPTS parameter on JCL DD statement."},
|
||||
{167, "EDC5167I", "Access to the UNIX System Services version of the C RTL is denied."},
|
||||
{168, "EDC5168I", "Password has expired."},
|
||||
{169, "EDC5169I", "Password is invalid."},
|
||||
{170, "EDC5170I", "An error was encountered with WLM."},
|
||||
{171, "EDC5171I", "An error was encountered with CPL."},
|
||||
{172, "EDC5172I", "An error was encountered with Application Response Measurement (ARM) component."},
|
||||
{200, "EDC5200I", "The application contains a Language Environment member language that cannot tolerate a fork()."},
|
||||
{201, "EDC5201I", "The Language Environment message file was not found in the hierarchical file system."},
|
||||
{202, "EDC5202E", "DLL facilities are not supported under SPC environment."},
|
||||
{203, "EDC5203E", "DLL facilities are not supported under POSIX environment."},
|
||||
{227, "EDC5227I", "Buffer is not long enough to contain a path definition"},
|
||||
{228, "EDC5228I", "The file referred to is an external link"},
|
||||
{229, "EDC5229I", "No path definition for ddname in effect"},
|
||||
{230, "EDC5230I", "ESM error."},
|
||||
{231, "EDC5231I", "CP or the external security manager had an error"},
|
||||
{232, "EDC5232I", "The function failed because it was invoked from a multithread environment."},
|
||||
{244, "EDC5244I", "The program, module or DLL is not supported in this environment."},
|
||||
{245, "EDC5245I", "Data is not valid."},
|
||||
{246, "EDC5246I", "Unknown system state."},
|
||||
{247, "EDC5247I", "Operation not supported."},
|
||||
{248, "EDC5248I", "The object name specified is not correct."},
|
||||
{249, "EDC5249I", "The function is not allowed."},
|
||||
{257, "EDC5257I", "Function cannot be called in the child process of a fork() from a multithreaded process until exec() is called."},
|
||||
{258, "EDC5258I", "A CUN_RS_NO_UNI_ENV error was issued by Unicode Services."},
|
||||
{259, "EDC5259I", "A CUN_RS_NO_CONVERSION error was issued by Unicode Services."},
|
||||
{260, "EDC5260I", "A CUN_RS_TABLE_NOT_ALIGNED error was issued by Unicode Services."},
|
||||
{262, "EDC5262I", "An iconv() function encountered an unexpected error while using Unicode Services."},
|
||||
{1000, "EDC8000I", "A bad socket-call constant was found in the IUCV header."},
|
||||
{1001, "EDC8001I", "An error was found in the IUCV header."},
|
||||
{1002, "EDC8002I", "A socket descriptor is out of range."},
|
||||
{1003, "EDC8003I", "A socket descriptor is in use."},
|
||||
{1004, "EDC8004I", "Request failed because of an IUCV error."},
|
||||
{1005, "EDC8005I", "Offload box error."},
|
||||
{1006, "EDC8006I", "Offload box restarted."},
|
||||
{1007, "EDC8007I", "Offload box down."},
|
||||
{1008, "EDC8008I", "Already a conflicting call outstanding on socket."},
|
||||
{1009, "EDC8009I", "Request cancelled using a SOCKcallCANCEL request."},
|
||||
{1011, "EDC8011I", "A name of a PFS was specified that either is not configured or is not a Sockets PFS."},
|
||||
{1100, "EDC8100I", "Block device required."},
|
||||
{1101, "EDC8101I", "Text file busy."},
|
||||
{1102, "EDC8102I", "Operation would block."},
|
||||
{1103, "EDC8103I", "Operation now in progress."},
|
||||
{1104, "EDC8104I", "Connection already in progress."},
|
||||
{1105, "EDC8105I", "Socket operation on non-socket."},
|
||||
{1106, "EDC8106I", "Destination address required."},
|
||||
{1107, "EDC8107I", "Message too long."},
|
||||
{1108, "EDC8108I", "Protocol wrong type for socket."},
|
||||
{1109, "EDC8109I", "Protocol not available."},
|
||||
{1110, "EDC8110I", "Protocol not supported."},
|
||||
{1111, "EDC8111I", "Socket type not supported."},
|
||||
{1112, "EDC8112I", "Operation not supported on socket."},
|
||||
{1113, "EDC8113I", "Protocol family not supported."},
|
||||
{1114, "EDC8114I", "Address family not supported."},
|
||||
{1115, "EDC8115I", "Address already in use."},
|
||||
{1116, "EDC8116I", "Address not available."},
|
||||
{1117, "EDC8117I", "Network is down."},
|
||||
{1118, "EDC8118I", "Network is unreachable."},
|
||||
{1119, "EDC8119I", "Network dropped connection on reset."},
|
||||
{1120, "EDC8120I", "Connection ended abnormally."},
|
||||
{1121, "EDC8121I", "Connection reset."},
|
||||
{1122, "EDC8122I", "No buffer space available."},
|
||||
{1123, "EDC8123I", "Socket already connected."},
|
||||
{1124, "EDC8124I", "Socket not connected."},
|
||||
{1125, "EDC8125I", "Can't send after socket shutdown."},
|
||||
{1126, "EDC8126I", "Too many references; can't splice."},
|
||||
{1127, "EDC8127I", "Connection timed out."},
|
||||
{1128, "EDC8128I", "Connection refused."},
|
||||
{1129, "EDC8129I", "Host is not available."},
|
||||
{1130, "EDC8130I", "Host cannot be reached."},
|
||||
{1131, "EDC8131I", "Too many processes."},
|
||||
{1132, "EDC8132I", "Too many users."},
|
||||
{1133, "EDC8133I", "Disk quota exceeded."},
|
||||
{1134, "EDC8134I", "Stale file handle."},
|
||||
{1135, "", ""},
|
||||
{1136, "EDC8136I", "File is not a STREAM."},
|
||||
{1137, "EDC8137I", "STREAMS ioctl() timeout."},
|
||||
{1138, "EDC8138I", "No STREAMS resources."},
|
||||
{1139, "EDC8139I", "The message identified by set_id and msg_id is not in the message catalog."},
|
||||
{1140, "EDC8140I", "Bad message."},
|
||||
{1141, "EDC8141I", "Identifier removed."},
|
||||
{1142, "", ""},
|
||||
{1143, "", ""},
|
||||
{1144, "EDC8144I", "The link has been severed."},
|
||||
{1145, "", ""},
|
||||
{1146, "", ""},
|
||||
{1147, "", ""},
|
||||
{1148, "EDC8148I", "Protocol error."},
|
||||
{1149, "EDC8149I", "Multihop not allowed."},
|
||||
{1150, "", ""},
|
||||
{1151, "", ""},
|
||||
{1152, "EDC8152I", "The asynchronous I/O request has been canceled."},
|
||||
{1159, "EDC8159I", "Function call was interrupted before any data was received."},
|
||||
{1160, "EDC8160I", "Socket reuse is not supported."},
|
||||
{1161, "EDC8161I", "The file system cannot currently be moved."},
|
||||
}
|
||||
|
||||
// Signal table
|
||||
var signalList = [...]struct {
|
||||
num Signal
|
||||
name string
|
||||
desc string
|
||||
}{
|
||||
{1, "SIGHUP", "hangup"},
|
||||
{2, "SIGINT", "interrupt"},
|
||||
{3, "SIGABT", "aborted"},
|
||||
{4, "SIGILL", "illegal instruction"},
|
||||
{5, "SIGPOLL", "pollable event"},
|
||||
{6, "SIGURG", "urgent I/O condition"},
|
||||
{7, "SIGSTOP", "stop process"},
|
||||
{8, "SIGFPE", "floating point exception"},
|
||||
{9, "SIGKILL", "killed"},
|
||||
{10, "SIGBUS", "bus error"},
|
||||
{11, "SIGSEGV", "segmentation fault"},
|
||||
{12, "SIGSYS", "bad argument to routine"},
|
||||
{13, "SIGPIPE", "broken pipe"},
|
||||
{14, "SIGALRM", "alarm clock"},
|
||||
{15, "SIGTERM", "terminated"},
|
||||
{16, "SIGUSR1", "user defined signal 1"},
|
||||
{17, "SIGUSR2", "user defined signal 2"},
|
||||
{18, "SIGABND", "abend"},
|
||||
{19, "SIGCONT", "continued"},
|
||||
{20, "SIGCHLD", "child exited"},
|
||||
{21, "SIGTTIN", "stopped (tty input)"},
|
||||
{22, "SIGTTOU", "stopped (tty output)"},
|
||||
{23, "SIGIO", "I/O possible"},
|
||||
{24, "SIGQUIT", "quit"},
|
||||
{25, "SIGTSTP", "stopped"},
|
||||
{26, "SIGTRAP", "trace/breakpoint trap"},
|
||||
{27, "SIGIOER", "I/O error"},
|
||||
{28, "SIGWINCH", "window changed"},
|
||||
{29, "SIGXCPU", "CPU time limit exceeded"},
|
||||
{30, "SIGXFSZ", "file size limit exceeded"},
|
||||
{31, "SIGVTALRM", "virtual timer expired"},
|
||||
{32, "SIGPROF", "profiling timer expired"},
|
||||
{33, "SIGDANGER", "danger"},
|
||||
{34, "SIGTHSTOP", "stop thread"},
|
||||
{35, "SIGTHCONT", "continue thread"},
|
||||
{37, "SIGTRACE", "trace"},
|
||||
{38, "", "DCE"},
|
||||
{39, "SIGDUMP", "dump"},
|
||||
}
|
||||
1217
unix/zsyscall_zos_s390x.go
Normal file
1217
unix/zsyscall_zos_s390x.go
Normal file
File diff suppressed because it is too large
Load Diff
2670
unix/zsysnum_zos_s390x.go
Normal file
2670
unix/zsysnum_zos_s390x.go
Normal file
File diff suppressed because it is too large
Load Diff
402
unix/ztypes_zos_s390x.go
Normal file
402
unix/ztypes_zos_s390x.go
Normal file
@@ -0,0 +1,402 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
// Hand edited based on ztypes_linux_s390x.go
|
||||
// TODO: auto-generate.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
SizeofPtr = 0x8
|
||||
SizeofShort = 0x2
|
||||
SizeofInt = 0x4
|
||||
SizeofLong = 0x8
|
||||
SizeofLongLong = 0x8
|
||||
PathMax = 0x1000
|
||||
)
|
||||
|
||||
const (
|
||||
SizeofSockaddrAny = 128
|
||||
SizeofCmsghdr = 12
|
||||
SizeofIPMreq = 8
|
||||
SizeofIPv6Mreq = 20
|
||||
SizeofICMPv6Filter = 32
|
||||
SizeofIPv6MTUInfo = 32
|
||||
SizeofLinger = 8
|
||||
SizeofSockaddrInet4 = 16
|
||||
SizeofSockaddrInet6 = 28
|
||||
SizeofTCPInfo = 0x68
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int64
|
||||
_C_long_long int64
|
||||
)
|
||||
|
||||
type Timespec struct {
|
||||
Sec int64
|
||||
Nsec int64
|
||||
}
|
||||
|
||||
type Timeval struct {
|
||||
Sec int64
|
||||
Usec int64
|
||||
}
|
||||
|
||||
type timeval_zos struct { //correct (with padding and all)
|
||||
Sec int64
|
||||
_ [4]byte // pad
|
||||
Usec int32
|
||||
}
|
||||
|
||||
type Tms struct { //clock_t is 4-byte unsigned int in zos
|
||||
Utime uint32
|
||||
Stime uint32
|
||||
Cutime uint32
|
||||
Cstime uint32
|
||||
}
|
||||
|
||||
type Time_t int64
|
||||
|
||||
type Utimbuf struct {
|
||||
Actime int64
|
||||
Modtime int64
|
||||
}
|
||||
|
||||
type Utsname struct {
|
||||
Sysname [65]byte
|
||||
Nodename [65]byte
|
||||
Release [65]byte
|
||||
Version [65]byte
|
||||
Machine [65]byte
|
||||
Domainname [65]byte
|
||||
}
|
||||
|
||||
type RawSockaddrInet4 struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Addr [4]byte /* in_addr */
|
||||
Zero [8]uint8
|
||||
}
|
||||
|
||||
type RawSockaddrInet6 struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Flowinfo uint32
|
||||
Addr [16]byte /* in6_addr */
|
||||
Scope_id uint32
|
||||
}
|
||||
|
||||
type RawSockaddrUnix struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Path [108]int8
|
||||
}
|
||||
|
||||
type RawSockaddr struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Data [14]uint8
|
||||
}
|
||||
|
||||
type RawSockaddrAny struct {
|
||||
Addr RawSockaddr
|
||||
_ [112]uint8 // pad
|
||||
}
|
||||
|
||||
type _Socklen uint32
|
||||
|
||||
type Linger struct {
|
||||
Onoff int32
|
||||
Linger int32
|
||||
}
|
||||
|
||||
type Iovec struct {
|
||||
Base *byte
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type IPMreq struct {
|
||||
Multiaddr [4]byte /* in_addr */
|
||||
Interface [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type IPv6Mreq struct {
|
||||
Multiaddr [16]byte /* in6_addr */
|
||||
Interface uint32
|
||||
}
|
||||
|
||||
type Msghdr struct {
|
||||
Name *byte
|
||||
Iov *Iovec
|
||||
Control *byte
|
||||
Flags int32
|
||||
Namelen int32
|
||||
Iovlen int32
|
||||
Controllen int32
|
||||
}
|
||||
|
||||
type Cmsghdr struct {
|
||||
Len int32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
type Inet4Pktinfo struct {
|
||||
Addr [4]byte /* in_addr */
|
||||
Ifindex uint32
|
||||
}
|
||||
|
||||
type Inet6Pktinfo struct {
|
||||
Addr [16]byte /* in6_addr */
|
||||
Ifindex uint32
|
||||
}
|
||||
|
||||
type IPv6MTUInfo struct {
|
||||
Addr RawSockaddrInet6
|
||||
Mtu uint32
|
||||
}
|
||||
|
||||
type ICMPv6Filter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
type TCPInfo struct {
|
||||
State uint8
|
||||
Ca_state uint8
|
||||
Retransmits uint8
|
||||
Probes uint8
|
||||
Backoff uint8
|
||||
Options uint8
|
||||
Rto uint32
|
||||
Ato uint32
|
||||
Snd_mss uint32
|
||||
Rcv_mss uint32
|
||||
Unacked uint32
|
||||
Sacked uint32
|
||||
Lost uint32
|
||||
Retrans uint32
|
||||
Fackets uint32
|
||||
Last_data_sent uint32
|
||||
Last_ack_sent uint32
|
||||
Last_data_recv uint32
|
||||
Last_ack_recv uint32
|
||||
Pmtu uint32
|
||||
Rcv_ssthresh uint32
|
||||
Rtt uint32
|
||||
Rttvar uint32
|
||||
Snd_ssthresh uint32
|
||||
Snd_cwnd uint32
|
||||
Advmss uint32
|
||||
Reordering uint32
|
||||
Rcv_rtt uint32
|
||||
Rcv_space uint32
|
||||
Total_retrans uint32
|
||||
}
|
||||
|
||||
type _Gid_t uint32
|
||||
|
||||
type rusage_zos struct {
|
||||
Utime timeval_zos
|
||||
Stime timeval_zos
|
||||
}
|
||||
|
||||
type Rusage struct {
|
||||
Utime Timeval
|
||||
Stime Timeval
|
||||
Maxrss int64
|
||||
Ixrss int64
|
||||
Idrss int64
|
||||
Isrss int64
|
||||
Minflt int64
|
||||
Majflt int64
|
||||
Nswap int64
|
||||
Inblock int64
|
||||
Oublock int64
|
||||
Msgsnd int64
|
||||
Msgrcv int64
|
||||
Nsignals int64
|
||||
Nvcsw int64
|
||||
Nivcsw int64
|
||||
}
|
||||
|
||||
type Rlimit struct {
|
||||
Cur uint64
|
||||
Max uint64
|
||||
}
|
||||
|
||||
// { int, short, short } in poll.h
|
||||
type PollFd struct {
|
||||
Fd int32
|
||||
Events int16
|
||||
Revents int16
|
||||
}
|
||||
|
||||
type Stat_t struct { //Linux Definition
|
||||
Dev uint64
|
||||
Ino uint64
|
||||
Nlink uint64
|
||||
Mode uint32
|
||||
Uid uint32
|
||||
Gid uint32
|
||||
_ int32
|
||||
Rdev uint64
|
||||
Size int64
|
||||
Atim Timespec
|
||||
Mtim Timespec
|
||||
Ctim Timespec
|
||||
Blksize int64
|
||||
Blocks int64
|
||||
_ [3]int64
|
||||
}
|
||||
|
||||
type Stat_LE_t struct {
|
||||
_ [4]byte // eye catcher
|
||||
Length uint16
|
||||
Version uint16
|
||||
Mode int32
|
||||
Ino uint32
|
||||
Dev uint32
|
||||
Nlink int32
|
||||
Uid int32
|
||||
Gid int32
|
||||
Size int64
|
||||
Atim31 [4]byte
|
||||
Mtim31 [4]byte
|
||||
Ctim31 [4]byte
|
||||
Rdev uint32
|
||||
Auditoraudit uint32
|
||||
Useraudit uint32
|
||||
Blksize int32
|
||||
Creatim31 [4]byte
|
||||
AuditID [16]byte
|
||||
_ [4]byte // rsrvd1
|
||||
File_tag struct {
|
||||
Ccsid uint16
|
||||
Txtflag uint16 // aggregating Txflag:1 deferred:1 rsvflags:14
|
||||
}
|
||||
CharsetID [8]byte
|
||||
Blocks int64
|
||||
Genvalue uint32
|
||||
Reftim31 [4]byte
|
||||
Fid [8]byte
|
||||
Filefmt byte
|
||||
Fspflag2 byte
|
||||
_ [2]byte // rsrvd2
|
||||
Ctimemsec int32
|
||||
Seclabel [8]byte
|
||||
_ [4]byte // rsrvd3
|
||||
_ [4]byte // rsrvd4
|
||||
Atim Time_t
|
||||
Mtim Time_t
|
||||
Ctim Time_t
|
||||
Creatim Time_t
|
||||
Reftim Time_t
|
||||
_ [24]byte // rsrvd5
|
||||
}
|
||||
|
||||
type Statvfs_t struct {
|
||||
ID [4]byte
|
||||
Len int32
|
||||
Bsize uint64
|
||||
Blocks uint64
|
||||
Usedspace uint64
|
||||
Bavail uint64
|
||||
Flag uint64
|
||||
Maxfilesize int64
|
||||
_ [16]byte
|
||||
Frsize uint64
|
||||
Bfree uint64
|
||||
Files uint32
|
||||
Ffree uint32
|
||||
Favail uint32
|
||||
Namemax31 uint32
|
||||
Invarsec uint32
|
||||
_ [4]byte
|
||||
Fsid uint64
|
||||
Namemax uint64
|
||||
}
|
||||
|
||||
type Statfs_t struct {
|
||||
Type uint32
|
||||
Bsize uint64
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail uint64
|
||||
Files uint32
|
||||
Ffree uint32
|
||||
Fsid uint64
|
||||
Namelen uint64
|
||||
Frsize uint64
|
||||
Flags uint64
|
||||
}
|
||||
|
||||
type Dirent struct {
|
||||
Reclen uint16
|
||||
Namlen uint16
|
||||
Ino uint32
|
||||
Extra uintptr
|
||||
Name [256]byte
|
||||
}
|
||||
|
||||
// This struct is packed on z/OS so it can't be used directly.
|
||||
type Flock_t struct {
|
||||
Type int16
|
||||
Whence int16
|
||||
Start int64
|
||||
Len int64
|
||||
Pid int32
|
||||
}
|
||||
|
||||
type Termios struct {
|
||||
Cflag uint32
|
||||
Iflag uint32
|
||||
Lflag uint32
|
||||
Oflag uint32
|
||||
Cc [11]uint8
|
||||
}
|
||||
|
||||
type Winsize struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
Xpixel uint16
|
||||
Ypixel uint16
|
||||
}
|
||||
|
||||
type W_Mnth struct {
|
||||
Hid [4]byte
|
||||
Size int32
|
||||
Cur1 int32 //32bit pointer
|
||||
Cur2 int32 //^
|
||||
Devno uint32
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
type W_Mntent struct {
|
||||
Fstype uint32
|
||||
Mode uint32
|
||||
Dev uint32
|
||||
Parentdev uint32
|
||||
Rootino uint32
|
||||
Status byte
|
||||
Ddname [9]byte
|
||||
Fstname [9]byte
|
||||
Fsname [45]byte
|
||||
Pathlen uint32
|
||||
Mountpoint [1024]byte
|
||||
Jobname [8]byte
|
||||
PID int32
|
||||
Parmoffset int32
|
||||
Parmlen int16
|
||||
Owner [8]byte
|
||||
Quiesceowner [8]byte
|
||||
_ [38]byte
|
||||
}
|
||||
Reference in New Issue
Block a user