mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
10
vendor/golang.org/x/sys/.gitattributes
generated
vendored
10
vendor/golang.org/x/sys/.gitattributes
generated
vendored
@ -1,10 +0,0 @@
|
||||
# Treat all files in this repo as binary, with no git magic updating
|
||||
# line endings. Windows users contributing to Go will need to use a
|
||||
# modern version of git and editors capable of LF line endings.
|
||||
#
|
||||
# We'll prevent accidental CRLF line endings from entering the repo
|
||||
# via the git-review gofmt checks.
|
||||
#
|
||||
# See golang.org/issue/9281
|
||||
|
||||
* -text
|
2
vendor/golang.org/x/sys/.gitignore
generated
vendored
2
vendor/golang.org/x/sys/.gitignore
generated
vendored
@ -1,2 +0,0 @@
|
||||
# Add no patterns to .hgignore except for files generated by the build.
|
||||
last-change
|
26
vendor/golang.org/x/sys/CONTRIBUTING.md
generated
vendored
26
vendor/golang.org/x/sys/CONTRIBUTING.md
generated
vendored
@ -1,26 +0,0 @@
|
||||
# Contributing to Go
|
||||
|
||||
Go is an open source project.
|
||||
|
||||
It is the work of hundreds of contributors. We appreciate your help!
|
||||
|
||||
## Filing issues
|
||||
|
||||
When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
|
||||
|
||||
1. What version of Go are you using (`go version`)?
|
||||
2. What operating system and processor architecture are you using?
|
||||
3. What did you do?
|
||||
4. What did you expect to see?
|
||||
5. What did you see instead?
|
||||
|
||||
General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
|
||||
The gophers there will answer or ask you to file an issue if you've tripped over a bug.
|
||||
|
||||
## Contributing code
|
||||
|
||||
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
|
||||
before sending patches.
|
||||
|
||||
Unless otherwise noted, the Go source files are distributed under
|
||||
the BSD-style license found in the LICENSE file.
|
18
vendor/golang.org/x/sys/README.md
generated
vendored
18
vendor/golang.org/x/sys/README.md
generated
vendored
@ -1,18 +0,0 @@
|
||||
# sys
|
||||
|
||||
This repository holds supplemental Go packages for low-level interactions with
|
||||
the operating system.
|
||||
|
||||
## Download/Install
|
||||
|
||||
The easiest way to install is to run `go get -u golang.org/x/sys`. You can
|
||||
also manually git clone the repository to `$GOPATH/src/golang.org/x/sys`.
|
||||
|
||||
## Report Issues / Send Patches
|
||||
|
||||
This repository uses Gerrit for code changes. To learn how to submit changes to
|
||||
this repository, see https://golang.org/doc/contribute.html.
|
||||
|
||||
The main issue tracker for the sys repository is located at
|
||||
https://github.com/golang/go/issues. Prefix your issue with "x/sys:" in the
|
||||
subject line, so it is easy to find.
|
1
vendor/golang.org/x/sys/codereview.cfg
generated
vendored
1
vendor/golang.org/x/sys/codereview.cfg
generated
vendored
@ -1 +0,0 @@
|
||||
issuerepo: golang/go
|
87
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
87
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
@ -1,87 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// Package cpu implements processor feature detection for
|
||||
// various CPU architectures.
|
||||
package cpu
|
||||
|
||||
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
||||
|
||||
// X86 contains the supported CPU features of the
|
||||
// current X86/AMD64 platform. If the current platform
|
||||
// is not X86/AMD64 then all feature flags are false.
|
||||
//
|
||||
// X86 is padded to avoid false sharing. Further the HasAVX
|
||||
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||
// registers in addition to the CPUID feature bit being set.
|
||||
var X86 struct {
|
||||
_ CacheLinePad
|
||||
HasAES bool // AES hardware implementation (AES NI)
|
||||
HasADX bool // Multi-precision add-carry instruction extensions
|
||||
HasAVX bool // Advanced vector extension
|
||||
HasAVX2 bool // Advanced vector extension 2
|
||||
HasBMI1 bool // Bit manipulation instruction set 1
|
||||
HasBMI2 bool // Bit manipulation instruction set 2
|
||||
HasERMS bool // Enhanced REP for MOVSB and STOSB
|
||||
HasFMA bool // Fused-multiply-add instructions
|
||||
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
|
||||
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
|
||||
HasPOPCNT bool // Hamming weight instruction POPCNT.
|
||||
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
|
||||
HasSSE3 bool // Streaming SIMD extension 3
|
||||
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// ARM64 contains the supported CPU features of the
|
||||
// current ARMv8(aarch64) platform. If the current platform
|
||||
// is not arm64 then all feature flags are false.
|
||||
var ARM64 struct {
|
||||
_ CacheLinePad
|
||||
HasFP bool // Floating-point instruction set (always available)
|
||||
HasASIMD bool // Advanced SIMD (always available)
|
||||
HasEVTSTRM bool // Event stream support
|
||||
HasAES bool // AES hardware implementation
|
||||
HasPMULL bool // Polynomial multiplication instruction set
|
||||
HasSHA1 bool // SHA1 hardware implementation
|
||||
HasSHA2 bool // SHA2 hardware implementation
|
||||
HasCRC32 bool // CRC32 hardware implementation
|
||||
HasATOMICS bool // Atomic memory operation instruction set
|
||||
HasFPHP bool // Half precision floating-point instruction set
|
||||
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||
HasCPUID bool // CPUID identification scheme registers
|
||||
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||
HasLRCPC bool // Release Consistent processor consistent support
|
||||
HasDCPOP bool // Persistent memory support
|
||||
HasSHA3 bool // SHA3 hardware implementation
|
||||
HasSM3 bool // SM3 hardware implementation
|
||||
HasSM4 bool // SM4 hardware implementation
|
||||
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||
HasSHA512 bool // SHA512 hardware implementation
|
||||
HasSVE bool // Scalable Vector Extensions
|
||||
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
|
||||
// If the current platform is not ppc64/ppc64le then all feature flags are false.
|
||||
//
|
||||
// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
|
||||
// since there are no optional categories. There are some exceptions that also
|
||||
// require kernel support to work (DARN, SCV), so there are feature bits for
|
||||
// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
|
||||
// The struct is padded to avoid false sharing.
|
||||
var PPC64 struct {
|
||||
_ CacheLinePad
|
||||
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
||||
HasSCV bool // Syscall vectored (requires kernel enablement)
|
||||
IsPOWER8 bool // ISA v2.07 (POWER8)
|
||||
IsPOWER9 bool // ISA v3.00 (POWER9)
|
||||
_ CacheLinePad
|
||||
}
|
9
vendor/golang.org/x/sys/cpu/cpu_arm.go
generated
vendored
9
vendor/golang.org/x/sys/cpu/cpu_arm.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func doinit() {}
|
67
vendor/golang.org/x/sys/cpu/cpu_arm64.go
generated
vendored
67
vendor/golang.org/x/sys/cpu/cpu_arm64.go
generated
vendored
@ -1,67 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 64
|
||||
|
||||
// HWCAP/HWCAP2 bits. These are exposed by Linux.
|
||||
const (
|
||||
hwcap_FP = 1 << 0
|
||||
hwcap_ASIMD = 1 << 1
|
||||
hwcap_EVTSTRM = 1 << 2
|
||||
hwcap_AES = 1 << 3
|
||||
hwcap_PMULL = 1 << 4
|
||||
hwcap_SHA1 = 1 << 5
|
||||
hwcap_SHA2 = 1 << 6
|
||||
hwcap_CRC32 = 1 << 7
|
||||
hwcap_ATOMICS = 1 << 8
|
||||
hwcap_FPHP = 1 << 9
|
||||
hwcap_ASIMDHP = 1 << 10
|
||||
hwcap_CPUID = 1 << 11
|
||||
hwcap_ASIMDRDM = 1 << 12
|
||||
hwcap_JSCVT = 1 << 13
|
||||
hwcap_FCMA = 1 << 14
|
||||
hwcap_LRCPC = 1 << 15
|
||||
hwcap_DCPOP = 1 << 16
|
||||
hwcap_SHA3 = 1 << 17
|
||||
hwcap_SM3 = 1 << 18
|
||||
hwcap_SM4 = 1 << 19
|
||||
hwcap_ASIMDDP = 1 << 20
|
||||
hwcap_SHA512 = 1 << 21
|
||||
hwcap_SVE = 1 << 22
|
||||
hwcap_ASIMDFHM = 1 << 23
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// HWCAP feature bits
|
||||
ARM64.HasFP = isSet(HWCap, hwcap_FP)
|
||||
ARM64.HasASIMD = isSet(HWCap, hwcap_ASIMD)
|
||||
ARM64.HasEVTSTRM = isSet(HWCap, hwcap_EVTSTRM)
|
||||
ARM64.HasAES = isSet(HWCap, hwcap_AES)
|
||||
ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL)
|
||||
ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1)
|
||||
ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2)
|
||||
ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32)
|
||||
ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS)
|
||||
ARM64.HasFPHP = isSet(HWCap, hwcap_FPHP)
|
||||
ARM64.HasASIMDHP = isSet(HWCap, hwcap_ASIMDHP)
|
||||
ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID)
|
||||
ARM64.HasASIMDRDM = isSet(HWCap, hwcap_ASIMDRDM)
|
||||
ARM64.HasJSCVT = isSet(HWCap, hwcap_JSCVT)
|
||||
ARM64.HasFCMA = isSet(HWCap, hwcap_FCMA)
|
||||
ARM64.HasLRCPC = isSet(HWCap, hwcap_LRCPC)
|
||||
ARM64.HasDCPOP = isSet(HWCap, hwcap_DCPOP)
|
||||
ARM64.HasSHA3 = isSet(HWCap, hwcap_SHA3)
|
||||
ARM64.HasSM3 = isSet(HWCap, hwcap_SM3)
|
||||
ARM64.HasSM4 = isSet(HWCap, hwcap_SM4)
|
||||
ARM64.HasASIMDDP = isSet(HWCap, hwcap_ASIMDDP)
|
||||
ARM64.HasSHA512 = isSet(HWCap, hwcap_SHA512)
|
||||
ARM64.HasSVE = isSet(HWCap, hwcap_SVE)
|
||||
ARM64.HasASIMDFHM = isSet(HWCap, hwcap_ASIMDFHM)
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
@ -1,16 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build !gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
// cpuid is implemented in cpu_x86.s for gc compiler
|
||||
// and in cpu_gccgo.c for gccgo.
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
|
||||
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
|
||||
// and in cpu_gccgo.c for gccgo.
|
||||
func xgetbv() (eax, edx uint32)
|
43
vendor/golang.org/x/sys/cpu/cpu_gccgo.c
generated
vendored
43
vendor/golang.org/x/sys/cpu/cpu_gccgo.c
generated
vendored
@ -1,43 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build gccgo
|
||||
|
||||
#include <cpuid.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Need to wrap __get_cpuid_count because it's declared as static.
|
||||
int
|
||||
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
|
||||
uint32_t *eax, uint32_t *ebx,
|
||||
uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
|
||||
}
|
||||
|
||||
// xgetbv reads the contents of an XCR (Extended Control Register)
|
||||
// specified in the ECX register into registers EDX:EAX.
|
||||
// Currently, the only supported value for XCR is 0.
|
||||
//
|
||||
// TODO: Replace with a better alternative:
|
||||
//
|
||||
// #include <xsaveintrin.h>
|
||||
//
|
||||
// #pragma GCC target("xsave")
|
||||
//
|
||||
// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
|
||||
// unsigned long long x = _xgetbv(0);
|
||||
// *eax = x & 0xffffffff;
|
||||
// *edx = (x >> 32) & 0xffffffff;
|
||||
// }
|
||||
//
|
||||
// Note that _xgetbv is defined starting with GCC 8.
|
||||
void
|
||||
gccgoXgetbv(uint32_t *eax, uint32_t *edx)
|
||||
{
|
||||
__asm(" xorl %%ecx, %%ecx\n"
|
||||
" xgetbv"
|
||||
: "=a"(*eax), "=d"(*edx));
|
||||
}
|
26
vendor/golang.org/x/sys/cpu/cpu_gccgo.go
generated
vendored
26
vendor/golang.org/x/sys/cpu/cpu_gccgo.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
//extern gccgoGetCpuidCount
|
||||
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
|
||||
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
|
||||
var a, b, c, d uint32
|
||||
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
|
||||
return a, b, c, d
|
||||
}
|
||||
|
||||
//extern gccgoXgetbv
|
||||
func gccgoXgetbv(eax, edx *uint32)
|
||||
|
||||
func xgetbv() (eax, edx uint32) {
|
||||
var a, d uint32
|
||||
gccgoXgetbv(&a, &d)
|
||||
return a, d
|
||||
}
|
61
vendor/golang.org/x/sys/cpu/cpu_linux.go
generated
vendored
61
vendor/golang.org/x/sys/cpu/cpu_linux.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
//+build !amd64,!amd64p32,!386
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
_AT_HWCAP = 16
|
||||
_AT_HWCAP2 = 26
|
||||
|
||||
procAuxv = "/proc/self/auxv"
|
||||
|
||||
uintSize uint = 32 << (^uint(0) >> 63)
|
||||
)
|
||||
|
||||
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
|
||||
// These are initialized in cpu_$GOARCH.go
|
||||
// and should not be changed after they are initialized.
|
||||
var HWCap uint
|
||||
var HWCap2 uint
|
||||
|
||||
func init() {
|
||||
buf, err := ioutil.ReadFile(procAuxv)
|
||||
if err != nil {
|
||||
panic("read proc auxv failed: " + err.Error())
|
||||
}
|
||||
|
||||
pb := int(uintSize / 8)
|
||||
|
||||
for i := 0; i < len(buf)-pb*2; i += pb * 2 {
|
||||
var tag, val uint
|
||||
switch uintSize {
|
||||
case 32:
|
||||
tag = uint(binary.LittleEndian.Uint32(buf[i:]))
|
||||
val = uint(binary.LittleEndian.Uint32(buf[i+pb:]))
|
||||
case 64:
|
||||
if runtime.GOARCH == "ppc64" {
|
||||
tag = uint(binary.BigEndian.Uint64(buf[i:]))
|
||||
val = uint(binary.BigEndian.Uint64(buf[i+pb:]))
|
||||
} else {
|
||||
tag = uint(binary.LittleEndian.Uint64(buf[i:]))
|
||||
val = uint(binary.LittleEndian.Uint64(buf[i+pb:]))
|
||||
}
|
||||
}
|
||||
switch tag {
|
||||
case _AT_HWCAP:
|
||||
HWCap = val
|
||||
case _AT_HWCAP2:
|
||||
HWCap2 = val
|
||||
}
|
||||
}
|
||||
doinit()
|
||||
}
|
11
vendor/golang.org/x/sys/cpu/cpu_mips64x.go
generated
vendored
11
vendor/golang.org/x/sys/cpu/cpu_mips64x.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build mips64 mips64le
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func doinit() {}
|
11
vendor/golang.org/x/sys/cpu/cpu_mipsx.go
generated
vendored
11
vendor/golang.org/x/sys/cpu/cpu_mipsx.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build mips mipsle
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func doinit() {}
|
32
vendor/golang.org/x/sys/cpu/cpu_ppc64x.go
generated
vendored
32
vendor/golang.org/x/sys/cpu/cpu_ppc64x.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build ppc64 ppc64le
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 128
|
||||
|
||||
// HWCAP/HWCAP2 bits. These are exposed by the kernel.
|
||||
const (
|
||||
// ISA Level
|
||||
_PPC_FEATURE2_ARCH_2_07 = 0x80000000
|
||||
_PPC_FEATURE2_ARCH_3_00 = 0x00800000
|
||||
|
||||
// CPU features
|
||||
_PPC_FEATURE2_DARN = 0x00200000
|
||||
_PPC_FEATURE2_SCV = 0x00100000
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// HWCAP2 feature bits
|
||||
PPC64.IsPOWER8 = isSet(HWCap2, _PPC_FEATURE2_ARCH_2_07)
|
||||
PPC64.IsPOWER9 = isSet(HWCap2, _PPC_FEATURE2_ARCH_3_00)
|
||||
PPC64.HasDARN = isSet(HWCap2, _PPC_FEATURE2_DARN)
|
||||
PPC64.HasSCV = isSet(HWCap2, _PPC_FEATURE2_SCV)
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
9
vendor/golang.org/x/sys/cpu/cpu_s390x.go
generated
vendored
9
vendor/golang.org/x/sys/cpu/cpu_s390x.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 256
|
||||
|
||||
func doinit() {}
|
54
vendor/golang.org/x/sys/cpu/cpu_test.go
generated
vendored
54
vendor/golang.org/x/sys/cpu/cpu_test.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package cpu_test
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
func TestAMD64minimalFeatures(t *testing.T) {
|
||||
if runtime.GOARCH == "amd64" {
|
||||
if !cpu.X86.HasSSE2 {
|
||||
t.Fatal("HasSSE2 expected true, got false")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVX2hasAVX(t *testing.T) {
|
||||
if runtime.GOARCH == "amd64" {
|
||||
if cpu.X86.HasAVX2 && !cpu.X86.HasAVX {
|
||||
t.Fatal("HasAVX expected true, got false")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestARM64minimalFeatures(t *testing.T) {
|
||||
if runtime.GOARCH != "arm64" || runtime.GOOS != "linux" {
|
||||
return
|
||||
}
|
||||
if !cpu.ARM64.HasASIMD {
|
||||
t.Fatal("HasASIMD expected true, got false")
|
||||
}
|
||||
if !cpu.ARM64.HasFP {
|
||||
t.Fatal("HasFP expected true, got false")
|
||||
}
|
||||
}
|
||||
|
||||
// On ppc64x, the ISA bit for POWER8 should always be set on POWER8 and beyond.
|
||||
func TestPPC64minimalFeatures(t *testing.T) {
|
||||
// Do not run this with gccgo on ppc64, as it doesn't have POWER8 as a minimum
|
||||
// requirement.
|
||||
if runtime.Compiler == "gccgo" && runtime.GOARCH == "ppc64" {
|
||||
t.Skip("gccgo does not require POWER8 on ppc64; skipping")
|
||||
}
|
||||
if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" {
|
||||
if !cpu.PPC64.IsPOWER8 {
|
||||
t.Fatal("IsPOWER8 expected true, got false")
|
||||
}
|
||||
}
|
||||
}
|
55
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
55
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
@ -1,55 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 64
|
||||
|
||||
func init() {
|
||||
maxID, _, _, _ := cpuid(0, 0)
|
||||
|
||||
if maxID < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
_, _, ecx1, edx1 := cpuid(1, 0)
|
||||
X86.HasSSE2 = isSet(26, edx1)
|
||||
|
||||
X86.HasSSE3 = isSet(0, ecx1)
|
||||
X86.HasPCLMULQDQ = isSet(1, ecx1)
|
||||
X86.HasSSSE3 = isSet(9, ecx1)
|
||||
X86.HasFMA = isSet(12, ecx1)
|
||||
X86.HasSSE41 = isSet(19, ecx1)
|
||||
X86.HasSSE42 = isSet(20, ecx1)
|
||||
X86.HasPOPCNT = isSet(23, ecx1)
|
||||
X86.HasAES = isSet(25, ecx1)
|
||||
X86.HasOSXSAVE = isSet(27, ecx1)
|
||||
|
||||
osSupportsAVX := false
|
||||
// For XGETBV, OSXSAVE bit is required and sufficient.
|
||||
if X86.HasOSXSAVE {
|
||||
eax, _ := xgetbv()
|
||||
// Check if XMM and YMM registers have OS support.
|
||||
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
||||
}
|
||||
|
||||
X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
|
||||
|
||||
if maxID < 7 {
|
||||
return
|
||||
}
|
||||
|
||||
_, ebx7, _, _ := cpuid(7, 0)
|
||||
X86.HasBMI1 = isSet(3, ebx7)
|
||||
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
|
||||
X86.HasBMI2 = isSet(8, ebx7)
|
||||
X86.HasERMS = isSet(9, ebx7)
|
||||
X86.HasADX = isSet(19, ebx7)
|
||||
}
|
||||
|
||||
func isSet(bitpos uint, value uint32) bool {
|
||||
return value&(1<<bitpos) != 0
|
||||
}
|
27
vendor/golang.org/x/sys/cpu/cpu_x86.s
generated
vendored
27
vendor/golang.org/x/sys/cpu/cpu_x86.s
generated
vendored
@ -1,27 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
TEXT ·cpuid(SB), NOSPLIT, $0-24
|
||||
MOVL eaxArg+0(FP), AX
|
||||
MOVL ecxArg+4(FP), CX
|
||||
CPUID
|
||||
MOVL AX, eax+8(FP)
|
||||
MOVL BX, ebx+12(FP)
|
||||
MOVL CX, ecx+16(FP)
|
||||
MOVL DX, edx+20(FP)
|
||||
RET
|
||||
|
||||
// func xgetbv() (eax, edx uint32)
|
||||
TEXT ·xgetbv(SB),NOSPLIT,$0-8
|
||||
MOVL $0, CX
|
||||
XGETBV
|
||||
MOVL AX, eax+0(FP)
|
||||
MOVL DX, edx+4(FP)
|
||||
RET
|
8
vendor/golang.org/x/sys/plan9/asm.s
generated
vendored
8
vendor/golang.org/x/sys/plan9/asm.s
generated
vendored
@ -1,8 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·use(SB),NOSPLIT,$0
|
||||
RET
|
30
vendor/golang.org/x/sys/plan9/asm_plan9_386.s
generated
vendored
30
vendor/golang.org/x/sys/plan9/asm_plan9_386.s
generated
vendored
@ -1,30 +0,0 @@
|
||||
// Copyright 2009 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, Plan 9
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-32
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-44
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·seek(SB),NOSPLIT,$0-36
|
||||
JMP syscall·seek(SB)
|
||||
|
||||
TEXT ·exit(SB),NOSPLIT,$4-4
|
||||
JMP syscall·exit(SB)
|
30
vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
generated
vendored
30
vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
generated
vendored
@ -1,30 +0,0 @@
|
||||
// Copyright 2009 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for amd64, Plan 9
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-64
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·seek(SB),NOSPLIT,$0-56
|
||||
JMP syscall·seek(SB)
|
||||
|
||||
TEXT ·exit(SB),NOSPLIT,$8-8
|
||||
JMP syscall·exit(SB)
|
25
vendor/golang.org/x/sys/plan9/asm_plan9_arm.s
generated
vendored
25
vendor/golang.org/x/sys/plan9/asm_plan9_arm.s
generated
vendored
@ -1,25 +0,0 @@
|
||||
// Copyright 2009 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// System call support for plan9 on arm
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-32
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-44
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·seek(SB),NOSPLIT,$0-36
|
||||
JMP syscall·exit(SB)
|
70
vendor/golang.org/x/sys/plan9/const_plan9.go
generated
vendored
70
vendor/golang.org/x/sys/plan9/const_plan9.go
generated
vendored
@ -1,70 +0,0 @@
|
||||
package plan9
|
||||
|
||||
// Plan 9 Constants
|
||||
|
||||
// Open modes
|
||||
const (
|
||||
O_RDONLY = 0
|
||||
O_WRONLY = 1
|
||||
O_RDWR = 2
|
||||
O_TRUNC = 16
|
||||
O_CLOEXEC = 32
|
||||
O_EXCL = 0x1000
|
||||
)
|
||||
|
||||
// Rfork flags
|
||||
const (
|
||||
RFNAMEG = 1 << 0
|
||||
RFENVG = 1 << 1
|
||||
RFFDG = 1 << 2
|
||||
RFNOTEG = 1 << 3
|
||||
RFPROC = 1 << 4
|
||||
RFMEM = 1 << 5
|
||||
RFNOWAIT = 1 << 6
|
||||
RFCNAMEG = 1 << 10
|
||||
RFCENVG = 1 << 11
|
||||
RFCFDG = 1 << 12
|
||||
RFREND = 1 << 13
|
||||
RFNOMNT = 1 << 14
|
||||
)
|
||||
|
||||
// Qid.Type bits
|
||||
const (
|
||||
QTDIR = 0x80
|
||||
QTAPPEND = 0x40
|
||||
QTEXCL = 0x20
|
||||
QTMOUNT = 0x10
|
||||
QTAUTH = 0x08
|
||||
QTTMP = 0x04
|
||||
QTFILE = 0x00
|
||||
)
|
||||
|
||||
// Dir.Mode bits
|
||||
const (
|
||||
DMDIR = 0x80000000
|
||||
DMAPPEND = 0x40000000
|
||||
DMEXCL = 0x20000000
|
||||
DMMOUNT = 0x10000000
|
||||
DMAUTH = 0x08000000
|
||||
DMTMP = 0x04000000
|
||||
DMREAD = 0x4
|
||||
DMWRITE = 0x2
|
||||
DMEXEC = 0x1
|
||||
)
|
||||
|
||||
const (
|
||||
STATMAX = 65535
|
||||
ERRMAX = 128
|
||||
STATFIXLEN = 49
|
||||
)
|
||||
|
||||
// Mount and bind flags
|
||||
const (
|
||||
MREPL = 0x0000
|
||||
MBEFORE = 0x0001
|
||||
MAFTER = 0x0002
|
||||
MORDER = 0x0003
|
||||
MCREATE = 0x0004
|
||||
MCACHE = 0x0010
|
||||
MMASK = 0x0017
|
||||
)
|
212
vendor/golang.org/x/sys/plan9/dir_plan9.go
generated
vendored
212
vendor/golang.org/x/sys/plan9/dir_plan9.go
generated
vendored
@ -1,212 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// Plan 9 directory marshalling. See intro(5).
|
||||
|
||||
package plan9
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrShortStat = errors.New("stat buffer too short")
|
||||
ErrBadStat = errors.New("malformed stat buffer")
|
||||
ErrBadName = errors.New("bad character in file name")
|
||||
)
|
||||
|
||||
// A Qid represents a 9P server's unique identification for a file.
|
||||
type Qid struct {
|
||||
Path uint64 // the file server's unique identification for the file
|
||||
Vers uint32 // version number for given Path
|
||||
Type uint8 // the type of the file (plan9.QTDIR for example)
|
||||
}
|
||||
|
||||
// A Dir contains the metadata for a file.
|
||||
type Dir struct {
|
||||
// system-modified data
|
||||
Type uint16 // server type
|
||||
Dev uint32 // server subtype
|
||||
|
||||
// file data
|
||||
Qid Qid // unique id from server
|
||||
Mode uint32 // permissions
|
||||
Atime uint32 // last read time
|
||||
Mtime uint32 // last write time
|
||||
Length int64 // file length
|
||||
Name string // last element of path
|
||||
Uid string // owner name
|
||||
Gid string // group name
|
||||
Muid string // last modifier name
|
||||
}
|
||||
|
||||
var nullDir = Dir{
|
||||
Type: ^uint16(0),
|
||||
Dev: ^uint32(0),
|
||||
Qid: Qid{
|
||||
Path: ^uint64(0),
|
||||
Vers: ^uint32(0),
|
||||
Type: ^uint8(0),
|
||||
},
|
||||
Mode: ^uint32(0),
|
||||
Atime: ^uint32(0),
|
||||
Mtime: ^uint32(0),
|
||||
Length: ^int64(0),
|
||||
}
|
||||
|
||||
// Null assigns special "don't touch" values to members of d to
|
||||
// avoid modifying them during plan9.Wstat.
|
||||
func (d *Dir) Null() { *d = nullDir }
|
||||
|
||||
// Marshal encodes a 9P stat message corresponding to d into b
|
||||
//
|
||||
// If there isn't enough space in b for a stat message, ErrShortStat is returned.
|
||||
func (d *Dir) Marshal(b []byte) (n int, err error) {
|
||||
n = STATFIXLEN + len(d.Name) + len(d.Uid) + len(d.Gid) + len(d.Muid)
|
||||
if n > len(b) {
|
||||
return n, ErrShortStat
|
||||
}
|
||||
|
||||
for _, c := range d.Name {
|
||||
if c == '/' {
|
||||
return n, ErrBadName
|
||||
}
|
||||
}
|
||||
|
||||
b = pbit16(b, uint16(n)-2)
|
||||
b = pbit16(b, d.Type)
|
||||
b = pbit32(b, d.Dev)
|
||||
b = pbit8(b, d.Qid.Type)
|
||||
b = pbit32(b, d.Qid.Vers)
|
||||
b = pbit64(b, d.Qid.Path)
|
||||
b = pbit32(b, d.Mode)
|
||||
b = pbit32(b, d.Atime)
|
||||
b = pbit32(b, d.Mtime)
|
||||
b = pbit64(b, uint64(d.Length))
|
||||
b = pstring(b, d.Name)
|
||||
b = pstring(b, d.Uid)
|
||||
b = pstring(b, d.Gid)
|
||||
b = pstring(b, d.Muid)
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// UnmarshalDir decodes a single 9P stat message from b and returns the resulting Dir.
|
||||
//
|
||||
// If b is too small to hold a valid stat message, ErrShortStat is returned.
|
||||
//
|
||||
// If the stat message itself is invalid, ErrBadStat is returned.
|
||||
func UnmarshalDir(b []byte) (*Dir, error) {
|
||||
if len(b) < STATFIXLEN {
|
||||
return nil, ErrShortStat
|
||||
}
|
||||
size, buf := gbit16(b)
|
||||
if len(b) != int(size)+2 {
|
||||
return nil, ErrBadStat
|
||||
}
|
||||
b = buf
|
||||
|
||||
var d Dir
|
||||
d.Type, b = gbit16(b)
|
||||
d.Dev, b = gbit32(b)
|
||||
d.Qid.Type, b = gbit8(b)
|
||||
d.Qid.Vers, b = gbit32(b)
|
||||
d.Qid.Path, b = gbit64(b)
|
||||
d.Mode, b = gbit32(b)
|
||||
d.Atime, b = gbit32(b)
|
||||
d.Mtime, b = gbit32(b)
|
||||
|
||||
n, b := gbit64(b)
|
||||
d.Length = int64(n)
|
||||
|
||||
var ok bool
|
||||
if d.Name, b, ok = gstring(b); !ok {
|
||||
return nil, ErrBadStat
|
||||
}
|
||||
if d.Uid, b, ok = gstring(b); !ok {
|
||||
return nil, ErrBadStat
|
||||
}
|
||||
if d.Gid, b, ok = gstring(b); !ok {
|
||||
return nil, ErrBadStat
|
||||
}
|
||||
if d.Muid, b, ok = gstring(b); !ok {
|
||||
return nil, ErrBadStat
|
||||
}
|
||||
|
||||
return &d, nil
|
||||
}
|
||||
|
||||
// pbit8 copies the 8-bit number v to b and returns the remaining slice of b.
|
||||
func pbit8(b []byte, v uint8) []byte {
|
||||
b[0] = byte(v)
|
||||
return b[1:]
|
||||
}
|
||||
|
||||
// pbit16 copies the 16-bit number v to b in little-endian order and returns the remaining slice of b.
|
||||
func pbit16(b []byte, v uint16) []byte {
|
||||
b[0] = byte(v)
|
||||
b[1] = byte(v >> 8)
|
||||
return b[2:]
|
||||
}
|
||||
|
||||
// pbit32 copies the 32-bit number v to b in little-endian order and returns the remaining slice of b.
|
||||
func pbit32(b []byte, v uint32) []byte {
|
||||
b[0] = byte(v)
|
||||
b[1] = byte(v >> 8)
|
||||
b[2] = byte(v >> 16)
|
||||
b[3] = byte(v >> 24)
|
||||
return b[4:]
|
||||
}
|
||||
|
||||
// pbit64 copies the 64-bit number v to b in little-endian order and returns the remaining slice of b.
|
||||
func pbit64(b []byte, v uint64) []byte {
|
||||
b[0] = byte(v)
|
||||
b[1] = byte(v >> 8)
|
||||
b[2] = byte(v >> 16)
|
||||
b[3] = byte(v >> 24)
|
||||
b[4] = byte(v >> 32)
|
||||
b[5] = byte(v >> 40)
|
||||
b[6] = byte(v >> 48)
|
||||
b[7] = byte(v >> 56)
|
||||
return b[8:]
|
||||
}
|
||||
|
||||
// pstring copies the string s to b, prepending it with a 16-bit length in little-endian order, and
|
||||
// returning the remaining slice of b..
|
||||
func pstring(b []byte, s string) []byte {
|
||||
b = pbit16(b, uint16(len(s)))
|
||||
n := copy(b, s)
|
||||
return b[n:]
|
||||
}
|
||||
|
||||
// gbit8 reads an 8-bit number from b and returns it with the remaining slice of b.
|
||||
func gbit8(b []byte) (uint8, []byte) {
|
||||
return uint8(b[0]), b[1:]
|
||||
}
|
||||
|
||||
// gbit16 reads a 16-bit number in little-endian order from b and returns it with the remaining slice of b.
|
||||
func gbit16(b []byte) (uint16, []byte) {
|
||||
return uint16(b[0]) | uint16(b[1])<<8, b[2:]
|
||||
}
|
||||
|
||||
// gbit32 reads a 32-bit number in little-endian order from b and returns it with the remaining slice of b.
|
||||
func gbit32(b []byte) (uint32, []byte) {
|
||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, b[4:]
|
||||
}
|
||||
|
||||
// gbit64 reads a 64-bit number in little-endian order from b and returns it with the remaining slice of b.
|
||||
func gbit64(b []byte) (uint64, []byte) {
|
||||
lo := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
hi := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24
|
||||
return uint64(lo) | uint64(hi)<<32, b[8:]
|
||||
}
|
||||
|
||||
// gstring reads a string from b, prefixed with a 16-bit length in little-endian order.
|
||||
// It returns the string with the remaining slice of b and a boolean. If the length is
|
||||
// greater than the number of bytes in b, the boolean will be false.
|
||||
func gstring(b []byte) (string, []byte, bool) {
|
||||
n, b := gbit16(b)
|
||||
if int(n) > len(b) {
|
||||
return "", b, false
|
||||
}
|
||||
return string(b[:n]), b[n:], true
|
||||
}
|
31
vendor/golang.org/x/sys/plan9/env_plan9.go
generated
vendored
31
vendor/golang.org/x/sys/plan9/env_plan9.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
// Copyright 2011 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.
|
||||
|
||||
// Plan 9 environment variables.
|
||||
|
||||
package plan9
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func Getenv(key string) (value string, found bool) {
|
||||
return syscall.Getenv(key)
|
||||
}
|
||||
|
||||
func Setenv(key, value string) error {
|
||||
return syscall.Setenv(key, value)
|
||||
}
|
||||
|
||||
func Clearenv() {
|
||||
syscall.Clearenv()
|
||||
}
|
||||
|
||||
func Environ() []string {
|
||||
return syscall.Environ()
|
||||
}
|
||||
|
||||
func Unsetenv(key string) error {
|
||||
return syscall.Unsetenv(key)
|
||||
}
|
50
vendor/golang.org/x/sys/plan9/errors_plan9.go
generated
vendored
50
vendor/golang.org/x/sys/plan9/errors_plan9.go
generated
vendored
@ -1,50 +0,0 @@
|
||||
// Copyright 2011 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.
|
||||
|
||||
package plan9
|
||||
|
||||
import "syscall"
|
||||
|
||||
// Constants
|
||||
const (
|
||||
// Invented values to support what package os expects.
|
||||
O_CREAT = 0x02000
|
||||
O_APPEND = 0x00400
|
||||
O_NOCTTY = 0x00000
|
||||
O_NONBLOCK = 0x00000
|
||||
O_SYNC = 0x00000
|
||||
O_ASYNC = 0x00000
|
||||
|
||||
S_IFMT = 0x1f000
|
||||
S_IFIFO = 0x1000
|
||||
S_IFCHR = 0x2000
|
||||
S_IFDIR = 0x4000
|
||||
S_IFBLK = 0x6000
|
||||
S_IFREG = 0x8000
|
||||
S_IFLNK = 0xa000
|
||||
S_IFSOCK = 0xc000
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
EINVAL = syscall.NewError("bad arg in system call")
|
||||
ENOTDIR = syscall.NewError("not a directory")
|
||||
EISDIR = syscall.NewError("file is a directory")
|
||||
ENOENT = syscall.NewError("file does not exist")
|
||||
EEXIST = syscall.NewError("file already exists")
|
||||
EMFILE = syscall.NewError("no free file descriptors")
|
||||
EIO = syscall.NewError("i/o error")
|
||||
ENAMETOOLONG = syscall.NewError("file name too long")
|
||||
EINTR = syscall.NewError("interrupted")
|
||||
EPERM = syscall.NewError("permission denied")
|
||||
EBUSY = syscall.NewError("no free devices")
|
||||
ETIMEDOUT = syscall.NewError("connection timed out")
|
||||
EPLAN9 = syscall.NewError("not supported by plan 9")
|
||||
|
||||
// The following errors do not correspond to any
|
||||
// Plan 9 system messages. Invented to support
|
||||
// what package os and others expect.
|
||||
EACCES = syscall.NewError("access permission denied")
|
||||
EAFNOSUPPORT = syscall.NewError("address family not supported by protocol")
|
||||
)
|
138
vendor/golang.org/x/sys/plan9/mkall.sh
generated
vendored
138
vendor/golang.org/x/sys/plan9/mkall.sh
generated
vendored
@ -1,138 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2009 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.
|
||||
|
||||
# The plan9 package provides access to the raw system call
|
||||
# interface of the underlying operating system. Porting Go to
|
||||
# a new architecture/operating system combination requires
|
||||
# some manual effort, though there are tools that automate
|
||||
# much of the process. The auto-generated files have names
|
||||
# beginning with z.
|
||||
#
|
||||
# This script runs or (given -n) prints suggested commands to generate z files
|
||||
# for the current system. Running those commands is not automatic.
|
||||
# This script is documentation more than anything else.
|
||||
#
|
||||
# * asm_${GOOS}_${GOARCH}.s
|
||||
#
|
||||
# This hand-written assembly file implements system call dispatch.
|
||||
# There are three entry points:
|
||||
#
|
||||
# func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
|
||||
# func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
|
||||
# func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
|
||||
#
|
||||
# The first and second are the standard ones; they differ only in
|
||||
# how many arguments can be passed to the kernel.
|
||||
# The third is for low-level use by the ForkExec wrapper;
|
||||
# unlike the first two, it does not call into the scheduler to
|
||||
# let it know that a system call is running.
|
||||
#
|
||||
# * syscall_${GOOS}.go
|
||||
#
|
||||
# This hand-written Go file implements system calls that need
|
||||
# special handling and lists "//sys" comments giving prototypes
|
||||
# for ones that can be auto-generated. Mksyscall reads those
|
||||
# comments to generate the stubs.
|
||||
#
|
||||
# * syscall_${GOOS}_${GOARCH}.go
|
||||
#
|
||||
# Same as syscall_${GOOS}.go except that it contains code specific
|
||||
# to ${GOOS} on one particular architecture.
|
||||
#
|
||||
# * types_${GOOS}.c
|
||||
#
|
||||
# This hand-written C file includes standard C headers and then
|
||||
# creates typedef or enum names beginning with a dollar sign
|
||||
# (use of $ in variable names is a gcc extension). The hardest
|
||||
# part about preparing this file is figuring out which headers to
|
||||
# include and which symbols need to be #defined to get the
|
||||
# actual data structures that pass through to the kernel system calls.
|
||||
# Some C libraries present alternate versions for binary compatibility
|
||||
# and translate them on the way in and out of system calls, but
|
||||
# there is almost always a #define that can get the real ones.
|
||||
# See types_darwin.c and types_linux.c for examples.
|
||||
#
|
||||
# * zerror_${GOOS}_${GOARCH}.go
|
||||
#
|
||||
# This machine-generated file defines the system's error numbers,
|
||||
# error strings, and signal numbers. The generator is "mkerrors.sh".
|
||||
# Usually no arguments are needed, but mkerrors.sh will pass its
|
||||
# arguments on to godefs.
|
||||
#
|
||||
# * zsyscall_${GOOS}_${GOARCH}.go
|
||||
#
|
||||
# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
|
||||
#
|
||||
# * zsysnum_${GOOS}_${GOARCH}.go
|
||||
#
|
||||
# Generated by mksysnum_${GOOS}.
|
||||
#
|
||||
# * ztypes_${GOOS}_${GOARCH}.go
|
||||
#
|
||||
# Generated by godefs; see types_${GOOS}.c above.
|
||||
|
||||
GOOSARCH="${GOOS}_${GOARCH}"
|
||||
|
||||
# defaults
|
||||
mksyscall="./mksyscall.pl"
|
||||
mkerrors="./mkerrors.sh"
|
||||
zerrors="zerrors_$GOOSARCH.go"
|
||||
mksysctl=""
|
||||
zsysctl="zsysctl_$GOOSARCH.go"
|
||||
mksysnum=
|
||||
mktypes=
|
||||
run="sh"
|
||||
|
||||
case "$1" in
|
||||
-syscalls)
|
||||
for i in zsyscall*go
|
||||
do
|
||||
sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
|
||||
rm _$i
|
||||
done
|
||||
exit 0
|
||||
;;
|
||||
-n)
|
||||
run="cat"
|
||||
shift
|
||||
esac
|
||||
|
||||
case "$#" in
|
||||
0)
|
||||
;;
|
||||
*)
|
||||
echo 'usage: mkall.sh [-n]' 1>&2
|
||||
exit 2
|
||||
esac
|
||||
|
||||
case "$GOOSARCH" in
|
||||
_* | *_ | _)
|
||||
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
plan9_386)
|
||||
mkerrors=
|
||||
mksyscall="./mksyscall.pl -l32 -plan9"
|
||||
mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
|
||||
mktypes="XXX"
|
||||
;;
|
||||
*)
|
||||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
(
|
||||
if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
|
||||
case "$GOOS" in
|
||||
plan9)
|
||||
syscall_goos="syscall_$GOOS.go"
|
||||
if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"; fi
|
||||
;;
|
||||
esac
|
||||
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
|
||||
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
|
||||
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go"; fi
|
||||
) | $run
|
246
vendor/golang.org/x/sys/plan9/mkerrors.sh
generated
vendored
246
vendor/golang.org/x/sys/plan9/mkerrors.sh
generated
vendored
@ -1,246 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2009 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.
|
||||
|
||||
# Generate Go code listing errors and other #defined constant
|
||||
# values (ENAMETOOLONG etc.), by asking the preprocessor
|
||||
# about the definitions.
|
||||
|
||||
unset LANG
|
||||
export LC_ALL=C
|
||||
export LC_CTYPE=C
|
||||
|
||||
CC=${CC:-gcc}
|
||||
|
||||
uname=$(uname)
|
||||
|
||||
includes='
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <errno.h>
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <sys/resource.h>
|
||||
'
|
||||
|
||||
ccflags="$@"
|
||||
|
||||
# Write go tool cgo -godefs input.
|
||||
(
|
||||
echo package plan9
|
||||
echo
|
||||
echo '/*'
|
||||
indirect="includes_$(uname)"
|
||||
echo "${!indirect} $includes"
|
||||
echo '*/'
|
||||
echo 'import "C"'
|
||||
echo
|
||||
echo 'const ('
|
||||
|
||||
# The gcc command line prints all the #defines
|
||||
# it encounters while processing the input
|
||||
echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
|
||||
awk '
|
||||
$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
|
||||
|
||||
$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
|
||||
$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
|
||||
$2 ~ /^(SCM_SRCRT)$/ {next}
|
||||
$2 ~ /^(MAP_FAILED)$/ {next}
|
||||
|
||||
$2 !~ /^ETH_/ &&
|
||||
$2 !~ /^EPROC_/ &&
|
||||
$2 !~ /^EQUIV_/ &&
|
||||
$2 !~ /^EXPR_/ &&
|
||||
$2 ~ /^E[A-Z0-9_]+$/ ||
|
||||
$2 ~ /^B[0-9_]+$/ ||
|
||||
$2 ~ /^V[A-Z0-9]+$/ ||
|
||||
$2 ~ /^CS[A-Z0-9]/ ||
|
||||
$2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
|
||||
$2 ~ /^IGN/ ||
|
||||
$2 ~ /^IX(ON|ANY|OFF)$/ ||
|
||||
$2 ~ /^IN(LCR|PCK)$/ ||
|
||||
$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
|
||||
$2 ~ /^C(LOCAL|READ)$/ ||
|
||||
$2 == "BRKINT" ||
|
||||
$2 == "HUPCL" ||
|
||||
$2 == "PENDIN" ||
|
||||
$2 == "TOSTOP" ||
|
||||
$2 ~ /^PAR/ ||
|
||||
$2 ~ /^SIG[^_]/ ||
|
||||
$2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ ||
|
||||
$2 ~ /^IN_/ ||
|
||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
||||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
|
||||
$2 == "ICMPV6_FILTER" ||
|
||||
$2 == "SOMAXCONN" ||
|
||||
$2 == "NAME_MAX" ||
|
||||
$2 == "IFNAMSIZ" ||
|
||||
$2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ ||
|
||||
$2 ~ /^SYSCTL_VERS/ ||
|
||||
$2 ~ /^(MS|MNT)_/ ||
|
||||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
||||
$2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||
|
||||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
|
||||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
|
||||
$2 !~ "NLA_TYPE_MASK" &&
|
||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
|
||||
$2 ~ /^SIOC/ ||
|
||||
$2 ~ /^TIOC/ ||
|
||||
$2 !~ "RTF_BITS" &&
|
||||
$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
|
||||
$2 ~ /^BIOC/ ||
|
||||
$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
|
||||
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
|
||||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
|
||||
$2 ~ /^CLONE_[A-Z_]+/ ||
|
||||
$2 !~ /^(BPF_TIMEVAL)$/ &&
|
||||
$2 ~ /^(BPF|DLT)_/ ||
|
||||
$2 !~ "WMESGLEN" &&
|
||||
$2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)}
|
||||
$2 ~ /^__WCOREFLAG$/ {next}
|
||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
|
||||
|
||||
{next}
|
||||
' | sort
|
||||
|
||||
echo ')'
|
||||
) >_const.go
|
||||
|
||||
# Pull out the error names for later.
|
||||
errors=$(
|
||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
|
||||
sort
|
||||
)
|
||||
|
||||
# Pull out the signal names for later.
|
||||
signals=$(
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
|
||||
sort
|
||||
)
|
||||
|
||||
# Again, writing regexps to a file.
|
||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||
sort >_error.grep
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
|
||||
sort >_signal.grep
|
||||
|
||||
echo '// mkerrors.sh' "$@"
|
||||
echo '// Code generated by the command above; DO NOT EDIT.'
|
||||
echo
|
||||
go tool cgo -godefs -- "$@" _const.go >_error.out
|
||||
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
|
||||
echo
|
||||
echo '// Errors'
|
||||
echo 'const ('
|
||||
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= Errno(\1)/'
|
||||
echo ')'
|
||||
|
||||
echo
|
||||
echo '// Signals'
|
||||
echo 'const ('
|
||||
cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= Signal(\1)/'
|
||||
echo ')'
|
||||
|
||||
# Run C program to print error and syscall strings.
|
||||
(
|
||||
echo -E "
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
|
||||
|
||||
int errors[] = {
|
||||
"
|
||||
for i in $errors
|
||||
do
|
||||
echo -E ' '$i,
|
||||
done
|
||||
|
||||
echo -E "
|
||||
};
|
||||
|
||||
int signals[] = {
|
||||
"
|
||||
for i in $signals
|
||||
do
|
||||
echo -E ' '$i,
|
||||
done
|
||||
|
||||
# Use -E because on some systems bash builtin interprets \n itself.
|
||||
echo -E '
|
||||
};
|
||||
|
||||
static int
|
||||
intcmp(const void *a, const void *b)
|
||||
{
|
||||
return *(int*)a - *(int*)b;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int i, j, e;
|
||||
char buf[1024], *p;
|
||||
|
||||
printf("\n\n// Error table\n");
|
||||
printf("var errors = [...]string {\n");
|
||||
qsort(errors, nelem(errors), sizeof errors[0], intcmp);
|
||||
for(i=0; i<nelem(errors); i++) {
|
||||
e = errors[i];
|
||||
if(i > 0 && errors[i-1] == e)
|
||||
continue;
|
||||
strcpy(buf, strerror(e));
|
||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
||||
buf[0] += a - A;
|
||||
printf("\t%d: \"%s\",\n", e, buf);
|
||||
}
|
||||
printf("}\n\n");
|
||||
|
||||
printf("\n\n// Signal table\n");
|
||||
printf("var signals = [...]string {\n");
|
||||
qsort(signals, nelem(signals), sizeof signals[0], intcmp);
|
||||
for(i=0; i<nelem(signals); i++) {
|
||||
e = signals[i];
|
||||
if(i > 0 && signals[i-1] == e)
|
||||
continue;
|
||||
strcpy(buf, strsignal(e));
|
||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
||||
buf[0] += a - A;
|
||||
// cut trailing : number.
|
||||
p = strrchr(buf, ":"[0]);
|
||||
if(p)
|
||||
*p = '\0';
|
||||
printf("\t%d: \"%s\",\n", e, buf);
|
||||
}
|
||||
printf("}\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
'
|
||||
) >_errors.c
|
||||
|
||||
$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
|
393
vendor/golang.org/x/sys/plan9/mksyscall.go
generated
vendored
393
vendor/golang.org/x/sys/plan9/mksyscall.go
generated
vendored
@ -1,393 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build ignore
|
||||
|
||||
/*
|
||||
This program reads a file containing function prototypes
|
||||
(like syscall_plan9.go) and generates system call bodies.
|
||||
The prototypes are marked by lines beginning with "//sys"
|
||||
and read like func declarations if //sys is replaced by func, but:
|
||||
* The parameter lists must give a name for each argument.
|
||||
This includes return parameters.
|
||||
* The parameter lists must give a type for each argument:
|
||||
the (x, y, z int) shorthand is not allowed.
|
||||
* If the return parameter is an error number, it must be named errno.
|
||||
|
||||
A line beginning with //sysnb is like //sys, except that the
|
||||
goroutine will not be suspended during the execution of the system
|
||||
call. This must only be used for system calls which can never
|
||||
block, as otherwise the system call could cause all goroutines to
|
||||
hang.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
||||
plan9 = flag.Bool("plan9", false, "plan9")
|
||||
openbsd = flag.Bool("openbsd", false, "openbsd")
|
||||
netbsd = flag.Bool("netbsd", false, "netbsd")
|
||||
dragonfly = flag.Bool("dragonfly", false, "dragonfly")
|
||||
arm = flag.Bool("arm", false, "arm") // 64-bit value should use (even, odd)-pair
|
||||
tags = flag.String("tags", "", "build tags")
|
||||
filename = flag.String("output", "", "output file name (standard output if omitted)")
|
||||
)
|
||||
|
||||
// cmdLine returns this programs's commandline arguments
|
||||
func cmdLine() string {
|
||||
return "go run mksyscall.go " + strings.Join(os.Args[1:], " ")
|
||||
}
|
||||
|
||||
// buildTags returns build tags
|
||||
func buildTags() string {
|
||||
return *tags
|
||||
}
|
||||
|
||||
// Param is function parameter
|
||||
type Param struct {
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
// usage prints the program usage
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// parseParamList parses parameter list and returns a slice of parameters
|
||||
func parseParamList(list string) []string {
|
||||
list = strings.TrimSpace(list)
|
||||
if list == "" {
|
||||
return []string{}
|
||||
}
|
||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
||||
}
|
||||
|
||||
// parseParam splits a parameter into name and type
|
||||
func parseParam(p string) Param {
|
||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
||||
if ps == nil {
|
||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
||||
os.Exit(1)
|
||||
}
|
||||
return Param{ps[1], ps[2]}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Get the OS and architecture (using GOARCH_TARGET if it exists)
|
||||
goos := os.Getenv("GOOS")
|
||||
goarch := os.Getenv("GOARCH_TARGET")
|
||||
if goarch == "" {
|
||||
goarch = os.Getenv("GOARCH")
|
||||
}
|
||||
|
||||
// Check that we are using the Docker-based build system if we should
|
||||
if goos == "linux" {
|
||||
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
|
||||
fmt.Fprintf(os.Stderr, "In the Docker-based build system, mksyscall should not be called directly.\n")
|
||||
fmt.Fprintf(os.Stderr, "See README.md\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
if len(flag.Args()) <= 0 {
|
||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
||||
usage()
|
||||
}
|
||||
|
||||
endianness := ""
|
||||
if *b32 {
|
||||
endianness = "big-endian"
|
||||
} else if *l32 {
|
||||
endianness = "little-endian"
|
||||
}
|
||||
|
||||
libc := false
|
||||
if goos == "darwin" && strings.Contains(buildTags(), ",go1.12") {
|
||||
libc = true
|
||||
}
|
||||
trampolines := map[string]bool{}
|
||||
|
||||
text := ""
|
||||
for _, path := range flag.Args() {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
s := bufio.NewScanner(file)
|
||||
for s.Scan() {
|
||||
t := s.Text()
|
||||
t = strings.TrimSpace(t)
|
||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Line must be of the form
|
||||
// func Open(path string, mode int, perm int) (fd int, errno error)
|
||||
// Split into name, in params, out params.
|
||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$`).FindStringSubmatch(t)
|
||||
if f == nil {
|
||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
||||
os.Exit(1)
|
||||
}
|
||||
funct, inps, outps, sysname := f[2], f[3], f[4], f[5]
|
||||
|
||||
// Split argument lists on comma.
|
||||
in := parseParamList(inps)
|
||||
out := parseParamList(outps)
|
||||
|
||||
// Try in vain to keep people from editing this file.
|
||||
// The theory is that they jump into the middle of the file
|
||||
// without reading the header.
|
||||
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
||||
|
||||
// Go function header.
|
||||
outDecl := ""
|
||||
if len(out) > 0 {
|
||||
outDecl = fmt.Sprintf(" (%s)", strings.Join(out, ", "))
|
||||
}
|
||||
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outDecl)
|
||||
|
||||
// Check if err return available
|
||||
errvar := ""
|
||||
for _, param := range out {
|
||||
p := parseParam(param)
|
||||
if p.Type == "error" {
|
||||
errvar = p.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare arguments to Syscall.
|
||||
var args []string
|
||||
n := 0
|
||||
for _, param := range in {
|
||||
p := parseParam(param)
|
||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
||||
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
|
||||
} else if p.Type == "string" && errvar != "" {
|
||||
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
|
||||
text += fmt.Sprintf("\t_p%d, %s = BytePtrFromString(%s)\n", n, errvar, p.Name)
|
||||
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
||||
n++
|
||||
} else if p.Type == "string" {
|
||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
||||
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
|
||||
text += fmt.Sprintf("\t_p%d, _ = BytePtrFromString(%s)\n", n, p.Name)
|
||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
||||
n++
|
||||
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
|
||||
// Convert slice into pointer, length.
|
||||
// Have to be careful not to take address of &a[0] if len == 0:
|
||||
// pass dummy pointer in that case.
|
||||
// Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
|
||||
text += fmt.Sprintf("\tvar _p%d unsafe.Pointer\n", n)
|
||||
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = unsafe.Pointer(&%s[0])\n\t}", p.Name, n, p.Name)
|
||||
text += fmt.Sprintf(" else {\n\t\t_p%d = unsafe.Pointer(&_zero)\n\t}\n", n)
|
||||
args = append(args, fmt.Sprintf("uintptr(_p%d)", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
|
||||
n++
|
||||
} else if p.Type == "int64" && (*openbsd || *netbsd) {
|
||||
args = append(args, "0")
|
||||
if endianness == "big-endian" {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
||||
} else if endianness == "little-endian" {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
||||
} else {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
||||
}
|
||||
} else if p.Type == "int64" && *dragonfly {
|
||||
if regexp.MustCompile(`^(?i)extp(read|write)`).FindStringSubmatch(funct) == nil {
|
||||
args = append(args, "0")
|
||||
}
|
||||
if endianness == "big-endian" {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
||||
} else if endianness == "little-endian" {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
||||
} else {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
||||
}
|
||||
} else if p.Type == "int64" && endianness != "" {
|
||||
if len(args)%2 == 1 && *arm {
|
||||
// arm abi specifies 64-bit argument uses
|
||||
// (even, odd) pair
|
||||
args = append(args, "0")
|
||||
}
|
||||
if endianness == "big-endian" {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
||||
} else {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
||||
}
|
||||
} else {
|
||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
||||
}
|
||||
}
|
||||
|
||||
// Determine which form to use; pad args with zeros.
|
||||
asm := "Syscall"
|
||||
if nonblock != nil {
|
||||
if errvar == "" && goos == "linux" {
|
||||
asm = "RawSyscallNoError"
|
||||
} else {
|
||||
asm = "RawSyscall"
|
||||
}
|
||||
} else {
|
||||
if errvar == "" && goos == "linux" {
|
||||
asm = "SyscallNoError"
|
||||
}
|
||||
}
|
||||
if len(args) <= 3 {
|
||||
for len(args) < 3 {
|
||||
args = append(args, "0")
|
||||
}
|
||||
} else if len(args) <= 6 {
|
||||
asm += "6"
|
||||
for len(args) < 6 {
|
||||
args = append(args, "0")
|
||||
}
|
||||
} else if len(args) <= 9 {
|
||||
asm += "9"
|
||||
for len(args) < 9 {
|
||||
args = append(args, "0")
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "%s:%s too many arguments to system call\n", path, funct)
|
||||
}
|
||||
|
||||
// System call number.
|
||||
if sysname == "" {
|
||||
sysname = "SYS_" + funct
|
||||
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
|
||||
sysname = strings.ToUpper(sysname)
|
||||
}
|
||||
|
||||
var libcFn string
|
||||
if libc {
|
||||
asm = "syscall_" + strings.ToLower(asm[:1]) + asm[1:] // internal syscall call
|
||||
sysname = strings.TrimPrefix(sysname, "SYS_") // remove SYS_
|
||||
sysname = strings.ToLower(sysname) // lowercase
|
||||
if sysname == "getdirentries64" {
|
||||
// Special case - libSystem name and
|
||||
// raw syscall name don't match.
|
||||
sysname = "__getdirentries64"
|
||||
}
|
||||
libcFn = sysname
|
||||
sysname = "funcPC(libc_" + sysname + "_trampoline)"
|
||||
}
|
||||
|
||||
// Actual call.
|
||||
arglist := strings.Join(args, ", ")
|
||||
call := fmt.Sprintf("%s(%s, %s)", asm, sysname, arglist)
|
||||
|
||||
// Assign return values.
|
||||
body := ""
|
||||
ret := []string{"_", "_", "_"}
|
||||
doErrno := false
|
||||
for i := 0; i < len(out); i++ {
|
||||
p := parseParam(out[i])
|
||||
reg := ""
|
||||
if p.Name == "err" && !*plan9 {
|
||||
reg = "e1"
|
||||
ret[2] = reg
|
||||
doErrno = true
|
||||
} else if p.Name == "err" && *plan9 {
|
||||
ret[0] = "r0"
|
||||
ret[2] = "e1"
|
||||
break
|
||||
} else {
|
||||
reg = fmt.Sprintf("r%d", i)
|
||||
ret[i] = reg
|
||||
}
|
||||
if p.Type == "bool" {
|
||||
reg = fmt.Sprintf("%s != 0", reg)
|
||||
}
|
||||
if p.Type == "int64" && endianness != "" {
|
||||
// 64-bit number in r1:r0 or r0:r1.
|
||||
if i+2 > len(out) {
|
||||
fmt.Fprintf(os.Stderr, "%s:%s not enough registers for int64 return\n", path, funct)
|
||||
}
|
||||
if endianness == "big-endian" {
|
||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
|
||||
} else {
|
||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
|
||||
}
|
||||
ret[i] = fmt.Sprintf("r%d", i)
|
||||
ret[i+1] = fmt.Sprintf("r%d", i+1)
|
||||
}
|
||||
if reg != "e1" || *plan9 {
|
||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
||||
}
|
||||
}
|
||||
if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
|
||||
text += fmt.Sprintf("\t%s\n", call)
|
||||
} else {
|
||||
if errvar == "" && goos == "linux" {
|
||||
// raw syscall without error on Linux, see golang.org/issue/22924
|
||||
text += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], call)
|
||||
} else {
|
||||
text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
|
||||
}
|
||||
}
|
||||
text += body
|
||||
|
||||
if *plan9 && ret[2] == "e1" {
|
||||
text += "\tif int32(r0) == -1 {\n"
|
||||
text += "\t\terr = e1\n"
|
||||
text += "\t}\n"
|
||||
} else if doErrno {
|
||||
text += "\tif e1 != 0 {\n"
|
||||
text += "\t\terr = errnoErr(e1)\n"
|
||||
text += "\t}\n"
|
||||
}
|
||||
text += "\treturn\n"
|
||||
text += "}\n\n"
|
||||
|
||||
if libc && !trampolines[libcFn] {
|
||||
// some system calls share a trampoline, like read and readlen.
|
||||
trampolines[libcFn] = true
|
||||
// Declare assembly trampoline.
|
||||
text += fmt.Sprintf("func libc_%s_trampoline()\n", libcFn)
|
||||
// Assembly trampoline calls the libc_* function, which this magic
|
||||
// redirects to use the function from libSystem.
|
||||
text += fmt.Sprintf("//go:linkname libc_%s libc_%s\n", libcFn, libcFn)
|
||||
text += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"/usr/lib/libSystem.B.dylib\"\n", libcFn, libcFn)
|
||||
text += "\n"
|
||||
}
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
file.Close()
|
||||
}
|
||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
|
||||
}
|
||||
|
||||
const srcTemplate = `// %s
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build %s
|
||||
|
||||
package plan9
|
||||
|
||||
import "unsafe"
|
||||
|
||||
%s
|
||||
`
|
23
vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh
generated
vendored
23
vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh
generated
vendored
@ -1,23 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright 2009 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.
|
||||
|
||||
COMMAND="mksysnum_plan9.sh $@"
|
||||
|
||||
cat <<EOF
|
||||
// $COMMAND
|
||||
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||
|
||||
package plan9
|
||||
|
||||
const(
|
||||
EOF
|
||||
|
||||
SP='[ ]' # space or tab
|
||||
sed "s/^#define${SP}\\([A-Z0-9_][A-Z0-9_]*\\)${SP}${SP}*\\([0-9][0-9]*\\)/SYS_\\1=\\2/g" \
|
||||
< $1 | grep -v SYS__
|
||||
|
||||
cat <<EOF
|
||||
)
|
||||
EOF
|
21
vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go
generated
vendored
21
vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go
generated
vendored
@ -1,21 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build go1.5
|
||||
|
||||
package plan9
|
||||
|
||||
import "syscall"
|
||||
|
||||
func fixwd() {
|
||||
syscall.Fixwd()
|
||||
}
|
||||
|
||||
func Getwd() (wd string, err error) {
|
||||
return syscall.Getwd()
|
||||
}
|
||||
|
||||
func Chdir(path string) error {
|
||||
return syscall.Chdir(path)
|
||||
}
|
23
vendor/golang.org/x/sys/plan9/pwd_plan9.go
generated
vendored
23
vendor/golang.org/x/sys/plan9/pwd_plan9.go
generated
vendored
@ -1,23 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build !go1.5
|
||||
|
||||
package plan9
|
||||
|
||||
func fixwd() {
|
||||
}
|
||||
|
||||
func Getwd() (wd string, err error) {
|
||||
fd, err := open(".", O_RDONLY)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer Close(fd)
|
||||
return Fd2path(fd)
|
||||
}
|
||||
|
||||
func Chdir(path string) error {
|
||||
return chdir(path)
|
||||
}
|
30
vendor/golang.org/x/sys/plan9/race.go
generated
vendored
30
vendor/golang.org/x/sys/plan9/race.go
generated
vendored
@ -1,30 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build plan9,race
|
||||
|
||||
package plan9
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const raceenabled = true
|
||||
|
||||
func raceAcquire(addr unsafe.Pointer) {
|
||||
runtime.RaceAcquire(addr)
|
||||
}
|
||||
|
||||
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||
runtime.RaceReleaseMerge(addr)
|
||||
}
|
||||
|
||||
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||
runtime.RaceReadRange(addr, len)
|
||||
}
|
||||
|
||||
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||
runtime.RaceWriteRange(addr, len)
|
||||
}
|
25
vendor/golang.org/x/sys/plan9/race0.go
generated
vendored
25
vendor/golang.org/x/sys/plan9/race0.go
generated
vendored
@ -1,25 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build plan9,!race
|
||||
|
||||
package plan9
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const raceenabled = false
|
||||
|
||||
func raceAcquire(addr unsafe.Pointer) {
|
||||
}
|
||||
|
||||
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||
}
|
||||
|
||||
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||
}
|
||||
|
||||
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||
}
|
22
vendor/golang.org/x/sys/plan9/str.go
generated
vendored
22
vendor/golang.org/x/sys/plan9/str.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
// Copyright 2009 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.
|
||||
|
||||
// +build plan9
|
||||
|
||||
package plan9
|
||||
|
||||
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
||||
if val < 0 {
|
||||
return "-" + itoa(-val)
|
||||
}
|
||||
var buf [32]byte // big enough for int64
|
||||
i := len(buf) - 1
|
||||
for val >= 10 {
|
||||
buf[i] = byte(val%10 + '0')
|
||||
i--
|
||||
val /= 10
|
||||
}
|
||||
buf[i] = byte(val + '0')
|
||||
return string(buf[i:])
|
||||
}
|
77
vendor/golang.org/x/sys/plan9/syscall.go
generated
vendored
77
vendor/golang.org/x/sys/plan9/syscall.go
generated
vendored
@ -1,77 +0,0 @@
|
||||
// Copyright 2009 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.
|
||||
|
||||
// +build plan9
|
||||
|
||||
// Package plan9 contains an interface to the low-level operating system
|
||||
// primitives. OS details vary depending on the underlying system, and
|
||||
// by default, godoc will display the OS-specific documentation for the current
|
||||
// system. If you want godoc to display documentation for another
|
||||
// system, set $GOOS and $GOARCH to the desired system. For example, if
|
||||
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
|
||||
// to freebsd and $GOARCH to arm.
|
||||
//
|
||||
// The primary use of this package is inside other packages that provide a more
|
||||
// portable interface to the system, such as "os", "time" and "net". Use
|
||||
// those packages rather than this one if you can.
|
||||
//
|
||||
// For details of the functions and data types in this package consult
|
||||
// the manuals for the appropriate operating system.
|
||||
//
|
||||
// These calls return err == nil to indicate success; otherwise
|
||||
// err represents an operating system error describing the failure and
|
||||
// holds a value of type syscall.ErrorString.
|
||||
package plan9 // import "golang.org/x/sys/plan9"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
||||
// containing the text of s. If s contains a NUL byte at any
|
||||
// location, it returns (nil, EINVAL).
|
||||
func ByteSliceFromString(s string) ([]byte, error) {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == 0 {
|
||||
return nil, EINVAL
|
||||
}
|
||||
}
|
||||
a := make([]byte, len(s)+1)
|
||||
copy(a, s)
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// BytePtrFromString returns a pointer to a NUL-terminated array of
|
||||
// bytes containing the text of s. If s contains a NUL byte at any
|
||||
// location, it returns (nil, EINVAL).
|
||||
func BytePtrFromString(s string) (*byte, error) {
|
||||
a, err := ByteSliceFromString(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &a[0], nil
|
||||
}
|
||||
|
||||
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||
// See mksyscall.pl.
|
||||
var _zero uintptr
|
||||
|
||||
func (ts *Timespec) Unix() (sec int64, nsec int64) {
|
||||
return int64(ts.Sec), int64(ts.Nsec)
|
||||
}
|
||||
|
||||
func (tv *Timeval) Unix() (sec int64, nsec int64) {
|
||||
return int64(tv.Sec), int64(tv.Usec) * 1000
|
||||
}
|
||||
|
||||
func (ts *Timespec) Nano() int64 {
|
||||
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
|
||||
}
|
||||
|
||||
func (tv *Timeval) Nano() int64 {
|
||||
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
|
||||
}
|
||||
|
||||
// use is a no-op, but the compiler cannot see that it is.
|
||||
// Calling use(p) ensures that p is kept live until that point.
|
||||
//go:noescape
|
||||
func use(p unsafe.Pointer)
|
349
vendor/golang.org/x/sys/plan9/syscall_plan9.go
generated
vendored
349
vendor/golang.org/x/sys/plan9/syscall_plan9.go
generated
vendored
@ -1,349 +0,0 @@
|
||||
// Copyright 2011 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.
|
||||
|
||||
// Plan 9 system calls.
|
||||
// This file is compiled as ordinary Go code,
|
||||
// but it is also input to mksyscall,
|
||||
// which parses the //sys lines and generates system call stubs.
|
||||
// Note that sometimes we use a lowercase //sys name and
|
||||
// wrap it in our own nicer implementation.
|
||||
|
||||
package plan9
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// A Note is a string describing a process note.
|
||||
// It implements the os.Signal interface.
|
||||
type Note string
|
||||
|
||||
func (n Note) Signal() {}
|
||||
|
||||
func (n Note) String() string {
|
||||
return string(n)
|
||||
}
|
||||
|
||||
var (
|
||||
Stdin = 0
|
||||
Stdout = 1
|
||||
Stderr = 2
|
||||
)
|
||||
|
||||
// For testing: clients can set this flag to force
|
||||
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
||||
var SocketDisableIPv6 bool
|
||||
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
|
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
|
||||
func atoi(b []byte) (n uint) {
|
||||
n = 0
|
||||
for i := 0; i < len(b); i++ {
|
||||
n = n*10 + uint(b[i]-'0')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func cstring(s []byte) string {
|
||||
i := bytes.IndexByte(s, 0)
|
||||
if i == -1 {
|
||||
i = len(s)
|
||||
}
|
||||
return string(s[:i])
|
||||
}
|
||||
|
||||
func errstr() string {
|
||||
var buf [ERRMAX]byte
|
||||
|
||||
RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
|
||||
|
||||
buf[len(buf)-1] = 0
|
||||
return cstring(buf[:])
|
||||
}
|
||||
|
||||
// Implemented in assembly to import from runtime.
|
||||
func exit(code int)
|
||||
|
||||
func Exit(code int) { exit(code) }
|
||||
|
||||
func readnum(path string) (uint, error) {
|
||||
var b [12]byte
|
||||
|
||||
fd, e := Open(path, O_RDONLY)
|
||||
if e != nil {
|
||||
return 0, e
|
||||
}
|
||||
defer Close(fd)
|
||||
|
||||
n, e := Pread(fd, b[:], 0)
|
||||
|
||||
if e != nil {
|
||||
return 0, e
|
||||
}
|
||||
|
||||
m := 0
|
||||
for ; m < n && b[m] == ' '; m++ {
|
||||
}
|
||||
|
||||
return atoi(b[m : n-1]), nil
|
||||
}
|
||||
|
||||
func Getpid() (pid int) {
|
||||
n, _ := readnum("#c/pid")
|
||||
return int(n)
|
||||
}
|
||||
|
||||
func Getppid() (ppid int) {
|
||||
n, _ := readnum("#c/ppid")
|
||||
return int(n)
|
||||
}
|
||||
|
||||
func Read(fd int, p []byte) (n int, err error) {
|
||||
return Pread(fd, p, -1)
|
||||
}
|
||||
|
||||
func Write(fd int, p []byte) (n int, err error) {
|
||||
return Pwrite(fd, p, -1)
|
||||
}
|
||||
|
||||
var ioSync int64
|
||||
|
||||
//sys fd2path(fd int, buf []byte) (err error)
|
||||
func Fd2path(fd int) (path string, err error) {
|
||||
var buf [512]byte
|
||||
|
||||
e := fd2path(fd, buf[:])
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return cstring(buf[:]), nil
|
||||
}
|
||||
|
||||
//sys pipe(p *[2]int32) (err error)
|
||||
func Pipe(p []int) (err error) {
|
||||
if len(p) != 2 {
|
||||
return syscall.ErrorString("bad arg in system call")
|
||||
}
|
||||
var pp [2]int32
|
||||
err = pipe(&pp)
|
||||
p[0] = int(pp[0])
|
||||
p[1] = int(pp[1])
|
||||
return
|
||||
}
|
||||
|
||||
// Underlying system call writes to newoffset via pointer.
|
||||
// Implemented in assembly to avoid allocation.
|
||||
func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
|
||||
|
||||
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||
newoffset, e := seek(0, fd, offset, whence)
|
||||
|
||||
if newoffset == -1 {
|
||||
err = syscall.ErrorString(e)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Mkdir(path string, mode uint32) (err error) {
|
||||
fd, err := Create(path, O_RDONLY, DMDIR|mode)
|
||||
|
||||
if fd != -1 {
|
||||
Close(fd)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Waitmsg struct {
|
||||
Pid int
|
||||
Time [3]uint32
|
||||
Msg string
|
||||
}
|
||||
|
||||
func (w Waitmsg) Exited() bool { return true }
|
||||
func (w Waitmsg) Signaled() bool { return false }
|
||||
|
||||
func (w Waitmsg) ExitStatus() int {
|
||||
if len(w.Msg) == 0 {
|
||||
// a normal exit returns no message
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
//sys await(s []byte) (n int, err error)
|
||||
func Await(w *Waitmsg) (err error) {
|
||||
var buf [512]byte
|
||||
var f [5][]byte
|
||||
|
||||
n, err := await(buf[:])
|
||||
|
||||
if err != nil || w == nil {
|
||||
return
|
||||
}
|
||||
|
||||
nf := 0
|
||||
p := 0
|
||||
for i := 0; i < n && nf < len(f)-1; i++ {
|
||||
if buf[i] == ' ' {
|
||||
f[nf] = buf[p:i]
|
||||
p = i + 1
|
||||
nf++
|
||||
}
|
||||
}
|
||||
f[nf] = buf[p:]
|
||||
nf++
|
||||
|
||||
if nf != len(f) {
|
||||
return syscall.ErrorString("invalid wait message")
|
||||
}
|
||||
w.Pid = int(atoi(f[0]))
|
||||
w.Time[0] = uint32(atoi(f[1]))
|
||||
w.Time[1] = uint32(atoi(f[2]))
|
||||
w.Time[2] = uint32(atoi(f[3]))
|
||||
w.Msg = cstring(f[4])
|
||||
if w.Msg == "''" {
|
||||
// await() returns '' for no error
|
||||
w.Msg = ""
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Unmount(name, old string) (err error) {
|
||||
fixwd()
|
||||
oldp, err := BytePtrFromString(old)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldptr := uintptr(unsafe.Pointer(oldp))
|
||||
|
||||
var r0 uintptr
|
||||
var e syscall.ErrorString
|
||||
|
||||
// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
|
||||
if name == "" {
|
||||
r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
|
||||
} else {
|
||||
namep, err := BytePtrFromString(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
|
||||
}
|
||||
|
||||
if int32(r0) == -1 {
|
||||
err = e
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Fchdir(fd int) (err error) {
|
||||
path, err := Fd2path(fd)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return Chdir(path)
|
||||
}
|
||||
|
||||
type Timespec struct {
|
||||
Sec int32
|
||||
Nsec int32
|
||||
}
|
||||
|
||||
type Timeval struct {
|
||||
Sec int32
|
||||
Usec int32
|
||||
}
|
||||
|
||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func nsec() int64 {
|
||||
var scratch int64
|
||||
|
||||
r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
|
||||
// TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
|
||||
if r0 == 0 {
|
||||
return scratch
|
||||
}
|
||||
return int64(r0)
|
||||
}
|
||||
|
||||
func Gettimeofday(tv *Timeval) error {
|
||||
nsec := nsec()
|
||||
*tv = NsecToTimeval(nsec)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Getpagesize() int { return 0x1000 }
|
||||
|
||||
func Getegid() (egid int) { return -1 }
|
||||
func Geteuid() (euid int) { return -1 }
|
||||
func Getgid() (gid int) { return -1 }
|
||||
func Getuid() (uid int) { return -1 }
|
||||
|
||||
func Getgroups() (gids []int, err error) {
|
||||
return make([]int, 0), nil
|
||||
}
|
||||
|
||||
//sys open(path string, mode int) (fd int, err error)
|
||||
func Open(path string, mode int) (fd int, err error) {
|
||||
fixwd()
|
||||
return open(path, mode)
|
||||
}
|
||||
|
||||
//sys create(path string, mode int, perm uint32) (fd int, err error)
|
||||
func Create(path string, mode int, perm uint32) (fd int, err error) {
|
||||
fixwd()
|
||||
return create(path, mode, perm)
|
||||
}
|
||||
|
||||
//sys remove(path string) (err error)
|
||||
func Remove(path string) error {
|
||||
fixwd()
|
||||
return remove(path)
|
||||
}
|
||||
|
||||
//sys stat(path string, edir []byte) (n int, err error)
|
||||
func Stat(path string, edir []byte) (n int, err error) {
|
||||
fixwd()
|
||||
return stat(path, edir)
|
||||
}
|
||||
|
||||
//sys bind(name string, old string, flag int) (err error)
|
||||
func Bind(name string, old string, flag int) (err error) {
|
||||
fixwd()
|
||||
return bind(name, old, flag)
|
||||
}
|
||||
|
||||
//sys mount(fd int, afd int, old string, flag int, aname string) (err error)
|
||||
func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
|
||||
fixwd()
|
||||
return mount(fd, afd, old, flag, aname)
|
||||
}
|
||||
|
||||
//sys wstat(path string, edir []byte) (err error)
|
||||
func Wstat(path string, edir []byte) (err error) {
|
||||
fixwd()
|
||||
return wstat(path, edir)
|
||||
}
|
||||
|
||||
//sys chdir(path string) (err error)
|
||||
//sys Dup(oldfd int, newfd int) (fd int, err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys Close(fd int) (err error)
|
||||
//sys Fstat(fd int, edir []byte) (n int, err error)
|
||||
//sys Fwstat(fd int, edir []byte) (err error)
|
33
vendor/golang.org/x/sys/plan9/syscall_test.go
generated
vendored
33
vendor/golang.org/x/sys/plan9/syscall_test.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// +build plan9
|
||||
|
||||
package plan9_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/plan9"
|
||||
)
|
||||
|
||||
func testSetGetenv(t *testing.T, key, value string) {
|
||||
err := plan9.Setenv(key, value)
|
||||
if err != nil {
|
||||
t.Fatalf("Setenv failed to set %q: %v", value, err)
|
||||
}
|
||||
newvalue, found := plan9.Getenv(key)
|
||||
if !found {
|
||||
t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value)
|
||||
}
|
||||
if newvalue != value {
|
||||
t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
testSetGetenv(t, "TESTENV", "AVALUE")
|
||||
// make sure TESTENV gets set to "", not deleted
|
||||
testSetGetenv(t, "TESTENV", "")
|
||||
}
|
284
vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
generated
vendored
284
vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
generated
vendored
@ -1,284 +0,0 @@
|
||||
// go run mksyscall.go -l32 -plan9 -tags plan9,386 syscall_plan9.go
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build plan9,386
|
||||
|
||||
package plan9
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func fd2path(fd int, buf []byte) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func pipe(p *[2]int32) (err error) {
|
||||
r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func await(s []byte) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(s) > 0 {
|
||||
_p0 = unsafe.Pointer(&s[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func open(path string, mode int) (fd int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func create(path string, mode int, perm uint32) (fd int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func remove(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func stat(path string, edir []byte) (n int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p1 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p1 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func bind(name string, old string, flag int) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *byte
|
||||
_p1, err = BytePtrFromString(old)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func mount(fd int, afd int, old string, flag int, aname string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(old)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *byte
|
||||
_p1, err = BytePtrFromString(aname)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func wstat(path string, edir []byte) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p1 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p1 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func chdir(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Dup(oldfd int, newfd int) (fd int, err error) {
|
||||
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Pread(fd int, p []byte, offset int64) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(p) > 0 {
|
||||
_p0 = unsafe.Pointer(&p[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(p) > 0 {
|
||||
_p0 = unsafe.Pointer(&p[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Close(fd int) (err error) {
|
||||
r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Fstat(fd int, edir []byte) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p0 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Fwstat(fd int, edir []byte) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p0 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
284
vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
generated
vendored
284
vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
generated
vendored
@ -1,284 +0,0 @@
|
||||
// go run mksyscall.go -l32 -plan9 -tags plan9,amd64 syscall_plan9.go
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build plan9,amd64
|
||||
|
||||
package plan9
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func fd2path(fd int, buf []byte) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func pipe(p *[2]int32) (err error) {
|
||||
r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func await(s []byte) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(s) > 0 {
|
||||
_p0 = unsafe.Pointer(&s[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func open(path string, mode int) (fd int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func create(path string, mode int, perm uint32) (fd int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func remove(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func stat(path string, edir []byte) (n int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p1 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p1 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func bind(name string, old string, flag int) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *byte
|
||||
_p1, err = BytePtrFromString(old)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func mount(fd int, afd int, old string, flag int, aname string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(old)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *byte
|
||||
_p1, err = BytePtrFromString(aname)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func wstat(path string, edir []byte) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p1 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p1 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func chdir(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Dup(oldfd int, newfd int) (fd int, err error) {
|
||||
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Pread(fd int, p []byte, offset int64) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(p) > 0 {
|
||||
_p0 = unsafe.Pointer(&p[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(p) > 0 {
|
||||
_p0 = unsafe.Pointer(&p[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Close(fd int) (err error) {
|
||||
r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Fstat(fd int, edir []byte) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p0 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Fwstat(fd int, edir []byte) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p0 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
284
vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
generated
vendored
284
vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
generated
vendored
@ -1,284 +0,0 @@
|
||||
// go run mksyscall.go -l32 -plan9 -tags plan9,arm syscall_plan9.go
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build plan9,arm
|
||||
|
||||
package plan9
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func fd2path(fd int, buf []byte) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func pipe(p *[2]int32) (err error) {
|
||||
r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func await(s []byte) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(s) > 0 {
|
||||
_p0 = unsafe.Pointer(&s[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func open(path string, mode int) (fd int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func create(path string, mode int, perm uint32) (fd int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func remove(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func stat(path string, edir []byte) (n int, err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p1 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p1 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func bind(name string, old string, flag int) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *byte
|
||||
_p1, err = BytePtrFromString(old)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func mount(fd int, afd int, old string, flag int, aname string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(old)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *byte
|
||||
_p1, err = BytePtrFromString(aname)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func wstat(path string, edir []byte) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p1 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p1 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func chdir(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Dup(oldfd int, newfd int) (fd int, err error) {
|
||||
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
|
||||
fd = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Pread(fd int, p []byte, offset int64) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(p) > 0 {
|
||||
_p0 = unsafe.Pointer(&p[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(p) > 0 {
|
||||
_p0 = unsafe.Pointer(&p[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Close(fd int) (err error) {
|
||||
r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Fstat(fd int, edir []byte) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p0 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
|
||||
n = int(r0)
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Fwstat(fd int, edir []byte) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(edir) > 0 {
|
||||
_p0 = unsafe.Pointer(&edir[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
|
||||
if int32(r0) == -1 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
49
vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
generated
vendored
49
vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
generated
vendored
@ -1,49 +0,0 @@
|
||||
// mksysnum_plan9.sh /opt/plan9/sys/src/libc/9syscall/sys.h
|
||||
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||
|
||||
package plan9
|
||||
|
||||
const (
|
||||
SYS_SYSR1 = 0
|
||||
SYS_BIND = 2
|
||||
SYS_CHDIR = 3
|
||||
SYS_CLOSE = 4
|
||||
SYS_DUP = 5
|
||||
SYS_ALARM = 6
|
||||
SYS_EXEC = 7
|
||||
SYS_EXITS = 8
|
||||
SYS_FAUTH = 10
|
||||
SYS_SEGBRK = 12
|
||||
SYS_OPEN = 14
|
||||
SYS_OSEEK = 16
|
||||
SYS_SLEEP = 17
|
||||
SYS_RFORK = 19
|
||||
SYS_PIPE = 21
|
||||
SYS_CREATE = 22
|
||||
SYS_FD2PATH = 23
|
||||
SYS_BRK_ = 24
|
||||
SYS_REMOVE = 25
|
||||
SYS_NOTIFY = 28
|
||||
SYS_NOTED = 29
|
||||
SYS_SEGATTACH = 30
|
||||
SYS_SEGDETACH = 31
|
||||
SYS_SEGFREE = 32
|
||||
SYS_SEGFLUSH = 33
|
||||
SYS_RENDEZVOUS = 34
|
||||
SYS_UNMOUNT = 35
|
||||
SYS_SEMACQUIRE = 37
|
||||
SYS_SEMRELEASE = 38
|
||||
SYS_SEEK = 39
|
||||
SYS_FVERSION = 40
|
||||
SYS_ERRSTR = 41
|
||||
SYS_STAT = 42
|
||||
SYS_FSTAT = 43
|
||||
SYS_WSTAT = 44
|
||||
SYS_FWSTAT = 45
|
||||
SYS_MOUNT = 46
|
||||
SYS_AWAIT = 47
|
||||
SYS_PREAD = 50
|
||||
SYS_PWRITE = 51
|
||||
SYS_TSEMACQUIRE = 52
|
||||
SYS_NSEC = 53
|
||||
)
|
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
@ -1,2 +0,0 @@
|
||||
_obj/
|
||||
unix.test
|
173
vendor/golang.org/x/sys/unix/README.md
generated
vendored
173
vendor/golang.org/x/sys/unix/README.md
generated
vendored
@ -1,173 +0,0 @@
|
||||
# Building `sys/unix`
|
||||
|
||||
The sys/unix package provides access to the raw system call interface of the
|
||||
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
|
||||
|
||||
Porting Go to a new architecture/OS combination or adding syscalls, types, or
|
||||
constants to an existing architecture/OS pair requires some manual effort;
|
||||
however, there are tools that automate much of the process.
|
||||
|
||||
## Build Systems
|
||||
|
||||
There are currently two ways we generate the necessary files. We are currently
|
||||
migrating the build system to use containers so the builds are reproducible.
|
||||
This is being done on an OS-by-OS basis. Please update this documentation as
|
||||
components of the build system change.
|
||||
|
||||
### Old Build System (currently for `GOOS != "linux"`)
|
||||
|
||||
The old build system generates the Go files based on the C header files
|
||||
present on your system. This means that files
|
||||
for a given GOOS/GOARCH pair must be generated on a system with that OS and
|
||||
architecture. This also means that the generated code can differ from system
|
||||
to system, based on differences in the header files.
|
||||
|
||||
To avoid this, if you are using the old build system, only generate the Go
|
||||
files on an installation with unmodified header files. It is also important to
|
||||
keep track of which version of the OS the files were generated from (ex.
|
||||
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
|
||||
and have each OS upgrade correspond to a single change.
|
||||
|
||||
To build the files for your current OS and architecture, make sure GOOS and
|
||||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
|
||||
your specific system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, perl, go
|
||||
|
||||
### New Build System (currently for `GOOS == "linux"`)
|
||||
|
||||
The new build system uses a Docker container to generate the go files directly
|
||||
from source checkouts of the kernel and various system libraries. This means
|
||||
that on any platform that supports Docker, all the files using the new build
|
||||
system can be generated at once, and generated files will not change based on
|
||||
what the person running the scripts has installed on their computer.
|
||||
|
||||
The OS specific files for the new build system are located in the `${GOOS}`
|
||||
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
|
||||
the kernel or system library updates, modify the Dockerfile at
|
||||
`${GOOS}/Dockerfile` to checkout the new release of the source.
|
||||
|
||||
To build all the files under the new build system, you must be on an amd64/Linux
|
||||
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
|
||||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
|
||||
system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, perl, go, docker
|
||||
|
||||
## Component files
|
||||
|
||||
This section describes the various files used in the code generation process.
|
||||
It also contains instructions on how to modify these files to add a new
|
||||
architecture/OS or to add additional syscalls, types, or constants. Note that
|
||||
if you are using the new build system, the scripts cannot be called normally.
|
||||
They must be called from within the docker container.
|
||||
|
||||
### asm files
|
||||
|
||||
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
|
||||
call dispatch. There are three entry points:
|
||||
```
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
```
|
||||
The first and second are the standard ones; they differ only in how many
|
||||
arguments can be passed to the kernel. The third is for low-level use by the
|
||||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
||||
let it know that a system call is running.
|
||||
|
||||
When porting Go to an new architecture/OS, this file must be implemented for
|
||||
each GOOS/GOARCH pair.
|
||||
|
||||
### mksysnum
|
||||
|
||||
Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl`
|
||||
for the old system). This script takes in a list of header files containing the
|
||||
syscall number declarations and parses them to produce the corresponding list of
|
||||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
||||
constants.
|
||||
|
||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
||||
new installation of the target OS (or updating the source checkouts for the
|
||||
new build system). However, depending on the OS, you make need to update the
|
||||
parsing in mksysnum.
|
||||
|
||||
### mksyscall.pl
|
||||
|
||||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
||||
hand-written Go files which implement system calls (for unix, the specific OS,
|
||||
or the specific OS/Architecture pair respectively) that need special handling
|
||||
and list `//sys` comments giving prototypes for ones that can be generated.
|
||||
|
||||
The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts
|
||||
them into syscalls. This requires the name of the prototype in the comment to
|
||||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
||||
prototype can be exported (capitalized) or not.
|
||||
|
||||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
||||
with the desired arguments and a capitalized name so it is exported. However, if
|
||||
you want the interface to the syscall to be different, often one will make an
|
||||
unexported `//sys` prototype, an then write a custom wrapper in
|
||||
`syscall_${GOOS}.go`.
|
||||
|
||||
### types files
|
||||
|
||||
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
|
||||
`types_${GOOS}.go` on the old system). This file includes standard C headers and
|
||||
creates Go type aliases to the corresponding C types. The file is then fed
|
||||
through godef to get the Go compatible definitions. Finally, the generated code
|
||||
is fed though mkpost.go to format the code correctly and remove any hidden or
|
||||
private identifiers. This cleaned-up code is written to
|
||||
`ztypes_${GOOS}_${GOARCH}.go`.
|
||||
|
||||
The hardest part about preparing this file is figuring out which headers to
|
||||
include and which symbols need to be `#define`d to get the actual data
|
||||
structures that pass through to the kernel system calls. Some C libraries
|
||||
preset alternate versions for binary compatibility and translate them on the
|
||||
way in and out of system calls, but there is almost always a `#define` that can
|
||||
get the real ones.
|
||||
See `types_darwin.go` and `linux/types.go` for examples.
|
||||
|
||||
To add a new type, add in the necessary include statement at the top of the
|
||||
file (if it is not already there) and add in a type alias line. Note that if
|
||||
your type is significantly different on different architectures, you may need
|
||||
some `#if/#elif` macros in your include statements.
|
||||
|
||||
### mkerrors.sh
|
||||
|
||||
This script is used to generate the system's various constants. This doesn't
|
||||
just include the error numbers and error strings, but also the signal numbers
|
||||
an a wide variety of miscellaneous constants. The constants come from the list
|
||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
||||
the desired `#define` statements, and generates the corresponding Go constants.
|
||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
||||
signal numbers and strings are generated from `#include <signal.h>`. All of
|
||||
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
|
||||
`_errors.c`, which prints out all the constants.
|
||||
|
||||
To add a constant, add the header that includes it to the appropriate variable.
|
||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||
the regex too broad to avoid matching unintended constants.
|
||||
|
||||
|
||||
## Generated files
|
||||
|
||||
### `zerror_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all of the system's generated error numbers, error strings,
|
||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
||||
|
||||
### `zsyscall_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all the generated syscalls for a specific GOOS and GOARCH.
|
||||
Generated by `mksyscall.pl` (see above).
|
||||
|
||||
### `zsysnum_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A list of numeric constants for all the syscall number of the specific GOOS
|
||||
and GOARCH. Generated by mksysnum (see above).
|
||||
|
||||
### `ztypes_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing Go types for passing into (or returning from) syscalls.
|
||||
Generated by godefs and the types file (see above).
|
134
vendor/golang.org/x/sys/unix/creds_test.go
generated
vendored
134
vendor/golang.org/x/sys/unix/creds_test.go
generated
vendored
@ -1,134 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build linux
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/build"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// TestSCMCredentials tests the sending and receiving of credentials
|
||||
// (PID, UID, GID) in an ancillary message between two UNIX
|
||||
// sockets. The SO_PASSCRED socket option is enabled on the sending
|
||||
// socket for this to work.
|
||||
func TestSCMCredentials(t *testing.T) {
|
||||
socketTypeTests := []struct {
|
||||
socketType int
|
||||
dataLen int
|
||||
}{
|
||||
{
|
||||
unix.SOCK_STREAM,
|
||||
1,
|
||||
}, {
|
||||
unix.SOCK_DGRAM,
|
||||
0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range socketTypeTests {
|
||||
if tt.socketType == unix.SOCK_DGRAM && !atLeast1p10() {
|
||||
t.Log("skipping DGRAM test on pre-1.10")
|
||||
continue
|
||||
}
|
||||
|
||||
fds, err := unix.Socketpair(unix.AF_LOCAL, tt.socketType, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Socketpair: %v", err)
|
||||
}
|
||||
defer unix.Close(fds[0])
|
||||
defer unix.Close(fds[1])
|
||||
|
||||
err = unix.SetsockoptInt(fds[0], unix.SOL_SOCKET, unix.SO_PASSCRED, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("SetsockoptInt: %v", err)
|
||||
}
|
||||
|
||||
srvFile := os.NewFile(uintptr(fds[0]), "server")
|
||||
defer srvFile.Close()
|
||||
srv, err := net.FileConn(srvFile)
|
||||
if err != nil {
|
||||
t.Errorf("FileConn: %v", err)
|
||||
return
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
cliFile := os.NewFile(uintptr(fds[1]), "client")
|
||||
defer cliFile.Close()
|
||||
cli, err := net.FileConn(cliFile)
|
||||
if err != nil {
|
||||
t.Errorf("FileConn: %v", err)
|
||||
return
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
var ucred unix.Ucred
|
||||
ucred.Pid = int32(os.Getpid())
|
||||
ucred.Uid = uint32(os.Getuid())
|
||||
ucred.Gid = uint32(os.Getgid())
|
||||
oob := unix.UnixCredentials(&ucred)
|
||||
|
||||
// On SOCK_STREAM, this is internally going to send a dummy byte
|
||||
n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("WriteMsgUnix: %v", err)
|
||||
}
|
||||
if n != 0 {
|
||||
t.Fatalf("WriteMsgUnix n = %d, want 0", n)
|
||||
}
|
||||
if oobn != len(oob) {
|
||||
t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
|
||||
}
|
||||
|
||||
oob2 := make([]byte, 10*len(oob))
|
||||
n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadMsgUnix: %v", err)
|
||||
}
|
||||
if flags != 0 {
|
||||
t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
|
||||
}
|
||||
if n != tt.dataLen {
|
||||
t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
|
||||
}
|
||||
if oobn2 != oobn {
|
||||
// without SO_PASSCRED set on the socket, ReadMsgUnix will
|
||||
// return zero oob bytes
|
||||
t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
|
||||
}
|
||||
oob2 = oob2[:oobn2]
|
||||
if !bytes.Equal(oob, oob2) {
|
||||
t.Fatal("ReadMsgUnix oob bytes don't match")
|
||||
}
|
||||
|
||||
scm, err := unix.ParseSocketControlMessage(oob2)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseSocketControlMessage: %v", err)
|
||||
}
|
||||
newUcred, err := unix.ParseUnixCredentials(&scm[0])
|
||||
if err != nil {
|
||||
t.Fatalf("ParseUnixCredentials: %v", err)
|
||||
}
|
||||
if *newUcred != ucred {
|
||||
t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// atLeast1p10 reports whether we are running on Go 1.10 or later.
|
||||
func atLeast1p10() bool {
|
||||
for _, ver := range build.Default.ReleaseTags {
|
||||
if ver == "go1.10" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
210
vendor/golang.org/x/sys/unix/darwin_test.go
generated
vendored
210
vendor/golang.org/x/sys/unix/darwin_test.go
generated
vendored
@ -1,210 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build darwin,go1.12,amd64 darwin,go1.12,386
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type darwinTest struct {
|
||||
name string
|
||||
f func()
|
||||
}
|
||||
|
||||
// TODO(khr): decide whether to keep this test enabled permanently or
|
||||
// only temporarily.
|
||||
func TestDarwinLoader(t *testing.T) {
|
||||
// Make sure the Darwin dynamic loader can actually resolve
|
||||
// all the system calls into libSystem.dylib. Unfortunately
|
||||
// there is no easy way to test this at compile time. So we
|
||||
// implement a crazy hack here, calling into the syscall
|
||||
// function with all its arguments set to junk, and see what
|
||||
// error we get. We are happy with any error (or none) except
|
||||
// an error from the dynamic loader.
|
||||
//
|
||||
// We have to run each test in a separate subprocess for fault isolation.
|
||||
//
|
||||
// Hopefully the junk args won't accidentally ask the system to do "rm -fr /".
|
||||
//
|
||||
// In an ideal world each syscall would have its own test, so this test
|
||||
// would be unnecessary. Unfortunately, we do not live in that world.
|
||||
for _, test := range darwinTests {
|
||||
// Call the test binary recursively, giving it a magic argument
|
||||
// (see init below) and the name of the test to run.
|
||||
cmd := exec.Command(os.Args[0], "testDarwinLoader", test.name)
|
||||
|
||||
// Run subprocess, collect results. Note that we expect the subprocess
|
||||
// to fail somehow, so the error is irrelevant.
|
||||
out, _ := cmd.CombinedOutput()
|
||||
|
||||
if strings.Contains(string(out), "dyld: Symbol not found:") {
|
||||
t.Errorf("can't resolve %s in libSystem.dylib", test.name)
|
||||
}
|
||||
if !strings.Contains(string(out), "success") {
|
||||
// Not really an error. Might be a syscall that never returns,
|
||||
// like exit, or one that segfaults, like gettimeofday.
|
||||
t.Logf("test never finished: %s: %s", test.name, string(out))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
// The test binary execs itself with the "testDarwinLoader" argument.
|
||||
// Run the test specified by os.Args[2], then panic.
|
||||
if len(os.Args) >= 3 && os.Args[1] == "testDarwinLoader" {
|
||||
for _, test := range darwinTests {
|
||||
if test.name == os.Args[2] {
|
||||
test.f()
|
||||
}
|
||||
}
|
||||
// Panic with a "success" label, so the parent process can check it.
|
||||
panic("success")
|
||||
}
|
||||
}
|
||||
|
||||
// All the _trampoline functions in zsyscall_darwin_$ARCH.s
|
||||
var darwinTests = [...]darwinTest{
|
||||
{"getgroups", libc_getgroups_trampoline},
|
||||
{"setgroups", libc_setgroups_trampoline},
|
||||
{"wait4", libc_wait4_trampoline},
|
||||
{"accept", libc_accept_trampoline},
|
||||
{"bind", libc_bind_trampoline},
|
||||
{"connect", libc_connect_trampoline},
|
||||
{"socket", libc_socket_trampoline},
|
||||
{"getsockopt", libc_getsockopt_trampoline},
|
||||
{"setsockopt", libc_setsockopt_trampoline},
|
||||
{"getpeername", libc_getpeername_trampoline},
|
||||
{"getsockname", libc_getsockname_trampoline},
|
||||
{"shutdown", libc_shutdown_trampoline},
|
||||
{"socketpair", libc_socketpair_trampoline},
|
||||
{"recvfrom", libc_recvfrom_trampoline},
|
||||
{"sendto", libc_sendto_trampoline},
|
||||
{"recvmsg", libc_recvmsg_trampoline},
|
||||
{"sendmsg", libc_sendmsg_trampoline},
|
||||
{"kevent", libc_kevent_trampoline},
|
||||
{"__sysctl", libc___sysctl_trampoline},
|
||||
{"utimes", libc_utimes_trampoline},
|
||||
{"futimes", libc_futimes_trampoline},
|
||||
{"fcntl", libc_fcntl_trampoline},
|
||||
{"poll", libc_poll_trampoline},
|
||||
{"madvise", libc_madvise_trampoline},
|
||||
{"mlock", libc_mlock_trampoline},
|
||||
{"mlockall", libc_mlockall_trampoline},
|
||||
{"mprotect", libc_mprotect_trampoline},
|
||||
{"msync", libc_msync_trampoline},
|
||||
{"munlock", libc_munlock_trampoline},
|
||||
{"munlockall", libc_munlockall_trampoline},
|
||||
{"ptrace", libc_ptrace_trampoline},
|
||||
{"pipe", libc_pipe_trampoline},
|
||||
{"getxattr", libc_getxattr_trampoline},
|
||||
{"fgetxattr", libc_fgetxattr_trampoline},
|
||||
{"setxattr", libc_setxattr_trampoline},
|
||||
{"fsetxattr", libc_fsetxattr_trampoline},
|
||||
{"removexattr", libc_removexattr_trampoline},
|
||||
{"fremovexattr", libc_fremovexattr_trampoline},
|
||||
{"listxattr", libc_listxattr_trampoline},
|
||||
{"flistxattr", libc_flistxattr_trampoline},
|
||||
{"kill", libc_kill_trampoline},
|
||||
{"ioctl", libc_ioctl_trampoline},
|
||||
{"access", libc_access_trampoline},
|
||||
{"adjtime", libc_adjtime_trampoline},
|
||||
{"chdir", libc_chdir_trampoline},
|
||||
{"chflags", libc_chflags_trampoline},
|
||||
{"chmod", libc_chmod_trampoline},
|
||||
{"chown", libc_chown_trampoline},
|
||||
{"chroot", libc_chroot_trampoline},
|
||||
{"close", libc_close_trampoline},
|
||||
{"dup", libc_dup_trampoline},
|
||||
{"dup2", libc_dup2_trampoline},
|
||||
{"exchangedata", libc_exchangedata_trampoline},
|
||||
{"exit", libc_exit_trampoline},
|
||||
{"faccessat", libc_faccessat_trampoline},
|
||||
{"fchdir", libc_fchdir_trampoline},
|
||||
{"fchflags", libc_fchflags_trampoline},
|
||||
{"fchmod", libc_fchmod_trampoline},
|
||||
{"fchmodat", libc_fchmodat_trampoline},
|
||||
{"fchown", libc_fchown_trampoline},
|
||||
{"fchownat", libc_fchownat_trampoline},
|
||||
{"flock", libc_flock_trampoline},
|
||||
{"fpathconf", libc_fpathconf_trampoline},
|
||||
{"fstat64", libc_fstat64_trampoline},
|
||||
{"fstatat64", libc_fstatat64_trampoline},
|
||||
{"fstatfs64", libc_fstatfs64_trampoline},
|
||||
{"fsync", libc_fsync_trampoline},
|
||||
{"ftruncate", libc_ftruncate_trampoline},
|
||||
{"__getdirentries64", libc___getdirentries64_trampoline},
|
||||
{"getdtablesize", libc_getdtablesize_trampoline},
|
||||
{"getegid", libc_getegid_trampoline},
|
||||
{"geteuid", libc_geteuid_trampoline},
|
||||
{"getgid", libc_getgid_trampoline},
|
||||
{"getpgid", libc_getpgid_trampoline},
|
||||
{"getpgrp", libc_getpgrp_trampoline},
|
||||
{"getpid", libc_getpid_trampoline},
|
||||
{"getppid", libc_getppid_trampoline},
|
||||
{"getpriority", libc_getpriority_trampoline},
|
||||
{"getrlimit", libc_getrlimit_trampoline},
|
||||
{"getrusage", libc_getrusage_trampoline},
|
||||
{"getsid", libc_getsid_trampoline},
|
||||
{"getuid", libc_getuid_trampoline},
|
||||
{"issetugid", libc_issetugid_trampoline},
|
||||
{"kqueue", libc_kqueue_trampoline},
|
||||
{"lchown", libc_lchown_trampoline},
|
||||
{"link", libc_link_trampoline},
|
||||
{"linkat", libc_linkat_trampoline},
|
||||
{"listen", libc_listen_trampoline},
|
||||
{"lstat64", libc_lstat64_trampoline},
|
||||
{"mkdir", libc_mkdir_trampoline},
|
||||
{"mkdirat", libc_mkdirat_trampoline},
|
||||
{"mkfifo", libc_mkfifo_trampoline},
|
||||
{"mknod", libc_mknod_trampoline},
|
||||
{"open", libc_open_trampoline},
|
||||
{"openat", libc_openat_trampoline},
|
||||
{"pathconf", libc_pathconf_trampoline},
|
||||
{"pread", libc_pread_trampoline},
|
||||
{"pwrite", libc_pwrite_trampoline},
|
||||
{"read", libc_read_trampoline},
|
||||
{"readlink", libc_readlink_trampoline},
|
||||
{"readlinkat", libc_readlinkat_trampoline},
|
||||
{"rename", libc_rename_trampoline},
|
||||
{"renameat", libc_renameat_trampoline},
|
||||
{"revoke", libc_revoke_trampoline},
|
||||
{"rmdir", libc_rmdir_trampoline},
|
||||
{"lseek", libc_lseek_trampoline},
|
||||
{"select", libc_select_trampoline},
|
||||
{"setegid", libc_setegid_trampoline},
|
||||
{"seteuid", libc_seteuid_trampoline},
|
||||
{"setgid", libc_setgid_trampoline},
|
||||
{"setlogin", libc_setlogin_trampoline},
|
||||
{"setpgid", libc_setpgid_trampoline},
|
||||
{"setpriority", libc_setpriority_trampoline},
|
||||
{"setprivexec", libc_setprivexec_trampoline},
|
||||
{"setregid", libc_setregid_trampoline},
|
||||
{"setreuid", libc_setreuid_trampoline},
|
||||
{"setrlimit", libc_setrlimit_trampoline},
|
||||
{"setsid", libc_setsid_trampoline},
|
||||
{"settimeofday", libc_settimeofday_trampoline},
|
||||
{"setuid", libc_setuid_trampoline},
|
||||
{"stat64", libc_stat64_trampoline},
|
||||
{"statfs64", libc_statfs64_trampoline},
|
||||
{"symlink", libc_symlink_trampoline},
|
||||
{"symlinkat", libc_symlinkat_trampoline},
|
||||
{"sync", libc_sync_trampoline},
|
||||
{"truncate", libc_truncate_trampoline},
|
||||
{"umask", libc_umask_trampoline},
|
||||
{"undelete", libc_undelete_trampoline},
|
||||
{"unlink", libc_unlink_trampoline},
|
||||
{"unlinkat", libc_unlinkat_trampoline},
|
||||
{"unmount", libc_unmount_trampoline},
|
||||
{"write", libc_write_trampoline},
|
||||
{"mmap", libc_mmap_trampoline},
|
||||
{"munmap", libc_munmap_trampoline},
|
||||
{"gettimeofday", libc_gettimeofday_trampoline},
|
||||
{"getfsstat64", libc_getfsstat64_trampoline},
|
||||
}
|
56
vendor/golang.org/x/sys/unix/dev_linux_test.go
generated
vendored
56
vendor/golang.org/x/sys/unix/dev_linux_test.go
generated
vendored
@ -1,56 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDevices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
major uint32
|
||||
minor uint32
|
||||
}{
|
||||
// well known major/minor numbers according to
|
||||
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/devices.txt
|
||||
{"/dev/null", 1, 3},
|
||||
{"/dev/zero", 1, 5},
|
||||
{"/dev/random", 1, 8},
|
||||
{"/dev/full", 1, 7},
|
||||
{"/dev/urandom", 1, 9},
|
||||
{"/dev/tty", 5, 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)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
19
vendor/golang.org/x/sys/unix/example_exec_test.go
generated
vendored
19
vendor/golang.org/x/sys/unix/example_exec_test.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func ExampleExec() {
|
||||
err := unix.Exec("/bin/ls", []string{"ls", "-al"}, os.Environ())
|
||||
log.Fatal(err)
|
||||
}
|
25
vendor/golang.org/x/sys/unix/example_flock_test.go
generated
vendored
25
vendor/golang.org/x/sys/unix/example_flock_test.go
generated
vendored
@ -1,25 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func ExampleFlock() {
|
||||
f, _ := os.Create("example.lock")
|
||||
if err := unix.Flock(int(f.Fd()), unix.LOCK_EX); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Do work here that requires the lock. When finished, release the lock:
|
||||
if err := unix.Flock(int(f.Fd()), unix.LOCK_UN); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
9
vendor/golang.org/x/sys/unix/export_test.go
generated
vendored
9
vendor/golang.org/x/sys/unix/export_test.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
var Itoa = itoa
|
53
vendor/golang.org/x/sys/unix/linux/Dockerfile
generated
vendored
53
vendor/golang.org/x/sys/unix/linux/Dockerfile
generated
vendored
@ -1,53 +0,0 @@
|
||||
FROM ubuntu:18.10
|
||||
|
||||
# Dependencies to get the git sources and go binaries
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Get the git sources. If not cached, this takes O(5 minutes).
|
||||
WORKDIR /git
|
||||
RUN git config --global advice.detachedHead false
|
||||
# Linux Kernel: Released 23 Dec 2018
|
||||
RUN git clone --branch v4.20 --depth 1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
|
||||
# GNU C library: Released 01 Aug 2018 (we should try to get a secure way to clone this)
|
||||
RUN git clone --branch glibc-2.28 --depth 1 git://sourceware.org/git/glibc.git
|
||||
|
||||
# Get Go
|
||||
ENV GOLANG_VERSION 1.12beta1
|
||||
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
|
||||
ENV GOLANG_DOWNLOAD_SHA256 65bfd4a99925f1f85d712f4c1109977aa24ee4c6e198162bf8e819fdde19e875
|
||||
|
||||
RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \
|
||||
&& echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \
|
||||
&& tar -C /usr/local -xzf golang.tar.gz \
|
||||
&& rm golang.tar.gz
|
||||
|
||||
ENV PATH /usr/local/go/bin:$PATH
|
||||
|
||||
# Linux and Glibc build dependencies and emulator
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
bison gawk make python \
|
||||
gcc gcc-multilib \
|
||||
gettext texinfo \
|
||||
qemu-user \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
# Cross compilers (install recommended packages to get cross libc-dev)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc-aarch64-linux-gnu gcc-arm-linux-gnueabi \
|
||||
gcc-mips-linux-gnu gcc-mips64-linux-gnuabi64 \
|
||||
gcc-mips64el-linux-gnuabi64 gcc-mipsel-linux-gnu \
|
||||
gcc-powerpc64-linux-gnu gcc-powerpc64le-linux-gnu \
|
||||
gcc-riscv64-linux-gnu \
|
||||
gcc-s390x-linux-gnu gcc-sparc64-linux-gnu \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Let the scripts know they are in the docker environment
|
||||
ENV GOLANG_SYS_BUILD docker
|
||||
WORKDIR /build
|
||||
ENTRYPOINT ["go", "run", "linux/mkall.go", "/git/linux", "/git/glibc"]
|
775
vendor/golang.org/x/sys/unix/linux/mkall.go
generated
vendored
775
vendor/golang.org/x/sys/unix/linux/mkall.go
generated
vendored
@ -1,775 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// linux/mkall.go - Generates all Linux zsysnum, zsyscall, zerror, and ztype
|
||||
// files for all Linux architectures supported by the go compiler. See
|
||||
// README.md for more information about the build system.
|
||||
|
||||
// To run it you must have a git checkout of the Linux kernel and glibc. Once
|
||||
// the appropriate sources are ready, the program is run as:
|
||||
// go run linux/mkall.go <linux_dir> <glibc_dir>
|
||||
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"debug/elf"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// These will be paths to the appropriate source directories.
|
||||
var LinuxDir string
|
||||
var GlibcDir string
|
||||
|
||||
const TempDir = "/tmp"
|
||||
const IncludeDir = TempDir + "/include" // To hold our C headers
|
||||
const BuildDir = TempDir + "/build" // To hold intermediate build files
|
||||
|
||||
const GOOS = "linux" // Only for Linux targets
|
||||
const BuildArch = "amd64" // Must be built on this architecture
|
||||
const MinKernel = "2.6.23" // https://golang.org/doc/install#requirements
|
||||
|
||||
type target struct {
|
||||
GoArch string // Architecture name according to Go
|
||||
LinuxArch string // Architecture name according to the Linux Kernel
|
||||
GNUArch string // Architecture name according to GNU tools (https://wiki.debian.org/Multiarch/Tuples)
|
||||
BigEndian bool // Default Little Endian
|
||||
SignedChar bool // Is -fsigned-char needed (default no)
|
||||
Bits int
|
||||
}
|
||||
|
||||
// List of all Linux targets supported by the go compiler. Currently, riscv64
|
||||
// and sparc64 are not fully supported, but there is enough support already to
|
||||
// generate Go type and error definitions.
|
||||
var targets = []target{
|
||||
{
|
||||
GoArch: "386",
|
||||
LinuxArch: "x86",
|
||||
GNUArch: "i686-linux-gnu", // Note "i686" not "i386"
|
||||
Bits: 32,
|
||||
},
|
||||
{
|
||||
GoArch: "amd64",
|
||||
LinuxArch: "x86",
|
||||
GNUArch: "x86_64-linux-gnu",
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "arm64",
|
||||
LinuxArch: "arm64",
|
||||
GNUArch: "aarch64-linux-gnu",
|
||||
SignedChar: true,
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "arm",
|
||||
LinuxArch: "arm",
|
||||
GNUArch: "arm-linux-gnueabi",
|
||||
Bits: 32,
|
||||
},
|
||||
{
|
||||
GoArch: "mips",
|
||||
LinuxArch: "mips",
|
||||
GNUArch: "mips-linux-gnu",
|
||||
BigEndian: true,
|
||||
Bits: 32,
|
||||
},
|
||||
{
|
||||
GoArch: "mipsle",
|
||||
LinuxArch: "mips",
|
||||
GNUArch: "mipsel-linux-gnu",
|
||||
Bits: 32,
|
||||
},
|
||||
{
|
||||
GoArch: "mips64",
|
||||
LinuxArch: "mips",
|
||||
GNUArch: "mips64-linux-gnuabi64",
|
||||
BigEndian: true,
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "mips64le",
|
||||
LinuxArch: "mips",
|
||||
GNUArch: "mips64el-linux-gnuabi64",
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "ppc64",
|
||||
LinuxArch: "powerpc",
|
||||
GNUArch: "powerpc64-linux-gnu",
|
||||
BigEndian: true,
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "ppc64le",
|
||||
LinuxArch: "powerpc",
|
||||
GNUArch: "powerpc64le-linux-gnu",
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "riscv64",
|
||||
LinuxArch: "riscv",
|
||||
GNUArch: "riscv64-linux-gnu",
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "s390x",
|
||||
LinuxArch: "s390",
|
||||
GNUArch: "s390x-linux-gnu",
|
||||
BigEndian: true,
|
||||
SignedChar: true,
|
||||
Bits: 64,
|
||||
},
|
||||
{
|
||||
GoArch: "sparc64",
|
||||
LinuxArch: "sparc",
|
||||
GNUArch: "sparc64-linux-gnu",
|
||||
BigEndian: true,
|
||||
Bits: 64,
|
||||
},
|
||||
}
|
||||
|
||||
// ptracePairs is a list of pairs of targets that can, in some cases,
|
||||
// run each other's binaries.
|
||||
var ptracePairs = []struct{ a1, a2 string }{
|
||||
{"386", "amd64"},
|
||||
{"arm", "arm64"},
|
||||
{"mips", "mips64"},
|
||||
{"mipsle", "mips64le"},
|
||||
}
|
||||
|
||||
func main() {
|
||||
if runtime.GOOS != GOOS || runtime.GOARCH != BuildArch {
|
||||
fmt.Printf("Build system has GOOS_GOARCH = %s_%s, need %s_%s\n",
|
||||
runtime.GOOS, runtime.GOARCH, GOOS, BuildArch)
|
||||
return
|
||||
}
|
||||
|
||||
// Check that we are using the new build system if we should
|
||||
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
|
||||
fmt.Println("In the new build system, mkall.go should not be called directly.")
|
||||
fmt.Println("See README.md")
|
||||
return
|
||||
}
|
||||
|
||||
// Parse the command line options
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Println("USAGE: go run linux/mkall.go <linux_dir> <glibc_dir>")
|
||||
return
|
||||
}
|
||||
LinuxDir = os.Args[1]
|
||||
GlibcDir = os.Args[2]
|
||||
|
||||
for _, t := range targets {
|
||||
fmt.Printf("----- GENERATING: %s -----\n", t.GoArch)
|
||||
if err := t.generateFiles(); err != nil {
|
||||
fmt.Printf("%v\n***** FAILURE: %s *****\n\n", err, t.GoArch)
|
||||
} else {
|
||||
fmt.Printf("----- SUCCESS: %s -----\n\n", t.GoArch)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("----- GENERATING ptrace pairs -----\n")
|
||||
ok := true
|
||||
for _, p := range ptracePairs {
|
||||
if err := generatePtracePair(p.a1, p.a2); err != nil {
|
||||
fmt.Printf("%v\n***** FAILURE: %s/%s *****\n\n", err, p.a1, p.a2)
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
fmt.Printf("----- SUCCESS ptrace pairs -----\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
// Makes an exec.Cmd with Stderr attached to os.Stderr
|
||||
func makeCommand(name string, args ...string) *exec.Cmd {
|
||||
cmd := exec.Command(name, args...)
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Set GOARCH for target and build environments.
|
||||
func (t *target) setTargetBuildArch(cmd *exec.Cmd) {
|
||||
// Set GOARCH_TARGET so command knows what GOARCH is..
|
||||
cmd.Env = append(os.Environ(), "GOARCH_TARGET="+t.GoArch)
|
||||
// Set GOARCH to host arch for command, so it can run natively.
|
||||
for i, s := range cmd.Env {
|
||||
if strings.HasPrefix(s, "GOARCH=") {
|
||||
cmd.Env[i] = "GOARCH=" + BuildArch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Runs the command, pipes output to a formatter, pipes that to an output file.
|
||||
func (t *target) commandFormatOutput(formatter string, outputFile string,
|
||||
name string, args ...string) (err error) {
|
||||
mainCmd := makeCommand(name, args...)
|
||||
if name == "mksyscall" {
|
||||
args = append([]string{"run", "mksyscall.go"}, args...)
|
||||
mainCmd = makeCommand("go", args...)
|
||||
t.setTargetBuildArch(mainCmd)
|
||||
} else if name == "mksysnum" {
|
||||
args = append([]string{"run", "linux/mksysnum.go"}, args...)
|
||||
mainCmd = makeCommand("go", args...)
|
||||
t.setTargetBuildArch(mainCmd)
|
||||
}
|
||||
|
||||
fmtCmd := makeCommand(formatter)
|
||||
if formatter == "mkpost" {
|
||||
fmtCmd = makeCommand("go", "run", "mkpost.go")
|
||||
t.setTargetBuildArch(fmtCmd)
|
||||
}
|
||||
|
||||
// mainCmd | fmtCmd > outputFile
|
||||
if fmtCmd.Stdin, err = mainCmd.StdoutPipe(); err != nil {
|
||||
return
|
||||
}
|
||||
if fmtCmd.Stdout, err = os.Create(outputFile); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Make sure the formatter eventually closes
|
||||
if err = fmtCmd.Start(); err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
fmtErr := fmtCmd.Wait()
|
||||
if err == nil {
|
||||
err = fmtErr
|
||||
}
|
||||
}()
|
||||
|
||||
return mainCmd.Run()
|
||||
}
|
||||
|
||||
// Generates all the files for a Linux target
|
||||
func (t *target) generateFiles() error {
|
||||
// Setup environment variables
|
||||
os.Setenv("GOOS", GOOS)
|
||||
os.Setenv("GOARCH", t.GoArch)
|
||||
|
||||
// Get appropriate compiler and emulator (unless on x86)
|
||||
if t.LinuxArch != "x86" {
|
||||
// Check/Setup cross compiler
|
||||
compiler := t.GNUArch + "-gcc"
|
||||
if _, err := exec.LookPath(compiler); err != nil {
|
||||
return err
|
||||
}
|
||||
os.Setenv("CC", compiler)
|
||||
|
||||
// Check/Setup emulator (usually first component of GNUArch)
|
||||
qemuArchName := t.GNUArch[:strings.Index(t.GNUArch, "-")]
|
||||
if t.LinuxArch == "powerpc" {
|
||||
qemuArchName = t.GoArch
|
||||
}
|
||||
// Fake uname for QEMU to allow running on Host kernel version < 4.15
|
||||
if t.LinuxArch == "riscv" {
|
||||
os.Setenv("QEMU_UNAME", "4.15")
|
||||
}
|
||||
os.Setenv("GORUN", "qemu-"+qemuArchName)
|
||||
} else {
|
||||
os.Setenv("CC", "gcc")
|
||||
}
|
||||
|
||||
// Make the include directory and fill it with headers
|
||||
if err := os.MkdirAll(IncludeDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(IncludeDir)
|
||||
if err := t.makeHeaders(); err != nil {
|
||||
return fmt.Errorf("could not make header files: %v", err)
|
||||
}
|
||||
fmt.Println("header files generated")
|
||||
|
||||
// Make each of the four files
|
||||
if err := t.makeZSysnumFile(); err != nil {
|
||||
return fmt.Errorf("could not make zsysnum file: %v", err)
|
||||
}
|
||||
fmt.Println("zsysnum file generated")
|
||||
|
||||
if err := t.makeZSyscallFile(); err != nil {
|
||||
return fmt.Errorf("could not make zsyscall file: %v", err)
|
||||
}
|
||||
fmt.Println("zsyscall file generated")
|
||||
|
||||
if err := t.makeZTypesFile(); err != nil {
|
||||
return fmt.Errorf("could not make ztypes file: %v", err)
|
||||
}
|
||||
fmt.Println("ztypes file generated")
|
||||
|
||||
if err := t.makeZErrorsFile(); err != nil {
|
||||
return fmt.Errorf("could not make zerrors file: %v", err)
|
||||
}
|
||||
fmt.Println("zerrors file generated")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create the Linux, glibc and ABI (C compiler convention) headers in the include directory.
|
||||
func (t *target) makeHeaders() error {
|
||||
// Make the Linux headers we need for this architecture
|
||||
linuxMake := makeCommand("make", "headers_install", "ARCH="+t.LinuxArch, "INSTALL_HDR_PATH="+TempDir)
|
||||
linuxMake.Dir = LinuxDir
|
||||
if err := linuxMake.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// A Temporary build directory for glibc
|
||||
if err := os.MkdirAll(BuildDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(BuildDir)
|
||||
|
||||
// Make the glibc headers we need for this architecture
|
||||
confScript := filepath.Join(GlibcDir, "configure")
|
||||
glibcConf := makeCommand(confScript, "--prefix="+TempDir, "--host="+t.GNUArch, "--enable-kernel="+MinKernel)
|
||||
glibcConf.Dir = BuildDir
|
||||
if err := glibcConf.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
glibcMake := makeCommand("make", "install-headers")
|
||||
glibcMake.Dir = BuildDir
|
||||
if err := glibcMake.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
// We only need an empty stubs file
|
||||
stubsFile := filepath.Join(IncludeDir, "gnu/stubs.h")
|
||||
if file, err := os.Create(stubsFile); err != nil {
|
||||
return err
|
||||
} else {
|
||||
file.Close()
|
||||
}
|
||||
|
||||
// ABI headers will specify C compiler behavior for the target platform.
|
||||
return t.makeABIHeaders()
|
||||
}
|
||||
|
||||
// makeABIHeaders generates C header files based on the platform's calling convention.
|
||||
// While many platforms have formal Application Binary Interfaces, in practice, whatever the
|
||||
// dominant C compilers generate is the de-facto calling convention.
|
||||
//
|
||||
// We generate C headers instead of a Go file, so as to enable references to the ABI from Cgo.
|
||||
func (t *target) makeABIHeaders() (err error) {
|
||||
abiDir := filepath.Join(IncludeDir, "abi")
|
||||
if err = os.Mkdir(abiDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cc := os.Getenv("CC")
|
||||
if cc == "" {
|
||||
return errors.New("CC (compiler) env var not set")
|
||||
}
|
||||
|
||||
// Build a sacrificial ELF file, to mine for C compiler behavior.
|
||||
binPath := filepath.Join(TempDir, "tmp_abi.o")
|
||||
bin, err := t.buildELF(cc, cCode, binPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot build ELF to analyze: %v", err)
|
||||
}
|
||||
defer bin.Close()
|
||||
defer os.Remove(binPath)
|
||||
|
||||
// Right now, we put everything in abi.h, but we may change this later.
|
||||
abiFile, err := os.Create(filepath.Join(abiDir, "abi.h"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if cerr := abiFile.Close(); cerr != nil && err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}()
|
||||
|
||||
if err = t.writeBitFieldMasks(bin, abiFile); err != nil {
|
||||
return fmt.Errorf("cannot write bitfield masks: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *target) buildELF(cc, src, path string) (*elf.File, error) {
|
||||
// Compile the cCode source using the set compiler - we will need its .data section.
|
||||
// Do not link the binary, so that we can find .data section offsets from the symbol values.
|
||||
ccCmd := makeCommand(cc, "-o", path, "-gdwarf", "-x", "c", "-c", "-")
|
||||
ccCmd.Stdin = strings.NewReader(src)
|
||||
ccCmd.Stdout = os.Stdout
|
||||
if err := ccCmd.Run(); err != nil {
|
||||
return nil, fmt.Errorf("compiler error: %v", err)
|
||||
}
|
||||
|
||||
bin, err := elf.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot read ELF file %s: %v", path, err)
|
||||
}
|
||||
|
||||
return bin, nil
|
||||
}
|
||||
|
||||
func (t *target) writeBitFieldMasks(bin *elf.File, out io.Writer) error {
|
||||
symbols, err := bin.Symbols()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting ELF symbols: %v", err)
|
||||
}
|
||||
var masksSym *elf.Symbol
|
||||
|
||||
for _, sym := range symbols {
|
||||
if sym.Name == "masks" {
|
||||
masksSym = &sym
|
||||
}
|
||||
}
|
||||
|
||||
if masksSym == nil {
|
||||
return errors.New("could not find the 'masks' symbol in ELF symtab")
|
||||
}
|
||||
|
||||
dataSection := bin.Section(".data")
|
||||
if dataSection == nil {
|
||||
return errors.New("ELF file has no .data section")
|
||||
}
|
||||
|
||||
data, err := dataSection.Data()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read .data section: %v\n", err)
|
||||
}
|
||||
|
||||
var bo binary.ByteOrder
|
||||
if t.BigEndian {
|
||||
bo = binary.BigEndian
|
||||
} else {
|
||||
bo = binary.LittleEndian
|
||||
}
|
||||
|
||||
// 64 bit masks of type uint64 are stored in the data section starting at masks.Value.
|
||||
// Here we are running on AMD64, but these values may be big endian or little endian,
|
||||
// depending on target architecture.
|
||||
for i := uint64(0); i < 64; i++ {
|
||||
off := masksSym.Value + i*8
|
||||
// Define each mask in native by order, so as to match target endian.
|
||||
fmt.Fprintf(out, "#define BITFIELD_MASK_%d %dULL\n", i, bo.Uint64(data[off:off+8]))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// makes the zsysnum_linux_$GOARCH.go file
|
||||
func (t *target) makeZSysnumFile() error {
|
||||
zsysnumFile := fmt.Sprintf("zsysnum_linux_%s.go", t.GoArch)
|
||||
unistdFile := filepath.Join(IncludeDir, "asm/unistd.h")
|
||||
|
||||
args := append(t.cFlags(), unistdFile)
|
||||
return t.commandFormatOutput("gofmt", zsysnumFile, "mksysnum", args...)
|
||||
}
|
||||
|
||||
// makes the zsyscall_linux_$GOARCH.go file
|
||||
func (t *target) makeZSyscallFile() error {
|
||||
zsyscallFile := fmt.Sprintf("zsyscall_linux_%s.go", t.GoArch)
|
||||
// Find the correct architecture syscall file (might end with x.go)
|
||||
archSyscallFile := fmt.Sprintf("syscall_linux_%s.go", t.GoArch)
|
||||
if _, err := os.Stat(archSyscallFile); os.IsNotExist(err) {
|
||||
shortArch := strings.TrimSuffix(t.GoArch, "le")
|
||||
archSyscallFile = fmt.Sprintf("syscall_linux_%sx.go", shortArch)
|
||||
}
|
||||
|
||||
args := append(t.mksyscallFlags(), "-tags", "linux,"+t.GoArch,
|
||||
"syscall_linux.go", archSyscallFile)
|
||||
return t.commandFormatOutput("gofmt", zsyscallFile, "mksyscall", args...)
|
||||
}
|
||||
|
||||
// makes the zerrors_linux_$GOARCH.go file
|
||||
func (t *target) makeZErrorsFile() error {
|
||||
zerrorsFile := fmt.Sprintf("zerrors_linux_%s.go", t.GoArch)
|
||||
|
||||
return t.commandFormatOutput("gofmt", zerrorsFile, "./mkerrors.sh", t.cFlags()...)
|
||||
}
|
||||
|
||||
// makes the ztypes_linux_$GOARCH.go file
|
||||
func (t *target) makeZTypesFile() error {
|
||||
ztypesFile := fmt.Sprintf("ztypes_linux_%s.go", t.GoArch)
|
||||
|
||||
args := []string{"tool", "cgo", "-godefs", "--"}
|
||||
args = append(args, t.cFlags()...)
|
||||
args = append(args, "linux/types.go")
|
||||
return t.commandFormatOutput("mkpost", ztypesFile, "go", args...)
|
||||
}
|
||||
|
||||
// Flags that should be given to gcc and cgo for this target
|
||||
func (t *target) cFlags() []string {
|
||||
// Compile statically to avoid cross-architecture dynamic linking.
|
||||
flags := []string{"-Wall", "-Werror", "-static", "-I" + IncludeDir}
|
||||
|
||||
// Architecture-specific flags
|
||||
if t.SignedChar {
|
||||
flags = append(flags, "-fsigned-char")
|
||||
}
|
||||
if t.LinuxArch == "x86" {
|
||||
flags = append(flags, fmt.Sprintf("-m%d", t.Bits))
|
||||
}
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
// Flags that should be given to mksyscall for this target
|
||||
func (t *target) mksyscallFlags() (flags []string) {
|
||||
if t.Bits == 32 {
|
||||
if t.BigEndian {
|
||||
flags = append(flags, "-b32")
|
||||
} else {
|
||||
flags = append(flags, "-l32")
|
||||
}
|
||||
}
|
||||
|
||||
// This flag means a 64-bit value should use (even, odd)-pair.
|
||||
if t.GoArch == "arm" || (t.LinuxArch == "mips" && t.Bits == 32) {
|
||||
flags = append(flags, "-arm")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// generatePtracePair takes a pair of GOARCH values that can run each
|
||||
// other's binaries, such as 386 and amd64. It extracts the PtraceRegs
|
||||
// type for each one. It writes a new file defining the types
|
||||
// PtraceRegsArch1 and PtraceRegsArch2 and the corresponding functions
|
||||
// Ptrace{Get,Set}Regs{arch1,arch2}. This permits debugging the other
|
||||
// binary on a native system.
|
||||
func generatePtracePair(arch1, arch2 string) error {
|
||||
def1, err := ptraceDef(arch1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
def2, err := ptraceDef(arch2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(fmt.Sprintf("zptrace%s_linux.go", arch1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf := bufio.NewWriter(f)
|
||||
fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%s, %s). DO NOT EDIT.\n", arch1, arch2)
|
||||
fmt.Fprintf(buf, "\n")
|
||||
fmt.Fprintf(buf, "// +build linux\n")
|
||||
fmt.Fprintf(buf, "// +build %s %s\n", arch1, arch2)
|
||||
fmt.Fprintf(buf, "\n")
|
||||
fmt.Fprintf(buf, "package unix\n")
|
||||
fmt.Fprintf(buf, "\n")
|
||||
fmt.Fprintf(buf, "%s\n", `import "unsafe"`)
|
||||
fmt.Fprintf(buf, "\n")
|
||||
writeOnePtrace(buf, arch1, def1)
|
||||
fmt.Fprintf(buf, "\n")
|
||||
writeOnePtrace(buf, arch2, def2)
|
||||
if err := buf.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ptraceDef returns the definition of PtraceRegs for arch.
|
||||
func ptraceDef(arch string) (string, error) {
|
||||
filename := fmt.Sprintf("ztypes_linux_%s.go", arch)
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("reading %s: %v", filename, err)
|
||||
}
|
||||
start := bytes.Index(data, []byte("type PtraceRegs struct"))
|
||||
if start < 0 {
|
||||
return "", fmt.Errorf("%s: no definition of PtraceRegs", filename)
|
||||
}
|
||||
data = data[start:]
|
||||
end := bytes.Index(data, []byte("\n}\n"))
|
||||
if end < 0 {
|
||||
return "", fmt.Errorf("%s: can't find end of PtraceRegs definition", filename)
|
||||
}
|
||||
return string(data[:end+2]), nil
|
||||
}
|
||||
|
||||
// writeOnePtrace writes out the ptrace definitions for arch.
|
||||
func writeOnePtrace(w io.Writer, arch, def string) {
|
||||
uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:]
|
||||
fmt.Fprintf(w, "// PtraceRegs%s is the registers used by %s binaries.\n", uarch, arch)
|
||||
fmt.Fprintf(w, "%s\n", strings.Replace(def, "PtraceRegs", "PtraceRegs"+uarch, 1))
|
||||
fmt.Fprintf(w, "\n")
|
||||
fmt.Fprintf(w, "// PtraceGetRegs%s fetches the registers used by %s binaries.\n", uarch, arch)
|
||||
fmt.Fprintf(w, "func PtraceGetRegs%s(pid int, regsout *PtraceRegs%s) error {\n", uarch, uarch)
|
||||
fmt.Fprintf(w, "\treturn ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))\n")
|
||||
fmt.Fprintf(w, "}\n")
|
||||
fmt.Fprintf(w, "\n")
|
||||
fmt.Fprintf(w, "// PtraceSetRegs%s sets the registers used by %s binaries.\n", uarch, arch)
|
||||
fmt.Fprintf(w, "func PtraceSetRegs%s(pid int, regs *PtraceRegs%s) error {\n", uarch, uarch)
|
||||
fmt.Fprintf(w, "\treturn ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))\n")
|
||||
fmt.Fprintf(w, "}\n")
|
||||
}
|
||||
|
||||
// cCode is compiled for the target architecture, and the resulting data section is carved for
|
||||
// the statically initialized bit masks.
|
||||
const cCode = `
|
||||
// Bit fields are used in some system calls and other ABIs, but their memory layout is
|
||||
// implementation-defined [1]. Even with formal ABIs, bit fields are a source of subtle bugs [2].
|
||||
// Here we generate the offsets for all 64 bits in an uint64.
|
||||
// 1: http://en.cppreference.com/w/c/language/bit_field
|
||||
// 2: https://lwn.net/Articles/478657/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct bitfield {
|
||||
union {
|
||||
uint64_t val;
|
||||
struct {
|
||||
uint64_t u64_bit_0 : 1;
|
||||
uint64_t u64_bit_1 : 1;
|
||||
uint64_t u64_bit_2 : 1;
|
||||
uint64_t u64_bit_3 : 1;
|
||||
uint64_t u64_bit_4 : 1;
|
||||
uint64_t u64_bit_5 : 1;
|
||||
uint64_t u64_bit_6 : 1;
|
||||
uint64_t u64_bit_7 : 1;
|
||||
uint64_t u64_bit_8 : 1;
|
||||
uint64_t u64_bit_9 : 1;
|
||||
uint64_t u64_bit_10 : 1;
|
||||
uint64_t u64_bit_11 : 1;
|
||||
uint64_t u64_bit_12 : 1;
|
||||
uint64_t u64_bit_13 : 1;
|
||||
uint64_t u64_bit_14 : 1;
|
||||
uint64_t u64_bit_15 : 1;
|
||||
uint64_t u64_bit_16 : 1;
|
||||
uint64_t u64_bit_17 : 1;
|
||||
uint64_t u64_bit_18 : 1;
|
||||
uint64_t u64_bit_19 : 1;
|
||||
uint64_t u64_bit_20 : 1;
|
||||
uint64_t u64_bit_21 : 1;
|
||||
uint64_t u64_bit_22 : 1;
|
||||
uint64_t u64_bit_23 : 1;
|
||||
uint64_t u64_bit_24 : 1;
|
||||
uint64_t u64_bit_25 : 1;
|
||||
uint64_t u64_bit_26 : 1;
|
||||
uint64_t u64_bit_27 : 1;
|
||||
uint64_t u64_bit_28 : 1;
|
||||
uint64_t u64_bit_29 : 1;
|
||||
uint64_t u64_bit_30 : 1;
|
||||
uint64_t u64_bit_31 : 1;
|
||||
uint64_t u64_bit_32 : 1;
|
||||
uint64_t u64_bit_33 : 1;
|
||||
uint64_t u64_bit_34 : 1;
|
||||
uint64_t u64_bit_35 : 1;
|
||||
uint64_t u64_bit_36 : 1;
|
||||
uint64_t u64_bit_37 : 1;
|
||||
uint64_t u64_bit_38 : 1;
|
||||
uint64_t u64_bit_39 : 1;
|
||||
uint64_t u64_bit_40 : 1;
|
||||
uint64_t u64_bit_41 : 1;
|
||||
uint64_t u64_bit_42 : 1;
|
||||
uint64_t u64_bit_43 : 1;
|
||||
uint64_t u64_bit_44 : 1;
|
||||
uint64_t u64_bit_45 : 1;
|
||||
uint64_t u64_bit_46 : 1;
|
||||
uint64_t u64_bit_47 : 1;
|
||||
uint64_t u64_bit_48 : 1;
|
||||
uint64_t u64_bit_49 : 1;
|
||||
uint64_t u64_bit_50 : 1;
|
||||
uint64_t u64_bit_51 : 1;
|
||||
uint64_t u64_bit_52 : 1;
|
||||
uint64_t u64_bit_53 : 1;
|
||||
uint64_t u64_bit_54 : 1;
|
||||
uint64_t u64_bit_55 : 1;
|
||||
uint64_t u64_bit_56 : 1;
|
||||
uint64_t u64_bit_57 : 1;
|
||||
uint64_t u64_bit_58 : 1;
|
||||
uint64_t u64_bit_59 : 1;
|
||||
uint64_t u64_bit_60 : 1;
|
||||
uint64_t u64_bit_61 : 1;
|
||||
uint64_t u64_bit_62 : 1;
|
||||
uint64_t u64_bit_63 : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct bitfield masks[] = {
|
||||
{.u64_bit_0 = 1},
|
||||
{.u64_bit_1 = 1},
|
||||
{.u64_bit_2 = 1},
|
||||
{.u64_bit_3 = 1},
|
||||
{.u64_bit_4 = 1},
|
||||
{.u64_bit_5 = 1},
|
||||
{.u64_bit_6 = 1},
|
||||
{.u64_bit_7 = 1},
|
||||
{.u64_bit_8 = 1},
|
||||
{.u64_bit_9 = 1},
|
||||
{.u64_bit_10 = 1},
|
||||
{.u64_bit_11 = 1},
|
||||
{.u64_bit_12 = 1},
|
||||
{.u64_bit_13 = 1},
|
||||
{.u64_bit_14 = 1},
|
||||
{.u64_bit_15 = 1},
|
||||
{.u64_bit_16 = 1},
|
||||
{.u64_bit_17 = 1},
|
||||
{.u64_bit_18 = 1},
|
||||
{.u64_bit_19 = 1},
|
||||
{.u64_bit_20 = 1},
|
||||
{.u64_bit_21 = 1},
|
||||
{.u64_bit_22 = 1},
|
||||
{.u64_bit_23 = 1},
|
||||
{.u64_bit_24 = 1},
|
||||
{.u64_bit_25 = 1},
|
||||
{.u64_bit_26 = 1},
|
||||
{.u64_bit_27 = 1},
|
||||
{.u64_bit_28 = 1},
|
||||
{.u64_bit_29 = 1},
|
||||
{.u64_bit_30 = 1},
|
||||
{.u64_bit_31 = 1},
|
||||
{.u64_bit_32 = 1},
|
||||
{.u64_bit_33 = 1},
|
||||
{.u64_bit_34 = 1},
|
||||
{.u64_bit_35 = 1},
|
||||
{.u64_bit_36 = 1},
|
||||
{.u64_bit_37 = 1},
|
||||
{.u64_bit_38 = 1},
|
||||
{.u64_bit_39 = 1},
|
||||
{.u64_bit_40 = 1},
|
||||
{.u64_bit_41 = 1},
|
||||
{.u64_bit_42 = 1},
|
||||
{.u64_bit_43 = 1},
|
||||
{.u64_bit_44 = 1},
|
||||
{.u64_bit_45 = 1},
|
||||
{.u64_bit_46 = 1},
|
||||
{.u64_bit_47 = 1},
|
||||
{.u64_bit_48 = 1},
|
||||
{.u64_bit_49 = 1},
|
||||
{.u64_bit_50 = 1},
|
||||
{.u64_bit_51 = 1},
|
||||
{.u64_bit_52 = 1},
|
||||
{.u64_bit_53 = 1},
|
||||
{.u64_bit_54 = 1},
|
||||
{.u64_bit_55 = 1},
|
||||
{.u64_bit_56 = 1},
|
||||
{.u64_bit_57 = 1},
|
||||
{.u64_bit_58 = 1},
|
||||
{.u64_bit_59 = 1},
|
||||
{.u64_bit_60 = 1},
|
||||
{.u64_bit_61 = 1},
|
||||
{.u64_bit_62 = 1},
|
||||
{.u64_bit_63 = 1}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct bitfield *mask_ptr = &masks[0];
|
||||
return mask_ptr->val;
|
||||
}
|
||||
|
||||
`
|
143
vendor/golang.org/x/sys/unix/linux/mksysnum.go
generated
vendored
143
vendor/golang.org/x/sys/unix/linux/mksysnum.go
generated
vendored
@ -1,143 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
goos, goarch string
|
||||
)
|
||||
|
||||
// cmdLine returns this programs's commandline arguments
|
||||
func cmdLine() string {
|
||||
return "go run linux/mksysnum.go " + strings.Join(os.Args[1:], " ")
|
||||
}
|
||||
|
||||
// buildTags returns build tags
|
||||
func buildTags() string {
|
||||
return fmt.Sprintf("%s,%s", goarch, goos)
|
||||
}
|
||||
|
||||
func format(name string, num int, offset int) string {
|
||||
if num > 999 {
|
||||
// ignore deprecated syscalls that are no longer implemented
|
||||
// https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/unistd.h?id=refs/heads/master#n716
|
||||
return ""
|
||||
}
|
||||
name = strings.ToUpper(name)
|
||||
num = num + offset
|
||||
return fmt.Sprintf(" SYS_%s = %d;\n", name, num)
|
||||
}
|
||||
|
||||
func checkErr(err error) {
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// source string and substring slice for regexp
|
||||
type re struct {
|
||||
str string // source string
|
||||
sub []string // matched sub-string
|
||||
}
|
||||
|
||||
// Match performs regular expression match
|
||||
func (r *re) Match(exp string) bool {
|
||||
r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
|
||||
if r.sub != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Get the OS and architecture (using GOARCH_TARGET if it exists)
|
||||
goos = os.Getenv("GOOS")
|
||||
goarch = os.Getenv("GOARCH_TARGET")
|
||||
if goarch == "" {
|
||||
goarch = os.Getenv("GOARCH")
|
||||
}
|
||||
// Check if GOOS and GOARCH environment variables are defined
|
||||
if goarch == "" || goos == "" {
|
||||
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
// Check that we are using the new build system if we should
|
||||
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
|
||||
fmt.Fprintf(os.Stderr, "In the new build system, mksysnum should not be called directly.\n")
|
||||
fmt.Fprintf(os.Stderr, "See README.md\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cc := os.Getenv("CC")
|
||||
if cc == "" {
|
||||
fmt.Fprintf(os.Stderr, "CC is not defined in environment\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
args := os.Args[1:]
|
||||
args = append([]string{"-E", "-dD"}, args...)
|
||||
cmd, err := exec.Command(cc, args...).Output() // execute command and capture output
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "can't run %s", cc)
|
||||
os.Exit(1)
|
||||
}
|
||||
text := ""
|
||||
s := bufio.NewScanner(strings.NewReader(string(cmd)))
|
||||
var offset, prev int
|
||||
for s.Scan() {
|
||||
t := re{str: s.Text()}
|
||||
if t.Match(`^#define __NR_Linux\s+([0-9]+)`) {
|
||||
// mips/mips64: extract offset
|
||||
offset, _ = strconv.Atoi(t.sub[1]) // Make offset=0 if empty or non-numeric
|
||||
} else if t.Match(`^#define __NR(\w*)_SYSCALL_BASE\s+([0-9]+)`) {
|
||||
// arm: extract offset
|
||||
offset, _ = strconv.Atoi(t.sub[1]) // Make offset=0 if empty or non-numeric
|
||||
} else if t.Match(`^#define __NR_syscalls\s+`) {
|
||||
// ignore redefinitions of __NR_syscalls
|
||||
} else if t.Match(`^#define __NR_(\w*)Linux_syscalls\s+`) {
|
||||
// mips/mips64: ignore definitions about the number of syscalls
|
||||
} else if t.Match(`^#define __NR_(\w+)\s+([0-9]+)`) {
|
||||
prev, err = strconv.Atoi(t.sub[2])
|
||||
checkErr(err)
|
||||
text += format(t.sub[1], prev, offset)
|
||||
} else if t.Match(`^#define __NR3264_(\w+)\s+([0-9]+)`) {
|
||||
prev, err = strconv.Atoi(t.sub[2])
|
||||
checkErr(err)
|
||||
text += format(t.sub[1], prev, offset)
|
||||
} else if t.Match(`^#define __NR_(\w+)\s+\(\w+\+\s*([0-9]+)\)`) {
|
||||
r2, err := strconv.Atoi(t.sub[2])
|
||||
checkErr(err)
|
||||
text += format(t.sub[1], prev+r2, offset)
|
||||
} else if t.Match(`^#define __NR_(\w+)\s+\(__NR_(?:SYSCALL_BASE|Linux) \+ ([0-9]+)`) {
|
||||
r2, err := strconv.Atoi(t.sub[2])
|
||||
checkErr(err)
|
||||
text += format(t.sub[1], r2, offset)
|
||||
}
|
||||
}
|
||||
err = s.Err()
|
||||
checkErr(err)
|
||||
fmt.Printf(template, cmdLine(), buildTags(), text)
|
||||
}
|
||||
|
||||
const template = `// %s
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build %s
|
||||
|
||||
package unix
|
||||
|
||||
const(
|
||||
%s)`
|
1667
vendor/golang.org/x/sys/unix/linux/types.go
generated
vendored
1667
vendor/golang.org/x/sys/unix/linux/types.go
generated
vendored
File diff suppressed because it is too large
Load Diff
214
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
214
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
@ -1,214 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2009 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.
|
||||
|
||||
# This script runs or (given -n) prints suggested commands to generate files for
|
||||
# the Architecture/OS specified by the GOARCH and GOOS environment variables.
|
||||
# See README.md for more information about how the build system works.
|
||||
|
||||
GOOSARCH="${GOOS}_${GOARCH}"
|
||||
|
||||
# defaults
|
||||
mksyscall="go run mksyscall.go"
|
||||
mkerrors="./mkerrors.sh"
|
||||
zerrors="zerrors_$GOOSARCH.go"
|
||||
mksysctl=""
|
||||
zsysctl="zsysctl_$GOOSARCH.go"
|
||||
mksysnum=
|
||||
mktypes=
|
||||
mkasm=
|
||||
run="sh"
|
||||
cmd=""
|
||||
|
||||
case "$1" in
|
||||
-syscalls)
|
||||
for i in zsyscall*go
|
||||
do
|
||||
# Run the command line that appears in the first line
|
||||
# of the generated file to regenerate it.
|
||||
sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
|
||||
rm _$i
|
||||
done
|
||||
exit 0
|
||||
;;
|
||||
-n)
|
||||
run="cat"
|
||||
cmd="echo"
|
||||
shift
|
||||
esac
|
||||
|
||||
case "$#" in
|
||||
0)
|
||||
;;
|
||||
*)
|
||||
echo 'usage: mkall.sh [-n]' 1>&2
|
||||
exit 2
|
||||
esac
|
||||
|
||||
if [[ "$GOOS" = "linux" ]]; then
|
||||
# Use the Docker-based build system
|
||||
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
|
||||
$cmd docker build --tag generate:$GOOS $GOOS
|
||||
$cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS
|
||||
exit
|
||||
fi
|
||||
|
||||
GOOSARCH_in=syscall_$GOOSARCH.go
|
||||
case "$GOOSARCH" in
|
||||
_* | *_ | _)
|
||||
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
aix_ppc)
|
||||
mkerrors="$mkerrors -maix32"
|
||||
mksyscall="go run mksyscall_aix_ppc.go -aix"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
aix_ppc64)
|
||||
mkerrors="$mkerrors -maix64"
|
||||
mksyscall="./mksyscall_aix_ppc64.pl -aix"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
darwin_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="go run mksyscall.go -l32"
|
||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
;;
|
||||
darwin_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
;;
|
||||
darwin_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="go run mksyscall.go -l32"
|
||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
;;
|
||||
darwin_arm64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
;;
|
||||
dragonfly_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="go run mksyscall.go -dragonfly"
|
||||
mksysnum="go run mksysnum.go 'https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
freebsd_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="go run mksyscall.go -l32"
|
||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
freebsd_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
freebsd_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="go run mksyscall.go -l32 -arm"
|
||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
|
||||
# Let the type of C char be signed for making the bare syscall
|
||||
# API consistent across platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
freebsd_arm64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
netbsd_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="go run mksyscall.go -l32 -netbsd"
|
||||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
netbsd_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="go run mksyscall.go -netbsd"
|
||||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
netbsd_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="go run mksyscall.go -l32 -netbsd -arm"
|
||||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
|
||||
# Let the type of C char be signed for making the bare syscall
|
||||
# API consistent across platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
openbsd_386)
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="go run mksyscall.go -l32 -openbsd"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
openbsd_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="go run mksyscall.go -openbsd"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
openbsd_arm)
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="go run mksyscall.go -l32 -openbsd -arm"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
||||
# Let the type of C char be signed for making the bare syscall
|
||||
# API consistent across platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
solaris_amd64)
|
||||
mksyscall="./mksyscall_solaris.pl"
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksysnum=
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
*)
|
||||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
(
|
||||
if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
|
||||
case "$GOOS" in
|
||||
*)
|
||||
syscall_goos="syscall_$GOOS.go"
|
||||
case "$GOOS" in
|
||||
darwin | dragonfly | freebsd | netbsd | openbsd)
|
||||
syscall_goos="syscall_bsd.go $syscall_goos"
|
||||
;;
|
||||
esac
|
||||
if [ -n "$mksyscall" ]; then
|
||||
if [ "$GOOSARCH" == "aix_ppc64" ]; then
|
||||
# aix/ppc64 script generates files instead of writing to stdin.
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
|
||||
elif [ "$GOOS" == "darwin" ]; then
|
||||
# pre-1.12, direct syscalls
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH,!go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.1_11.go";
|
||||
# 1.12 and later, syscalls via libSystem
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
||||
else
|
||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
||||
fi
|
||||
fi
|
||||
esac
|
||||
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
|
||||
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
|
||||
if [ -n "$mktypes" ]; then
|
||||
echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go";
|
||||
if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
|
||||
fi
|
||||
) | $run
|
665
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
665
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
@ -1,665 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2009 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.
|
||||
|
||||
# Generate Go code listing errors and other #defined constant
|
||||
# values (ENAMETOOLONG etc.), by asking the preprocessor
|
||||
# about the definitions.
|
||||
|
||||
unset LANG
|
||||
export LC_ALL=C
|
||||
export LC_CTYPE=C
|
||||
|
||||
if test -z "$GOARCH" -o -z "$GOOS"; then
|
||||
echo 1>&2 "GOARCH or GOOS not defined in environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check that we are using the new build system if we should
|
||||
if [[ "$GOOS" = "linux" ]] && [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then
|
||||
echo 1>&2 "In the Docker based build system, mkerrors should not be called directly."
|
||||
echo 1>&2 "See README.md"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$GOOS" = "aix" ]]; then
|
||||
CC=${CC:-gcc}
|
||||
else
|
||||
CC=${CC:-cc}
|
||||
fi
|
||||
|
||||
if [[ "$GOOS" = "solaris" ]]; then
|
||||
# Assumes GNU versions of utilities in PATH.
|
||||
export PATH=/usr/gnu/bin:$PATH
|
||||
fi
|
||||
|
||||
uname=$(uname)
|
||||
|
||||
includes_AIX='
|
||||
#include <net/if.h>
|
||||
#include <net/netopt.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/stropts.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/termio.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define AF_LOCAL AF_UNIX
|
||||
'
|
||||
|
||||
includes_Darwin='
|
||||
#define _DARWIN_C_SOURCE
|
||||
#define KERNEL
|
||||
#define _DARWIN_USE_64_BIT_INODE
|
||||
#include <stdint.h>
|
||||
#include <sys/attr.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <termios.h>
|
||||
'
|
||||
|
||||
includes_DragonFly='
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <net/ip_mroute/ip_mroute.h>
|
||||
'
|
||||
|
||||
includes_FreeBSD='
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
#include <sys/extattr.h>
|
||||
|
||||
#if __FreeBSD__ >= 10
|
||||
#define IFT_CARP 0xf8 // IFT_CARP is deprecated in FreeBSD 10
|
||||
#undef SIOCAIFADDR
|
||||
#define SIOCAIFADDR _IOW(105, 26, struct oifaliasreq) // ifaliasreq contains if_data
|
||||
#undef SIOCSIFPHYADDR
|
||||
#define SIOCSIFPHYADDR _IOW(105, 70, struct oifaliasreq) // ifaliasreq contains if_data
|
||||
#endif
|
||||
'
|
||||
|
||||
includes_Linux='
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#ifndef __LP64__
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
#define _GNU_SOURCE
|
||||
|
||||
// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of
|
||||
// these structures. We just include them copied from <bits/termios.h>.
|
||||
#if defined(__powerpc__)
|
||||
struct sgttyb {
|
||||
char sg_ispeed;
|
||||
char sg_ospeed;
|
||||
char sg_erase;
|
||||
char sg_kill;
|
||||
short sg_flags;
|
||||
};
|
||||
|
||||
struct tchars {
|
||||
char t_intrc;
|
||||
char t_quitc;
|
||||
char t_startc;
|
||||
char t_stopc;
|
||||
char t_eofc;
|
||||
char t_brkc;
|
||||
};
|
||||
|
||||
struct ltchars {
|
||||
char t_suspc;
|
||||
char t_dsuspc;
|
||||
char t_rprntc;
|
||||
char t_flushc;
|
||||
char t_werasc;
|
||||
char t_lnextc;
|
||||
};
|
||||
#endif
|
||||
|
||||
#include <bits/sockaddr.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_alg.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_ppp.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/falloc.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/keyctl.h>
|
||||
#include <linux/magic.h>
|
||||
#include <linux/memfd.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/net_namespace.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/icmpv6.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/vm_sockets.h>
|
||||
#include <linux/taskstats.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/if_xdp.h>
|
||||
#include <mtd/ubi-user.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#if defined(__sparc__)
|
||||
// On sparc{,64}, the kernel defines struct termios2 itself which clashes with the
|
||||
// definition in glibc. As only the error constants are needed here, include the
|
||||
// generic termibits.h (which is included by termbits.h on sparc).
|
||||
#include <asm-generic/termbits.h>
|
||||
#else
|
||||
#include <asm/termbits.h>
|
||||
#endif
|
||||
|
||||
#ifndef MSG_FASTOPEN
|
||||
#define MSG_FASTOPEN 0x20000000
|
||||
#endif
|
||||
|
||||
#ifndef PTRACE_GETREGS
|
||||
#define PTRACE_GETREGS 0xc
|
||||
#endif
|
||||
|
||||
#ifndef PTRACE_SETREGS
|
||||
#define PTRACE_SETREGS 0xd
|
||||
#endif
|
||||
|
||||
#ifndef SOL_NETLINK
|
||||
#define SOL_NETLINK 270
|
||||
#endif
|
||||
|
||||
#ifdef SOL_BLUETOOTH
|
||||
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
|
||||
// but it is already in bluetooth_linux.go
|
||||
#undef SOL_BLUETOOTH
|
||||
#endif
|
||||
|
||||
// Certain constants are missing from the fs/crypto UAPI
|
||||
#define FS_KEY_DESC_PREFIX "fscrypt:"
|
||||
#define FS_KEY_DESC_PREFIX_SIZE 8
|
||||
#define FS_MAX_KEY_SIZE 64
|
||||
|
||||
// XDP socket constants do not appear to be picked up otherwise.
|
||||
// Copied from samples/bpf/xdpsock_user.c.
|
||||
#ifndef SOL_XDP
|
||||
#define SOL_XDP 283
|
||||
#endif
|
||||
|
||||
#ifndef AF_XDP
|
||||
#define AF_XDP 44
|
||||
#endif
|
||||
'
|
||||
|
||||
includes_NetBSD='
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/extattr.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <sys/wait.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
// Needed since <sys/param.h> refers to it...
|
||||
#define schedppq 1
|
||||
'
|
||||
|
||||
includes_OpenBSD='
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <net/if_bridge.h>
|
||||
|
||||
// We keep some constants not supported in OpenBSD 5.5 and beyond for
|
||||
// the promise of compatibility.
|
||||
#define EMUL_ENABLED 0x1
|
||||
#define EMUL_NATIVE 0x2
|
||||
#define IPV6_FAITH 0x1d
|
||||
#define IPV6_OPTIONS 0x1
|
||||
#define IPV6_RTHDR_STRICT 0x1
|
||||
#define IPV6_SOCKOPT_RESERVED1 0x3
|
||||
#define SIOCGIFGENERIC 0xc020693a
|
||||
#define SIOCSIFGENERIC 0x80206939
|
||||
#define WALTSIG 0x4
|
||||
'
|
||||
|
||||
includes_SunOS='
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mkdev.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
'
|
||||
|
||||
|
||||
includes='
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <errno.h>
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <sys/resource.h>
|
||||
#include <time.h>
|
||||
'
|
||||
ccflags="$@"
|
||||
|
||||
# Write go tool cgo -godefs input.
|
||||
(
|
||||
echo package unix
|
||||
echo
|
||||
echo '/*'
|
||||
indirect="includes_$(uname)"
|
||||
echo "${!indirect} $includes"
|
||||
echo '*/'
|
||||
echo 'import "C"'
|
||||
echo 'import "syscall"'
|
||||
echo
|
||||
echo 'const ('
|
||||
|
||||
# The gcc command line prints all the #defines
|
||||
# it encounters while processing the input
|
||||
echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
|
||||
awk '
|
||||
$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
|
||||
|
||||
$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
|
||||
$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
|
||||
$2 ~ /^(SCM_SRCRT)$/ {next}
|
||||
$2 ~ /^(MAP_FAILED)$/ {next}
|
||||
$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.
|
||||
|
||||
$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
|
||||
$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}
|
||||
|
||||
$2 !~ /^ECCAPBITS/ &&
|
||||
$2 !~ /^ETH_/ &&
|
||||
$2 !~ /^EPROC_/ &&
|
||||
$2 !~ /^EQUIV_/ &&
|
||||
$2 !~ /^EXPR_/ &&
|
||||
$2 ~ /^E[A-Z0-9_]+$/ ||
|
||||
$2 ~ /^B[0-9_]+$/ ||
|
||||
$2 ~ /^(OLD|NEW)DEV$/ ||
|
||||
$2 == "BOTHER" ||
|
||||
$2 ~ /^CI?BAUD(EX)?$/ ||
|
||||
$2 == "IBSHIFT" ||
|
||||
$2 ~ /^V[A-Z0-9]+$/ ||
|
||||
$2 ~ /^CS[A-Z0-9]/ ||
|
||||
$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
|
||||
$2 ~ /^IGN/ ||
|
||||
$2 ~ /^IX(ON|ANY|OFF)$/ ||
|
||||
$2 ~ /^IN(LCR|PCK)$/ ||
|
||||
$2 !~ "X86_CR3_PCID_NOFLUSH" &&
|
||||
$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
|
||||
$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
|
||||
$2 == "BRKINT" ||
|
||||
$2 == "HUPCL" ||
|
||||
$2 == "PENDIN" ||
|
||||
$2 == "TOSTOP" ||
|
||||
$2 == "XCASE" ||
|
||||
$2 == "ALTWERASE" ||
|
||||
$2 == "NOKERNINFO" ||
|
||||
$2 ~ /^PAR/ ||
|
||||
$2 ~ /^SIG[^_]/ ||
|
||||
$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
|
||||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
|
||||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
|
||||
$2 ~ /^O?XTABS$/ ||
|
||||
$2 ~ /^TC[IO](ON|OFF)$/ ||
|
||||
$2 ~ /^IN_/ ||
|
||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
||||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
|
||||
$2 ~ /^TP_STATUS_/ ||
|
||||
$2 ~ /^FALLOC_/ ||
|
||||
$2 == "ICMPV6_FILTER" ||
|
||||
$2 == "SOMAXCONN" ||
|
||||
$2 == "NAME_MAX" ||
|
||||
$2 == "IFNAMSIZ" ||
|
||||
$2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
|
||||
$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
|
||||
$2 ~ /^HW_MACHINE$/ ||
|
||||
$2 ~ /^SYSCTL_VERS/ ||
|
||||
$2 !~ "MNT_BITS" &&
|
||||
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
|
||||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
||||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT)_/ ||
|
||||
$2 ~ /^KEXEC_/ ||
|
||||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
|
||||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
|
||||
$2 ~ /^MODULE_INIT_/ ||
|
||||
$2 !~ "NLA_TYPE_MASK" &&
|
||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
|
||||
$2 ~ /^SIOC/ ||
|
||||
$2 ~ /^TIOC/ ||
|
||||
$2 ~ /^TCGET/ ||
|
||||
$2 ~ /^TCSET/ ||
|
||||
$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
|
||||
$2 !~ "RTF_BITS" &&
|
||||
$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
|
||||
$2 ~ /^BIOC/ ||
|
||||
$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
|
||||
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
|
||||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
|
||||
$2 ~ /^CLONE_[A-Z_]+/ ||
|
||||
$2 !~ /^(BPF_TIMEVAL)$/ &&
|
||||
$2 ~ /^(BPF|DLT)_/ ||
|
||||
$2 ~ /^(CLOCK|TIMER)_/ ||
|
||||
$2 ~ /^CAN_/ ||
|
||||
$2 ~ /^CAP_/ ||
|
||||
$2 ~ /^ALG_/ ||
|
||||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
|
||||
$2 ~ /^GRND_/ ||
|
||||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
||||
$2 ~ /^KEYCTL_/ ||
|
||||
$2 ~ /^PERF_EVENT_IOC_/ ||
|
||||
$2 ~ /^SECCOMP_MODE_/ ||
|
||||
$2 ~ /^SPLICE_/ ||
|
||||
$2 ~ /^SYNC_FILE_RANGE_/ ||
|
||||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
|
||||
$2 !~ /IOC_MAGIC/ &&
|
||||
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
|
||||
$2 ~ /^(VM|VMADDR)_/ ||
|
||||
$2 ~ /^IOCTL_VM_SOCKETS_/ ||
|
||||
$2 ~ /^(TASKSTATS|TS)_/ ||
|
||||
$2 ~ /^CGROUPSTATS_/ ||
|
||||
$2 ~ /^GENL_/ ||
|
||||
$2 ~ /^STATX_/ ||
|
||||
$2 ~ /^RENAME/ ||
|
||||
$2 ~ /^UBI_IOC[A-Z]/ ||
|
||||
$2 ~ /^UTIME_/ ||
|
||||
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
|
||||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
|
||||
$2 ~ /^FSOPT_/ ||
|
||||
$2 ~ /^WDIOC_/ ||
|
||||
$2 ~ /^NFN/ ||
|
||||
$2 ~ /^XDP_/ ||
|
||||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
||||
$2 !~ "WMESGLEN" &&
|
||||
$2 ~ /^W[A-Z0-9]+$/ ||
|
||||
$2 ~/^PPPIOC/ ||
|
||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
|
||||
$2 ~ /^__WCOREFLAG$/ {next}
|
||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
|
||||
|
||||
{next}
|
||||
' | sort
|
||||
|
||||
echo ')'
|
||||
) >_const.go
|
||||
|
||||
# Pull out the error names for later.
|
||||
errors=$(
|
||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
|
||||
sort
|
||||
)
|
||||
|
||||
# Pull out the signal names for later.
|
||||
signals=$(
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
||||
sort
|
||||
)
|
||||
|
||||
# Again, writing regexps to a file.
|
||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||
sort >_error.grep
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
||||
sort >_signal.grep
|
||||
|
||||
echo '// mkerrors.sh' "$@"
|
||||
echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
|
||||
echo
|
||||
echo "// +build ${GOARCH},${GOOS}"
|
||||
echo
|
||||
go tool cgo -godefs -- "$@" _const.go >_error.out
|
||||
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
|
||||
echo
|
||||
echo '// Errors'
|
||||
echo 'const ('
|
||||
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
|
||||
echo ')'
|
||||
|
||||
echo
|
||||
echo '// Signals'
|
||||
echo 'const ('
|
||||
cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
|
||||
echo ')'
|
||||
|
||||
# Run C program to print error and syscall strings.
|
||||
(
|
||||
echo -E "
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
|
||||
|
||||
struct tuple {
|
||||
int num;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct tuple errors[] = {
|
||||
"
|
||||
for i in $errors
|
||||
do
|
||||
echo -E ' {'$i', "'$i'" },'
|
||||
done
|
||||
|
||||
echo -E "
|
||||
};
|
||||
|
||||
struct tuple signals[] = {
|
||||
"
|
||||
for i in $signals
|
||||
do
|
||||
echo -E ' {'$i', "'$i'" },'
|
||||
done
|
||||
|
||||
# Use -E because on some systems bash builtin interprets \n itself.
|
||||
echo -E '
|
||||
};
|
||||
|
||||
static int
|
||||
tuplecmp(const void *a, const void *b)
|
||||
{
|
||||
return ((struct tuple *)a)->num - ((struct tuple *)b)->num;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int i, e;
|
||||
char buf[1024], *p;
|
||||
|
||||
printf("\n\n// Error table\n");
|
||||
printf("var errorList = [...]struct {\n");
|
||||
printf("\tnum syscall.Errno\n");
|
||||
printf("\tname string\n");
|
||||
printf("\tdesc string\n");
|
||||
printf("} {\n");
|
||||
qsort(errors, nelem(errors), sizeof errors[0], tuplecmp);
|
||||
for(i=0; i<nelem(errors); i++) {
|
||||
e = errors[i].num;
|
||||
if(i > 0 && errors[i-1].num == e)
|
||||
continue;
|
||||
strcpy(buf, strerror(e));
|
||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
||||
buf[0] += a - A;
|
||||
printf("\t{ %d, \"%s\", \"%s\" },\n", e, errors[i].name, buf);
|
||||
}
|
||||
printf("}\n\n");
|
||||
|
||||
printf("\n\n// Signal table\n");
|
||||
printf("var signalList = [...]struct {\n");
|
||||
printf("\tnum syscall.Signal\n");
|
||||
printf("\tname string\n");
|
||||
printf("\tdesc string\n");
|
||||
printf("} {\n");
|
||||
qsort(signals, nelem(signals), sizeof signals[0], tuplecmp);
|
||||
for(i=0; i<nelem(signals); i++) {
|
||||
e = signals[i].num;
|
||||
if(i > 0 && signals[i-1].num == e)
|
||||
continue;
|
||||
strcpy(buf, strsignal(e));
|
||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
||||
buf[0] += a - A;
|
||||
// cut trailing : number.
|
||||
p = strrchr(buf, ":"[0]);
|
||||
if(p)
|
||||
*p = '\0';
|
||||
printf("\t{ %d, \"%s\", \"%s\" },\n", e, signals[i].name, buf);
|
||||
}
|
||||
printf("}\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
'
|
||||
) >_errors.c
|
||||
|
||||
$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
|
579
vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl
generated
vendored
579
vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl
generated
vendored
@ -1,579 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright 2018 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.
|
||||
|
||||
# This program reads a file containing function prototypes
|
||||
# (like syscall_aix.go) and generates system call bodies.
|
||||
# The prototypes are marked by lines beginning with "//sys"
|
||||
# and read like func declarations if //sys is replaced by func, but:
|
||||
# * The parameter lists must give a name for each argument.
|
||||
# This includes return parameters.
|
||||
# * The parameter lists must give a type for each argument:
|
||||
# the (x, y, z int) shorthand is not allowed.
|
||||
# * If the return parameter is an error number, it must be named err.
|
||||
# * If go func name needs to be different than its libc name,
|
||||
# * or the function is not in libc, name could be specified
|
||||
# * at the end, after "=" sign, like
|
||||
# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
||||
|
||||
# This program will generate three files and handle both gc and gccgo implementation:
|
||||
# - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation)
|
||||
# - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6
|
||||
# - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type.
|
||||
|
||||
# The generated code looks like this
|
||||
#
|
||||
# zsyscall_aix_ppc64.go
|
||||
# func asyscall(...) (n int, err error) {
|
||||
# // Pointer Creation
|
||||
# r1, e1 := callasyscall(...)
|
||||
# // Type Conversion
|
||||
# // Error Handler
|
||||
# return
|
||||
# }
|
||||
#
|
||||
# zsyscall_aix_ppc64_gc.go
|
||||
# //go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o"
|
||||
# //go:linkname libc_asyscall libc_asyscall
|
||||
# var asyscall syscallFunc
|
||||
#
|
||||
# func callasyscall(...) (r1 uintptr, e1 Errno) {
|
||||
# r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
|
||||
# return
|
||||
# }
|
||||
#
|
||||
# zsyscall_aix_ppc64_ggcgo.go
|
||||
# /*
|
||||
# int asyscall(...)
|
||||
#
|
||||
# */
|
||||
# import "C"
|
||||
#
|
||||
# func callasyscall(...) (r1 uintptr, e1 Errno) {
|
||||
# r1 = uintptr(C.asyscall(...))
|
||||
# e1 = syscall.GetErrno()
|
||||
# return
|
||||
# }
|
||||
|
||||
|
||||
|
||||
use strict;
|
||||
|
||||
my $cmdline = "mksyscall_aix_ppc64.pl " . join(' ', @ARGV);
|
||||
my $errors = 0;
|
||||
my $_32bit = "";
|
||||
my $tags = ""; # build tags
|
||||
my $aix = 0;
|
||||
my $solaris = 0;
|
||||
|
||||
binmode STDOUT;
|
||||
|
||||
if($ARGV[0] eq "-b32") {
|
||||
$_32bit = "big-endian";
|
||||
shift;
|
||||
} elsif($ARGV[0] eq "-l32") {
|
||||
$_32bit = "little-endian";
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-aix") {
|
||||
$aix = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-tags") {
|
||||
shift;
|
||||
$tags = $ARGV[0];
|
||||
shift;
|
||||
}
|
||||
|
||||
if($ARGV[0] =~ /^-/) {
|
||||
print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub parseparamlist($) {
|
||||
my ($list) = @_;
|
||||
$list =~ s/^\s*//;
|
||||
$list =~ s/\s*$//;
|
||||
if($list eq "") {
|
||||
return ();
|
||||
}
|
||||
return split(/\s*,\s*/, $list);
|
||||
}
|
||||
|
||||
sub parseparam($) {
|
||||
my ($p) = @_;
|
||||
if($p !~ /^(\S*) (\S*)$/) {
|
||||
print STDERR "$ARGV:$.: malformed parameter: $p\n";
|
||||
$errors = 1;
|
||||
return ("xx", "int");
|
||||
}
|
||||
return ($1, $2);
|
||||
}
|
||||
|
||||
my $package = "";
|
||||
# GCCGO
|
||||
my $textgccgo = "";
|
||||
my $c_extern = "/*\n#include <stdint.h>\n";
|
||||
# GC
|
||||
my $textgc = "";
|
||||
my $dynimports = "";
|
||||
my $linknames = "";
|
||||
my @vars = ();
|
||||
# COMMUN
|
||||
my $textcommon = "";
|
||||
|
||||
while(<>) {
|
||||
chomp;
|
||||
s/\s+/ /g;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
$package = $1 if !$package && /^package (\S+)$/;
|
||||
my $nonblock = /^\/\/sysnb /;
|
||||
next if !/^\/\/sys / && !$nonblock;
|
||||
|
||||
# Line must be of the form
|
||||
# func Open(path string, mode int, perm int) (fd int, err error)
|
||||
# Split into name, in params, out params.
|
||||
if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
|
||||
print STDERR "$ARGV:$.: malformed //sys declaration\n";
|
||||
$errors = 1;
|
||||
next;
|
||||
}
|
||||
my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
|
||||
|
||||
# Split argument lists on comma.
|
||||
my @in = parseparamlist($in);
|
||||
my @out = parseparamlist($out);
|
||||
|
||||
$in = join(', ', @in);
|
||||
$out = join(', ', @out);
|
||||
|
||||
if($sysname eq "") {
|
||||
$sysname = "$func";
|
||||
}
|
||||
|
||||
my $onlyCommon = 0;
|
||||
if ($func eq "readlen" || $func eq "writelen" || $func eq "FcntlInt" || $func eq "FcntlFlock") {
|
||||
# This function call another syscall which is already implemented.
|
||||
# Therefore, the gc and gccgo part must not be generated.
|
||||
$onlyCommon = 1
|
||||
}
|
||||
|
||||
# Try in vain to keep people from editing this file.
|
||||
# The theory is that they jump into the middle of the file
|
||||
# without reading the header.
|
||||
|
||||
$textcommon .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
|
||||
if (!$onlyCommon) {
|
||||
$textgccgo .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
|
||||
$textgc .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
|
||||
}
|
||||
|
||||
|
||||
# Check if value return, err return available
|
||||
my $errvar = "";
|
||||
my $retvar = "";
|
||||
my $rettype = "";
|
||||
foreach my $p (@out) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type eq "error") {
|
||||
$errvar = $name;
|
||||
} else {
|
||||
$retvar = $name;
|
||||
$rettype = $type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g;
|
||||
$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
|
||||
|
||||
# GCCGO Prototype return type
|
||||
my $C_rettype = "";
|
||||
if($rettype eq "unsafe.Pointer") {
|
||||
$C_rettype = "uintptr_t";
|
||||
} elsif($rettype eq "uintptr") {
|
||||
$C_rettype = "uintptr_t";
|
||||
} elsif($rettype =~ /^_/) {
|
||||
$C_rettype = "uintptr_t";
|
||||
} elsif($rettype eq "int") {
|
||||
$C_rettype = "int";
|
||||
} elsif($rettype eq "int32") {
|
||||
$C_rettype = "int";
|
||||
} elsif($rettype eq "int64") {
|
||||
$C_rettype = "long long";
|
||||
} elsif($rettype eq "uint32") {
|
||||
$C_rettype = "unsigned int";
|
||||
} elsif($rettype eq "uint64") {
|
||||
$C_rettype = "unsigned long long";
|
||||
} else {
|
||||
$C_rettype = "int";
|
||||
}
|
||||
if($sysname eq "exit") {
|
||||
$C_rettype = "void";
|
||||
}
|
||||
|
||||
# GCCGO Prototype arguments type
|
||||
my @c_in = ();
|
||||
foreach my $i (0 .. $#in) {
|
||||
my ($name, $type) = parseparam($in[$i]);
|
||||
if($type =~ /^\*/) {
|
||||
push @c_in, "uintptr_t";
|
||||
} elsif($type eq "string") {
|
||||
push @c_in, "uintptr_t";
|
||||
} elsif($type =~ /^\[\](.*)/) {
|
||||
push @c_in, "uintptr_t", "size_t";
|
||||
} elsif($type eq "unsafe.Pointer") {
|
||||
push @c_in, "uintptr_t";
|
||||
} elsif($type eq "uintptr") {
|
||||
push @c_in, "uintptr_t";
|
||||
} elsif($type =~ /^_/) {
|
||||
push @c_in, "uintptr_t";
|
||||
} elsif($type eq "int") {
|
||||
if (($i == 0 || $i == 2) && $func eq "fcntl"){
|
||||
# These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
|
||||
push @c_in, "uintptr_t";
|
||||
} else {
|
||||
push @c_in, "int";
|
||||
}
|
||||
} elsif($type eq "int32") {
|
||||
push @c_in, "int";
|
||||
} elsif($type eq "int64") {
|
||||
push @c_in, "long long";
|
||||
} elsif($type eq "uint32") {
|
||||
push @c_in, "unsigned int";
|
||||
} elsif($type eq "uint64") {
|
||||
push @c_in, "unsigned long long";
|
||||
} else {
|
||||
push @c_in, "int";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$onlyCommon){
|
||||
# GCCGO Prototype Generation
|
||||
# Imports of system calls from libc
|
||||
$c_extern .= "$C_rettype $sysname";
|
||||
my $c_in = join(', ', @c_in);
|
||||
$c_extern .= "($c_in);\n";
|
||||
}
|
||||
|
||||
# GC Library name
|
||||
if($modname eq "") {
|
||||
$modname = "libc.a/shr_64.o";
|
||||
} else {
|
||||
print STDERR "$func: only syscall using libc are available\n";
|
||||
$errors = 1;
|
||||
next;
|
||||
}
|
||||
my $sysvarname = "libc_${sysname}";
|
||||
|
||||
if (!$onlyCommon){
|
||||
# GC Runtime import of function to allow cross-platform builds.
|
||||
$dynimports .= "//go:cgo_import_dynamic ${sysvarname} ${sysname} \"$modname\"\n";
|
||||
# GC Link symbol to proc address variable.
|
||||
$linknames .= "//go:linkname ${sysvarname} ${sysvarname}\n";
|
||||
# GC Library proc address variable.
|
||||
push @vars, $sysvarname;
|
||||
}
|
||||
|
||||
my $strconvfunc ="BytePtrFromString";
|
||||
my $strconvtype = "*byte";
|
||||
|
||||
# Go function header.
|
||||
if($out ne "") {
|
||||
$out = " ($out)";
|
||||
}
|
||||
if($textcommon ne "") {
|
||||
$textcommon .= "\n"
|
||||
}
|
||||
|
||||
$textcommon .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ;
|
||||
|
||||
# Prepare arguments to call.
|
||||
my @argscommun = (); # Arguments in the commun part
|
||||
my @argscall = (); # Arguments for call prototype
|
||||
my @argsgc = (); # Arguments for gc call (with syscall6)
|
||||
my @argsgccgo = (); # Arguments for gccgo call (with C.name_of_syscall)
|
||||
my $n = 0;
|
||||
my $arg_n = 0;
|
||||
foreach my $p (@in) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type =~ /^\*/) {
|
||||
push @argscommun, "uintptr(unsafe.Pointer($name))";
|
||||
push @argscall, "$name uintptr";
|
||||
push @argsgc, "$name";
|
||||
push @argsgccgo, "C.uintptr_t($name)";
|
||||
} elsif($type eq "string" && $errvar ne "") {
|
||||
$textcommon .= "\tvar _p$n $strconvtype\n";
|
||||
$textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n";
|
||||
$textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
|
||||
|
||||
push @argscommun, "uintptr(unsafe.Pointer(_p$n))";
|
||||
push @argscall, "_p$n uintptr ";
|
||||
push @argsgc, "_p$n";
|
||||
push @argsgccgo, "C.uintptr_t(_p$n)";
|
||||
$n++;
|
||||
} elsif($type eq "string") {
|
||||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
|
||||
$textcommon .= "\tvar _p$n $strconvtype\n";
|
||||
$textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n";
|
||||
$textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
|
||||
|
||||
push @argscommun, "uintptr(unsafe.Pointer(_p$n))";
|
||||
push @argscall, "_p$n uintptr";
|
||||
push @argsgc, "_p$n";
|
||||
push @argsgccgo, "C.uintptr_t(_p$n)";
|
||||
$n++;
|
||||
} elsif($type =~ /^\[\](.*)/) {
|
||||
# Convert slice into pointer, length.
|
||||
# Have to be careful not to take address of &a[0] if len == 0:
|
||||
# pass nil in that case.
|
||||
$textcommon .= "\tvar _p$n *$1\n";
|
||||
$textcommon .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
|
||||
push @argscommun, "uintptr(unsafe.Pointer(_p$n))", "len($name)";
|
||||
push @argscall, "_p$n uintptr", "_lenp$n int";
|
||||
push @argsgc, "_p$n", "uintptr(_lenp$n)";
|
||||
push @argsgccgo, "C.uintptr_t(_p$n)", "C.size_t(_lenp$n)";
|
||||
$n++;
|
||||
} elsif($type eq "int64" && $_32bit ne "") {
|
||||
print STDERR "$ARGV:$.: $func uses int64 with 32 bits mode. Case not yet implemented\n";
|
||||
# if($_32bit eq "big-endian") {
|
||||
# push @args, "uintptr($name >> 32)", "uintptr($name)";
|
||||
# } else {
|
||||
# push @args, "uintptr($name)", "uintptr($name >> 32)";
|
||||
# }
|
||||
# $n++;
|
||||
} elsif($type eq "bool") {
|
||||
print STDERR "$ARGV:$.: $func uses bool. Case not yet implemented\n";
|
||||
# $text .= "\tvar _p$n uint32\n";
|
||||
# $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
|
||||
# push @args, "_p$n";
|
||||
# $n++;
|
||||
} elsif($type =~ /^_/ ||$type eq "unsafe.Pointer") {
|
||||
push @argscommun, "uintptr($name)";
|
||||
push @argscall, "$name uintptr";
|
||||
push @argsgc, "$name";
|
||||
push @argsgccgo, "C.uintptr_t($name)";
|
||||
} elsif($type eq "int") {
|
||||
if (($arg_n == 0 || $arg_n == 2) && ($func eq "fcntl" || $func eq "FcntlInt" || $func eq "FcntlFlock")) {
|
||||
# These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
|
||||
push @argscommun, "uintptr($name)";
|
||||
push @argscall, "$name uintptr";
|
||||
push @argsgc, "$name";
|
||||
push @argsgccgo, "C.uintptr_t($name)";
|
||||
} else {
|
||||
push @argscommun, "$name";
|
||||
push @argscall, "$name int";
|
||||
push @argsgc, "uintptr($name)";
|
||||
push @argsgccgo, "C.int($name)";
|
||||
}
|
||||
} elsif($type eq "int32") {
|
||||
push @argscommun, "$name";
|
||||
push @argscall, "$name int32";
|
||||
push @argsgc, "uintptr($name)";
|
||||
push @argsgccgo, "C.int($name)";
|
||||
} elsif($type eq "int64") {
|
||||
push @argscommun, "$name";
|
||||
push @argscall, "$name int64";
|
||||
push @argsgc, "uintptr($name)";
|
||||
push @argsgccgo, "C.longlong($name)";
|
||||
} elsif($type eq "uint32") {
|
||||
push @argscommun, "$name";
|
||||
push @argscall, "$name uint32";
|
||||
push @argsgc, "uintptr($name)";
|
||||
push @argsgccgo, "C.uint($name)";
|
||||
} elsif($type eq "uint64") {
|
||||
push @argscommun, "$name";
|
||||
push @argscall, "$name uint64";
|
||||
push @argsgc, "uintptr($name)";
|
||||
push @argsgccgo, "C.ulonglong($name)";
|
||||
} elsif($type eq "uintptr") {
|
||||
push @argscommun, "$name";
|
||||
push @argscall, "$name uintptr";
|
||||
push @argsgc, "$name";
|
||||
push @argsgccgo, "C.uintptr_t($name)";
|
||||
} else {
|
||||
push @argscommun, "int($name)";
|
||||
push @argscall, "$name int";
|
||||
push @argsgc, "uintptr($name)";
|
||||
push @argsgccgo, "C.int($name)";
|
||||
}
|
||||
$arg_n++;
|
||||
}
|
||||
my $nargs = @argsgc;
|
||||
|
||||
# COMMUN function generation
|
||||
my $argscommun = join(', ', @argscommun);
|
||||
my $callcommun = "call$sysname($argscommun)";
|
||||
my @ret = ("_", "_");
|
||||
my $body = "";
|
||||
my $do_errno = 0;
|
||||
for(my $i=0; $i<@out; $i++) {
|
||||
my $p = $out[$i];
|
||||
my ($name, $type) = parseparam($p);
|
||||
my $reg = "";
|
||||
if($name eq "err") {
|
||||
$reg = "e1";
|
||||
$ret[1] = $reg;
|
||||
$do_errno = 1;
|
||||
} else {
|
||||
$reg = "r0";
|
||||
$ret[0] = $reg;
|
||||
}
|
||||
if($type eq "bool") {
|
||||
$reg = "$reg != 0";
|
||||
}
|
||||
if($reg ne "e1") {
|
||||
$body .= "\t$name = $type($reg)\n";
|
||||
}
|
||||
}
|
||||
if ($ret[0] eq "_" && $ret[1] eq "_") {
|
||||
$textcommon .= "\t$callcommun\n";
|
||||
} else {
|
||||
$textcommon .= "\t$ret[0], $ret[1] := $callcommun\n";
|
||||
}
|
||||
$textcommon .= $body;
|
||||
|
||||
if ($do_errno) {
|
||||
$textcommon .= "\tif e1 != 0 {\n";
|
||||
$textcommon .= "\t\terr = errnoErr(e1)\n";
|
||||
$textcommon .= "\t}\n";
|
||||
}
|
||||
$textcommon .= "\treturn\n";
|
||||
$textcommon .= "}\n";
|
||||
|
||||
if ($onlyCommon){
|
||||
next
|
||||
}
|
||||
# CALL Prototype
|
||||
my $callProto = sprintf "func call%s(%s) (r1 uintptr, e1 Errno) {\n", $sysname, join(', ', @argscall);
|
||||
|
||||
# GC function generation
|
||||
my $asm = "syscall6";
|
||||
if ($nonblock) {
|
||||
$asm = "rawSyscall6";
|
||||
}
|
||||
|
||||
if(@argsgc <= 6) {
|
||||
while(@argsgc < 6) {
|
||||
push @argsgc, "0";
|
||||
}
|
||||
} else {
|
||||
print STDERR "$ARGV:$.: too many arguments to system call\n";
|
||||
}
|
||||
my $argsgc = join(', ', @argsgc);
|
||||
my $callgc = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $argsgc)";
|
||||
|
||||
$textgc .= $callProto;
|
||||
$textgc .= "\tr1, _, e1 = $callgc\n";
|
||||
$textgc .= "\treturn\n}\n";
|
||||
|
||||
# GCCGO function generation
|
||||
my $argsgccgo = join(', ', @argsgccgo);
|
||||
my $callgccgo = "C.$sysname($argsgccgo)";
|
||||
$textgccgo .= $callProto;
|
||||
$textgccgo .= "\tr1 = uintptr($callgccgo)\n";
|
||||
$textgccgo .= "\te1 = syscall.GetErrno()\n";
|
||||
$textgccgo .= "\treturn\n}\n";
|
||||
}
|
||||
|
||||
if($errors) {
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Print zsyscall_aix_ppc64.go
|
||||
open(my $fcommun, '>', 'zsyscall_aix_ppc64.go');
|
||||
my $tofcommun = <<EOF;
|
||||
// $cmdline
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $tags
|
||||
|
||||
package $package
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
EOF
|
||||
|
||||
$tofcommun .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
|
||||
|
||||
$tofcommun .=<<EOF;
|
||||
|
||||
$textcommon
|
||||
EOF
|
||||
print $fcommun $tofcommun;
|
||||
|
||||
|
||||
# Print zsyscall_aix_ppc64_gc.go
|
||||
open(my $fgc, '>', 'zsyscall_aix_ppc64_gc.go');
|
||||
my $tofgc = <<EOF;
|
||||
// $cmdline
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $tags
|
||||
// +build !gccgo
|
||||
|
||||
package $package
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
||||
EOF
|
||||
|
||||
$tofgc .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
|
||||
|
||||
my $vardecls = "\t" . join(",\n\t", @vars);
|
||||
$vardecls .= " syscallFunc";
|
||||
|
||||
$tofgc .=<<EOF;
|
||||
$dynimports
|
||||
$linknames
|
||||
type syscallFunc uintptr
|
||||
|
||||
var (
|
||||
$vardecls
|
||||
)
|
||||
|
||||
// Implemented in runtime/syscall_aix.go.
|
||||
func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
$textgc
|
||||
EOF
|
||||
print $fgc $tofgc;
|
||||
|
||||
# Print zsyscall_aix_ppc64_gc.go
|
||||
open(my $fgccgo, '>', 'zsyscall_aix_ppc64_gccgo.go');
|
||||
my $tofgccgo = <<EOF;
|
||||
// $cmdline
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $tags
|
||||
// +build gccgo
|
||||
|
||||
package $package
|
||||
|
||||
|
||||
$c_extern
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
|
||||
EOF
|
||||
|
||||
$tofgccgo .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
|
||||
|
||||
$tofgccgo .=<<EOF;
|
||||
|
||||
$textgccgo
|
||||
EOF
|
||||
print $fgccgo $tofgccgo;
|
||||
exit 0;
|
294
vendor/golang.org/x/sys/unix/mksyscall_solaris.pl
generated
vendored
294
vendor/golang.org/x/sys/unix/mksyscall_solaris.pl
generated
vendored
@ -1,294 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright 2009 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.
|
||||
|
||||
# This program reads a file containing function prototypes
|
||||
# (like syscall_solaris.go) and generates system call bodies.
|
||||
# The prototypes are marked by lines beginning with "//sys"
|
||||
# and read like func declarations if //sys is replaced by func, but:
|
||||
# * The parameter lists must give a name for each argument.
|
||||
# This includes return parameters.
|
||||
# * The parameter lists must give a type for each argument:
|
||||
# the (x, y, z int) shorthand is not allowed.
|
||||
# * If the return parameter is an error number, it must be named err.
|
||||
# * If go func name needs to be different than its libc name,
|
||||
# * or the function is not in libc, name could be specified
|
||||
# * at the end, after "=" sign, like
|
||||
# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
||||
|
||||
use strict;
|
||||
|
||||
my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV);
|
||||
my $errors = 0;
|
||||
my $_32bit = "";
|
||||
my $tags = ""; # build tags
|
||||
|
||||
binmode STDOUT;
|
||||
|
||||
if($ARGV[0] eq "-b32") {
|
||||
$_32bit = "big-endian";
|
||||
shift;
|
||||
} elsif($ARGV[0] eq "-l32") {
|
||||
$_32bit = "little-endian";
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-tags") {
|
||||
shift;
|
||||
$tags = $ARGV[0];
|
||||
shift;
|
||||
}
|
||||
|
||||
if($ARGV[0] =~ /^-/) {
|
||||
print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub parseparamlist($) {
|
||||
my ($list) = @_;
|
||||
$list =~ s/^\s*//;
|
||||
$list =~ s/\s*$//;
|
||||
if($list eq "") {
|
||||
return ();
|
||||
}
|
||||
return split(/\s*,\s*/, $list);
|
||||
}
|
||||
|
||||
sub parseparam($) {
|
||||
my ($p) = @_;
|
||||
if($p !~ /^(\S*) (\S*)$/) {
|
||||
print STDERR "$ARGV:$.: malformed parameter: $p\n";
|
||||
$errors = 1;
|
||||
return ("xx", "int");
|
||||
}
|
||||
return ($1, $2);
|
||||
}
|
||||
|
||||
my $package = "";
|
||||
my $text = "";
|
||||
my $dynimports = "";
|
||||
my $linknames = "";
|
||||
my @vars = ();
|
||||
while(<>) {
|
||||
chomp;
|
||||
s/\s+/ /g;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
$package = $1 if !$package && /^package (\S+)$/;
|
||||
my $nonblock = /^\/\/sysnb /;
|
||||
next if !/^\/\/sys / && !$nonblock;
|
||||
|
||||
# Line must be of the form
|
||||
# func Open(path string, mode int, perm int) (fd int, err error)
|
||||
# Split into name, in params, out params.
|
||||
if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
|
||||
print STDERR "$ARGV:$.: malformed //sys declaration\n";
|
||||
$errors = 1;
|
||||
next;
|
||||
}
|
||||
my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
|
||||
|
||||
# Split argument lists on comma.
|
||||
my @in = parseparamlist($in);
|
||||
my @out = parseparamlist($out);
|
||||
|
||||
# Try in vain to keep people from editing this file.
|
||||
# The theory is that they jump into the middle of the file
|
||||
# without reading the header.
|
||||
$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
|
||||
|
||||
# So file name.
|
||||
if($modname eq "") {
|
||||
$modname = "libc";
|
||||
}
|
||||
|
||||
# System call name.
|
||||
if($sysname eq "") {
|
||||
$sysname = "$func";
|
||||
}
|
||||
|
||||
# System call pointer variable name.
|
||||
my $sysvarname = "proc$sysname";
|
||||
|
||||
my $strconvfunc = "BytePtrFromString";
|
||||
my $strconvtype = "*byte";
|
||||
|
||||
$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
|
||||
|
||||
# Runtime import of function to allow cross-platform builds.
|
||||
$dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n";
|
||||
# Link symbol to proc address variable.
|
||||
$linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n";
|
||||
# Library proc address variable.
|
||||
push @vars, $sysvarname;
|
||||
|
||||
# Go function header.
|
||||
$out = join(', ', @out);
|
||||
if($out ne "") {
|
||||
$out = " ($out)";
|
||||
}
|
||||
if($text ne "") {
|
||||
$text .= "\n"
|
||||
}
|
||||
$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;
|
||||
|
||||
# Check if err return available
|
||||
my $errvar = "";
|
||||
foreach my $p (@out) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type eq "error") {
|
||||
$errvar = $name;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Prepare arguments to Syscall.
|
||||
my @args = ();
|
||||
my $n = 0;
|
||||
foreach my $p (@in) {
|
||||
my ($name, $type) = parseparam($p);
|
||||
if($type =~ /^\*/) {
|
||||
push @args, "uintptr(unsafe.Pointer($name))";
|
||||
} elsif($type eq "string" && $errvar ne "") {
|
||||
$text .= "\tvar _p$n $strconvtype\n";
|
||||
$text .= "\t_p$n, $errvar = $strconvfunc($name)\n";
|
||||
$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))";
|
||||
$n++;
|
||||
} elsif($type eq "string") {
|
||||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
|
||||
$text .= "\tvar _p$n $strconvtype\n";
|
||||
$text .= "\t_p$n, _ = $strconvfunc($name)\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))";
|
||||
$n++;
|
||||
} elsif($type =~ /^\[\](.*)/) {
|
||||
# Convert slice into pointer, length.
|
||||
# Have to be careful not to take address of &a[0] if len == 0:
|
||||
# pass nil in that case.
|
||||
$text .= "\tvar _p$n *$1\n";
|
||||
$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
|
||||
push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
|
||||
$n++;
|
||||
} elsif($type eq "int64" && $_32bit ne "") {
|
||||
if($_32bit eq "big-endian") {
|
||||
push @args, "uintptr($name >> 32)", "uintptr($name)";
|
||||
} else {
|
||||
push @args, "uintptr($name)", "uintptr($name >> 32)";
|
||||
}
|
||||
} elsif($type eq "bool") {
|
||||
$text .= "\tvar _p$n uint32\n";
|
||||
$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
|
||||
push @args, "uintptr(_p$n)";
|
||||
$n++;
|
||||
} else {
|
||||
push @args, "uintptr($name)";
|
||||
}
|
||||
}
|
||||
my $nargs = @args;
|
||||
|
||||
# Determine which form to use; pad args with zeros.
|
||||
my $asm = "sysvicall6";
|
||||
if ($nonblock) {
|
||||
$asm = "rawSysvicall6";
|
||||
}
|
||||
if(@args <= 6) {
|
||||
while(@args < 6) {
|
||||
push @args, "0";
|
||||
}
|
||||
} else {
|
||||
print STDERR "$ARGV:$.: too many arguments to system call\n";
|
||||
}
|
||||
|
||||
# Actual call.
|
||||
my $args = join(', ', @args);
|
||||
my $call = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $args)";
|
||||
|
||||
# Assign return values.
|
||||
my $body = "";
|
||||
my $failexpr = "";
|
||||
my @ret = ("_", "_", "_");
|
||||
my @pout= ();
|
||||
my $do_errno = 0;
|
||||
for(my $i=0; $i<@out; $i++) {
|
||||
my $p = $out[$i];
|
||||
my ($name, $type) = parseparam($p);
|
||||
my $reg = "";
|
||||
if($name eq "err") {
|
||||
$reg = "e1";
|
||||
$ret[2] = $reg;
|
||||
$do_errno = 1;
|
||||
} else {
|
||||
$reg = sprintf("r%d", $i);
|
||||
$ret[$i] = $reg;
|
||||
}
|
||||
if($type eq "bool") {
|
||||
$reg = "$reg != 0";
|
||||
}
|
||||
if($type eq "int64" && $_32bit ne "") {
|
||||
# 64-bit number in r1:r0 or r0:r1.
|
||||
if($i+2 > @out) {
|
||||
print STDERR "$ARGV:$.: not enough registers for int64 return\n";
|
||||
}
|
||||
if($_32bit eq "big-endian") {
|
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
|
||||
} else {
|
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
|
||||
}
|
||||
$ret[$i] = sprintf("r%d", $i);
|
||||
$ret[$i+1] = sprintf("r%d", $i+1);
|
||||
}
|
||||
if($reg ne "e1") {
|
||||
$body .= "\t$name = $type($reg)\n";
|
||||
}
|
||||
}
|
||||
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
|
||||
$text .= "\t$call\n";
|
||||
} else {
|
||||
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
|
||||
}
|
||||
$text .= $body;
|
||||
|
||||
if ($do_errno) {
|
||||
$text .= "\tif e1 != 0 {\n";
|
||||
$text .= "\t\terr = e1\n";
|
||||
$text .= "\t}\n";
|
||||
}
|
||||
$text .= "\treturn\n";
|
||||
$text .= "}\n";
|
||||
}
|
||||
|
||||
if($errors) {
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
// $cmdline
|
||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||
|
||||
// +build $tags
|
||||
|
||||
package $package
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
EOF
|
||||
|
||||
print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
|
||||
|
||||
my $vardecls = "\t" . join(",\n\t", @vars);
|
||||
$vardecls .= " syscallFunc";
|
||||
|
||||
chomp($_=<<EOF);
|
||||
|
||||
$dynimports
|
||||
$linknames
|
||||
var (
|
||||
$vardecls
|
||||
)
|
||||
|
||||
$text
|
||||
EOF
|
||||
print $_;
|
||||
exit 0;
|
265
vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
generated
vendored
265
vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
generated
vendored
@ -1,265 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Copyright 2011 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.
|
||||
|
||||
#
|
||||
# Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
|
||||
#
|
||||
# Build a MIB with each entry being an array containing the level, type and
|
||||
# a hash that will contain additional entries if the current entry is a node.
|
||||
# We then walk this MIB and create a flattened sysctl name to OID hash.
|
||||
#
|
||||
|
||||
use strict;
|
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
|
||||
print STDERR "GOARCH or GOOS not defined in environment\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $debug = 0;
|
||||
my %ctls = ();
|
||||
|
||||
my @headers = qw (
|
||||
sys/sysctl.h
|
||||
sys/socket.h
|
||||
sys/tty.h
|
||||
sys/malloc.h
|
||||
sys/mount.h
|
||||
sys/namei.h
|
||||
sys/sem.h
|
||||
sys/shm.h
|
||||
sys/vmmeter.h
|
||||
uvm/uvmexp.h
|
||||
uvm/uvm_param.h
|
||||
uvm/uvm_swap_encrypt.h
|
||||
ddb/db_var.h
|
||||
net/if.h
|
||||
net/if_pfsync.h
|
||||
net/pipex.h
|
||||
netinet/in.h
|
||||
netinet/icmp_var.h
|
||||
netinet/igmp_var.h
|
||||
netinet/ip_ah.h
|
||||
netinet/ip_carp.h
|
||||
netinet/ip_divert.h
|
||||
netinet/ip_esp.h
|
||||
netinet/ip_ether.h
|
||||
netinet/ip_gre.h
|
||||
netinet/ip_ipcomp.h
|
||||
netinet/ip_ipip.h
|
||||
netinet/pim_var.h
|
||||
netinet/tcp_var.h
|
||||
netinet/udp_var.h
|
||||
netinet6/in6.h
|
||||
netinet6/ip6_divert.h
|
||||
netinet6/pim6_var.h
|
||||
netinet/icmp6.h
|
||||
netmpls/mpls.h
|
||||
);
|
||||
|
||||
my @ctls = qw (
|
||||
kern
|
||||
vm
|
||||
fs
|
||||
net
|
||||
#debug # Special handling required
|
||||
hw
|
||||
#machdep # Arch specific
|
||||
user
|
||||
ddb
|
||||
#vfs # Special handling required
|
||||
fs.posix
|
||||
kern.forkstat
|
||||
kern.intrcnt
|
||||
kern.malloc
|
||||
kern.nchstats
|
||||
kern.seminfo
|
||||
kern.shminfo
|
||||
kern.timecounter
|
||||
kern.tty
|
||||
kern.watchdog
|
||||
net.bpf
|
||||
net.ifq
|
||||
net.inet
|
||||
net.inet.ah
|
||||
net.inet.carp
|
||||
net.inet.divert
|
||||
net.inet.esp
|
||||
net.inet.etherip
|
||||
net.inet.gre
|
||||
net.inet.icmp
|
||||
net.inet.igmp
|
||||
net.inet.ip
|
||||
net.inet.ip.ifq
|
||||
net.inet.ipcomp
|
||||
net.inet.ipip
|
||||
net.inet.mobileip
|
||||
net.inet.pfsync
|
||||
net.inet.pim
|
||||
net.inet.tcp
|
||||
net.inet.udp
|
||||
net.inet6
|
||||
net.inet6.divert
|
||||
net.inet6.ip6
|
||||
net.inet6.icmp6
|
||||
net.inet6.pim6
|
||||
net.inet6.tcp6
|
||||
net.inet6.udp6
|
||||
net.mpls
|
||||
net.mpls.ifq
|
||||
net.key
|
||||
net.pflow
|
||||
net.pfsync
|
||||
net.pipex
|
||||
net.rt
|
||||
vm.swapencrypt
|
||||
#vfsgenctl # Special handling required
|
||||
);
|
||||
|
||||
# Node name "fixups"
|
||||
my %ctl_map = (
|
||||
"ipproto" => "net.inet",
|
||||
"net.inet.ipproto" => "net.inet",
|
||||
"net.inet6.ipv6proto" => "net.inet6",
|
||||
"net.inet6.ipv6" => "net.inet6.ip6",
|
||||
"net.inet.icmpv6" => "net.inet6.icmp6",
|
||||
"net.inet6.divert6" => "net.inet6.divert",
|
||||
"net.inet6.tcp6" => "net.inet.tcp",
|
||||
"net.inet6.udp6" => "net.inet.udp",
|
||||
"mpls" => "net.mpls",
|
||||
"swpenc" => "vm.swapencrypt"
|
||||
);
|
||||
|
||||
# Node mappings
|
||||
my %node_map = (
|
||||
"net.inet.ip.ifq" => "net.ifq",
|
||||
"net.inet.pfsync" => "net.pfsync",
|
||||
"net.mpls.ifq" => "net.ifq"
|
||||
);
|
||||
|
||||
my $ctlname;
|
||||
my %mib = ();
|
||||
my %sysctl = ();
|
||||
my $node;
|
||||
|
||||
sub debug() {
|
||||
print STDERR "$_[0]\n" if $debug;
|
||||
}
|
||||
|
||||
# Walk the MIB and build a sysctl name to OID mapping.
|
||||
sub build_sysctl() {
|
||||
my ($node, $name, $oid) = @_;
|
||||
my %node = %{$node};
|
||||
my @oid = @{$oid};
|
||||
|
||||
foreach my $key (sort keys %node) {
|
||||
my @node = @{$node{$key}};
|
||||
my $nodename = $name.($name ne '' ? '.' : '').$key;
|
||||
my @nodeoid = (@oid, $node[0]);
|
||||
if ($node[1] eq 'CTLTYPE_NODE') {
|
||||
if (exists $node_map{$nodename}) {
|
||||
$node = \%mib;
|
||||
$ctlname = $node_map{$nodename};
|
||||
foreach my $part (split /\./, $ctlname) {
|
||||
$node = \%{@{$$node{$part}}[2]};
|
||||
}
|
||||
} else {
|
||||
$node = $node[2];
|
||||
}
|
||||
&build_sysctl($node, $nodename, \@nodeoid);
|
||||
} elsif ($node[1] ne '') {
|
||||
$sysctl{$nodename} = \@nodeoid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $ctl (@ctls) {
|
||||
$ctls{$ctl} = $ctl;
|
||||
}
|
||||
|
||||
# Build MIB
|
||||
foreach my $header (@headers) {
|
||||
&debug("Processing $header...");
|
||||
open HEADER, "/usr/include/$header" ||
|
||||
print STDERR "Failed to open $header\n";
|
||||
while (<HEADER>) {
|
||||
if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ ||
|
||||
$_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ ||
|
||||
$_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) {
|
||||
if ($1 eq 'CTL_NAMES') {
|
||||
# Top level.
|
||||
$node = \%mib;
|
||||
} else {
|
||||
# Node.
|
||||
my $nodename = lc($2);
|
||||
if ($header =~ /^netinet\//) {
|
||||
$ctlname = "net.inet.$nodename";
|
||||
} elsif ($header =~ /^netinet6\//) {
|
||||
$ctlname = "net.inet6.$nodename";
|
||||
} elsif ($header =~ /^net\//) {
|
||||
$ctlname = "net.$nodename";
|
||||
} else {
|
||||
$ctlname = "$nodename";
|
||||
$ctlname =~ s/^(fs|net|kern)_/$1\./;
|
||||
}
|
||||
if (exists $ctl_map{$ctlname}) {
|
||||
$ctlname = $ctl_map{$ctlname};
|
||||
}
|
||||
if (not exists $ctls{$ctlname}) {
|
||||
&debug("Ignoring $ctlname...");
|
||||
next;
|
||||
}
|
||||
|
||||
# Walk down from the top of the MIB.
|
||||
$node = \%mib;
|
||||
foreach my $part (split /\./, $ctlname) {
|
||||
if (not exists $$node{$part}) {
|
||||
&debug("Missing node $part");
|
||||
$$node{$part} = [ 0, '', {} ];
|
||||
}
|
||||
$node = \%{@{$$node{$part}}[2]};
|
||||
}
|
||||
}
|
||||
|
||||
# Populate current node with entries.
|
||||
my $i = -1;
|
||||
while (defined($_) && $_ !~ /^}/) {
|
||||
$_ = <HEADER>;
|
||||
$i++ if $_ =~ /{.*}/;
|
||||
next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/;
|
||||
$$node{$1} = [ $i, $2, {} ];
|
||||
}
|
||||
}
|
||||
}
|
||||
close HEADER;
|
||||
}
|
||||
|
||||
&build_sysctl(\%mib, "", []);
|
||||
|
||||
print <<EOF;
|
||||
// mksysctl_openbsd.pl
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
package unix;
|
||||
|
||||
type mibentry struct {
|
||||
ctlname string
|
||||
ctloid []_C_int
|
||||
}
|
||||
|
||||
var sysctlMib = []mibentry {
|
||||
EOF
|
||||
|
||||
foreach my $name (sort keys %sysctl) {
|
||||
my @oid = @{$sysctl{$name}};
|
||||
print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n";
|
||||
}
|
||||
|
||||
print <<EOF;
|
||||
}
|
||||
EOF
|
41
vendor/golang.org/x/sys/unix/mmap_unix_test.go
generated
vendored
41
vendor/golang.org/x/sys/unix/mmap_unix_test.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestMmap(t *testing.T) {
|
||||
b, err := unix.Mmap(-1, 0, unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
||||
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)
|
||||
}
|
||||
|
||||
b[0] = 42
|
||||
|
||||
if runtime.GOOS == "aix" {
|
||||
t.Skip("msync returns invalid argument for AIX, skipping msync test")
|
||||
} else {
|
||||
if err := unix.Msync(b, unix.MS_SYNC); err != nil {
|
||||
t.Fatalf("Msync: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := unix.Madvise(b, unix.MADV_DONTNEED); err != nil {
|
||||
t.Fatalf("Madvise: %v", err)
|
||||
}
|
||||
if err := unix.Munmap(b); err != nil {
|
||||
t.Fatalf("Munmap: %v", err)
|
||||
}
|
||||
}
|
113
vendor/golang.org/x/sys/unix/openbsd_test.go
generated
vendored
113
vendor/golang.org/x/sys/unix/openbsd_test.go
generated
vendored
@ -1,113 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build openbsd
|
||||
|
||||
// This, on the face of it, bizarre testing mechanism is necessary because
|
||||
// the only reliable way to gauge whether or not a pledge(2) call has succeeded
|
||||
// is that the program has been killed as a result of breaking its pledge.
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type testProc struct {
|
||||
fn func() // should always exit instead of returning
|
||||
cleanup func() error // for instance, delete coredumps from testing pledge
|
||||
success bool // whether zero-exit means success or failure
|
||||
}
|
||||
|
||||
var (
|
||||
testProcs = map[string]testProc{}
|
||||
procName = ""
|
||||
)
|
||||
|
||||
const (
|
||||
optName = "sys-unix-internal-procname"
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&procName, optName, "", "internal use only")
|
||||
}
|
||||
|
||||
// testCmd generates a proper command that, when executed, runs the test
|
||||
// corresponding to the given key.
|
||||
func testCmd(procName string) (*exec.Cmd, error) {
|
||||
exe, err := filepath.Abs(os.Args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.Command(exe, "-"+optName+"="+procName)
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
|
||||
// a testProc with a key.
|
||||
func ExitsCorrectly(procName string, t *testing.T) {
|
||||
s := testProcs[procName]
|
||||
c, err := testCmd(procName)
|
||||
defer func() {
|
||||
if s.cleanup() != nil {
|
||||
t.Fatalf("Failed to run cleanup for %s", procName)
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to construct command for %s", procName)
|
||||
}
|
||||
if (c.Run() == nil) != s.success {
|
||||
result := "succeed"
|
||||
if !s.success {
|
||||
result = "fail"
|
||||
}
|
||||
t.Fatalf("Process did not %s when it was supposed to", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
if procName != "" {
|
||||
testProcs[procName].fn()
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// For example, add a test for pledge.
|
||||
func init() {
|
||||
testProcs["pledge"] = testProc{
|
||||
func() {
|
||||
fmt.Println(unix.Pledge("", ""))
|
||||
os.Exit(0)
|
||||
},
|
||||
func() error {
|
||||
files, err := ioutil.ReadDir(".")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, file := range files {
|
||||
if filepath.Ext(file.Name()) == ".core" {
|
||||
if err := os.Remove(file.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
false,
|
||||
}
|
||||
}
|
||||
|
||||
func TestPledge(t *testing.T) {
|
||||
ExitsCorrectly("pledge", t)
|
||||
}
|
98
vendor/golang.org/x/sys/unix/sendfile_test.go
generated
vendored
98
vendor/golang.org/x/sys/unix/sendfile_test.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build darwin,amd64 darwin,386 dragonfly freebsd linux solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestSendfile(t *testing.T) {
|
||||
// Set up source data file.
|
||||
tempDir, err := ioutil.TempDir("", "TestSendfile")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
name := filepath.Join(tempDir, "source")
|
||||
const contents = "contents"
|
||||
err = ioutil.WriteFile(name, []byte(contents), 0666)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
done := make(chan bool)
|
||||
|
||||
// Start server listening on a socket.
|
||||
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Skipf("listen failed: %s\n", err)
|
||||
}
|
||||
defer ln.Close()
|
||||
go func() {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
b, err := ioutil.ReadAll(conn)
|
||||
if string(b) != contents {
|
||||
t.Errorf("contents not transmitted: got %s (len=%d), want %s", string(b), len(b), contents)
|
||||
}
|
||||
done <- true
|
||||
}()
|
||||
|
||||
// Open source file.
|
||||
src, err := os.Open(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Send source file to server.
|
||||
conn, err := net.Dial("tcp", ln.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := conn.(*net.TCPConn).File()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var off int64
|
||||
n, err := unix.Sendfile(int(file.Fd()), int(src.Fd()), &off, len(contents))
|
||||
if err != nil {
|
||||
t.Errorf("Sendfile failed %s\n", err)
|
||||
}
|
||||
if n != len(contents) {
|
||||
t.Errorf("written count wrong: want %d, got %d", len(contents), n)
|
||||
}
|
||||
// Note: off is updated on some systems and not others. Oh well.
|
||||
// Linux: increments off by the amount sent.
|
||||
// Darwin: leaves off unchanged.
|
||||
// It would be nice to fix Darwin if we can.
|
||||
if off != 0 && off != int64(len(contents)) {
|
||||
t.Errorf("offset wrong: god %d, want %d or %d", off, 0, len(contents))
|
||||
}
|
||||
// The cursor position should be unchanged.
|
||||
pos, err := src.Seek(0, 1)
|
||||
if err != nil {
|
||||
t.Errorf("can't get cursor position %s\n", err)
|
||||
}
|
||||
if pos != 0 {
|
||||
t.Errorf("cursor position wrong: got %d, want 0", pos)
|
||||
}
|
||||
|
||||
file.Close() // Note: required to have the close below really send EOF to the server.
|
||||
conn.Close()
|
||||
|
||||
// Wait for server to close.
|
||||
<-done
|
||||
}
|
162
vendor/golang.org/x/sys/unix/syscall_aix_test.go
generated
vendored
162
vendor/golang.org/x/sys/unix/syscall_aix_test.go
generated
vendored
@ -1,162 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build aix
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestIoctlGetInt(t *testing.T) {
|
||||
f, err := os.Open("/dev/random")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open device: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to perform ioctl: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("%d bits of entropy available", v)
|
||||
}
|
||||
|
||||
func TestTime(t *testing.T) {
|
||||
var ut unix.Time_t
|
||||
ut2, err := unix.Time(&ut)
|
||||
if err != nil {
|
||||
t.Fatalf("Time: %v", err)
|
||||
}
|
||||
if ut != ut2 {
|
||||
t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut)
|
||||
}
|
||||
|
||||
var now time.Time
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
ut, err = unix.Time(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Time: %v", err)
|
||||
}
|
||||
|
||||
now = time.Now()
|
||||
|
||||
if int64(ut) == now.Unix() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix())
|
||||
}
|
||||
|
||||
func TestUtime(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
touch(t, "file1")
|
||||
|
||||
buf := &unix.Utimbuf{
|
||||
Modtime: 12345,
|
||||
}
|
||||
|
||||
err := unix.Utime("file1", buf)
|
||||
if err != nil {
|
||||
t.Fatalf("Utime: %v", err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat("file1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if fi.ModTime().Unix() != 12345 {
|
||||
t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUtimesNanoAt(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
symlink := "symlink1"
|
||||
defer os.Remove(symlink)
|
||||
err := os.Symlink("nonexisting", symlink)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ts := []unix.Timespec{
|
||||
{Sec: 1111, Nsec: 2222},
|
||||
{Sec: 3333, Nsec: 4444},
|
||||
}
|
||||
err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != nil {
|
||||
t.Fatalf("UtimesNanoAt: %v", err)
|
||||
}
|
||||
|
||||
var st unix.Stat_t
|
||||
err = unix.Lstat(symlink, &st)
|
||||
if err != nil {
|
||||
t.Fatalf("Lstat: %v", err)
|
||||
}
|
||||
if runtime.GOARCH == "ppc64" {
|
||||
if int64(st.Atim.Sec) != int64(ts[0].Sec) || st.Atim.Nsec != int32(ts[0].Nsec) {
|
||||
t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
|
||||
}
|
||||
if int64(st.Mtim.Sec) != int64(ts[1].Sec) || st.Mtim.Nsec != int32(ts[1].Nsec) {
|
||||
t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
|
||||
}
|
||||
} else {
|
||||
if int32(st.Atim.Sec) != int32(ts[0].Sec) || int32(st.Atim.Nsec) != int32(ts[0].Nsec) {
|
||||
t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
|
||||
}
|
||||
if int32(st.Mtim.Sec) != int32(ts[1].Sec) || int32(st.Mtim.Nsec) != int32(ts[1].Nsec) {
|
||||
t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPselect(t *testing.T) {
|
||||
if runtime.GOARCH == "ppc64" {
|
||||
t.Skip("pselect issue with structure timespec on AIX 7.2 tl0, skipping test")
|
||||
}
|
||||
|
||||
_, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 0, Nsec: 0}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Pselect: %v", err)
|
||||
}
|
||||
|
||||
dur := 2500 * time.Microsecond
|
||||
ts := unix.NsecToTimespec(int64(dur))
|
||||
start := time.Now()
|
||||
_, err = unix.Pselect(0, nil, nil, nil, &ts, nil)
|
||||
took := time.Since(start)
|
||||
if err != nil {
|
||||
t.Fatalf("Pselect: %v", err)
|
||||
}
|
||||
|
||||
if took < dur {
|
||||
t.Errorf("Pselect: timeout should have been at least %v, got %v", dur, took)
|
||||
}
|
||||
}
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On Linux, each entry is a NULL-terminated string.
|
||||
func stringsFromByteSlice(buf []byte) []string {
|
||||
var result []string
|
||||
off := 0
|
||||
for i, b := range buf {
|
||||
if b == 0 {
|
||||
result = append(result, string(buf[off:i]))
|
||||
off = i + 1
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
89
vendor/golang.org/x/sys/unix/syscall_bsd_test.go
generated
vendored
89
vendor/golang.org/x/sys/unix/syscall_bsd_test.go
generated
vendored
@ -1,89 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// +build darwin dragonfly freebsd openbsd
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestGetfsstat(t *testing.T) {
|
||||
n, err := unix.Getfsstat(nil, unix.MNT_NOWAIT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
data := make([]unix.Statfs_t, n)
|
||||
n2, err := unix.Getfsstat(data, unix.MNT_NOWAIT)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n != n2 {
|
||||
t.Errorf("Getfsstat(nil) = %d, but subsequent Getfsstat(slice) = %d", n, n2)
|
||||
}
|
||||
for i, stat := range data {
|
||||
if stat == (unix.Statfs_t{}) {
|
||||
t.Errorf("index %v is an empty Statfs_t struct", i)
|
||||
}
|
||||
}
|
||||
if t.Failed() {
|
||||
for i, stat := range data[:n2] {
|
||||
t.Logf("data[%v] = %+v", i, stat)
|
||||
}
|
||||
mount, err := exec.Command("mount").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("mount: %v\n%s", err, mount)
|
||||
} else {
|
||||
t.Logf("mount: %s", mount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelect(t *testing.T) {
|
||||
err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
|
||||
if err != nil {
|
||||
t.Fatalf("Select: %v", err)
|
||||
}
|
||||
|
||||
dur := 250 * time.Millisecond
|
||||
tv := unix.NsecToTimeval(int64(dur))
|
||||
start := time.Now()
|
||||
err = unix.Select(0, nil, nil, nil, &tv)
|
||||
took := time.Since(start)
|
||||
if err != nil {
|
||||
t.Fatalf("Select: %v", err)
|
||||
}
|
||||
|
||||
// On some BSDs the actual timeout might also be slightly less than the requested.
|
||||
// Add an acceptable margin to avoid flaky tests.
|
||||
if took < dur*2/3 {
|
||||
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSysctlRaw(t *testing.T) {
|
||||
if runtime.GOOS == "openbsd" {
|
||||
t.Skip("kern.proc.pid does not exist on OpenBSD")
|
||||
}
|
||||
|
||||
_, err := unix.SysctlRaw("kern.proc.pid", unix.Getpid())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSysctlUint32(t *testing.T) {
|
||||
maxproc, err := unix.SysctlUint32("kern.maxproc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("kern.maxproc: %v", maxproc)
|
||||
}
|
63
vendor/golang.org/x/sys/unix/syscall_darwin_test.go
generated
vendored
63
vendor/golang.org/x/sys/unix/syscall_darwin_test.go
generated
vendored
@ -1,63 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On Darwin, each entry is a NULL-terminated string.
|
||||
func stringsFromByteSlice(buf []byte) []string {
|
||||
var result []string
|
||||
off := 0
|
||||
for i, b := range buf {
|
||||
if b == 0 {
|
||||
result = append(result, string(buf[off:i]))
|
||||
off = i + 1
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func TestUtimesNanoAt(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
symlink := "symlink1"
|
||||
os.Remove(symlink)
|
||||
err := os.Symlink("nonexisting", symlink)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ts := []unix.Timespec{
|
||||
{Sec: 1111, Nsec: 2222},
|
||||
{Sec: 3333, Nsec: 4444},
|
||||
}
|
||||
err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != nil {
|
||||
t.Fatalf("UtimesNanoAt: %v", err)
|
||||
}
|
||||
|
||||
var st unix.Stat_t
|
||||
err = unix.Lstat(symlink, &st)
|
||||
if err != nil {
|
||||
t.Fatalf("Lstat: %v", err)
|
||||
}
|
||||
|
||||
// Only check Mtimespec, Atimespec might not be supported by the underlying filesystem
|
||||
expected := ts[1]
|
||||
if st.Mtimespec.Nsec == 0 {
|
||||
// Some filesystems only support 1-second time stamp resolution
|
||||
// and will always set Nsec to 0.
|
||||
expected.Nsec = 0
|
||||
}
|
||||
if st.Mtimespec != expected {
|
||||
t.Errorf("UtimesNanoAt: wrong mtime: got %v, expected %v", st.Mtimespec, expected)
|
||||
}
|
||||
}
|
312
vendor/golang.org/x/sys/unix/syscall_freebsd_test.go
generated
vendored
312
vendor/golang.org/x/sys/unix/syscall_freebsd_test.go
generated
vendored
@ -1,312 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// +build freebsd
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestSysctlUint64(t *testing.T) {
|
||||
_, err := unix.SysctlUint64("vm.swap_total")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Infrastructure for launching tests in subprocesses stolen from openbsd_test.go - refactor?
|
||||
// testCmd generates a proper command that, when executed, runs the test
|
||||
// corresponding to the given key.
|
||||
|
||||
type testProc struct {
|
||||
fn func() // should always exit instead of returning
|
||||
arg func(t *testing.T) string // generate argument for test
|
||||
cleanup func(arg string) error // for instance, delete coredumps from testing pledge
|
||||
success bool // whether zero-exit means success or failure
|
||||
}
|
||||
|
||||
var (
|
||||
testProcs = map[string]testProc{}
|
||||
procName = ""
|
||||
procArg = ""
|
||||
)
|
||||
|
||||
const (
|
||||
optName = "sys-unix-internal-procname"
|
||||
optArg = "sys-unix-internal-arg"
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&procName, optName, "", "internal use only")
|
||||
flag.StringVar(&procArg, optArg, "", "internal use only")
|
||||
|
||||
}
|
||||
|
||||
func testCmd(procName string, procArg string) (*exec.Cmd, error) {
|
||||
exe, err := filepath.Abs(os.Args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.Command(exe, "-"+optName+"="+procName, "-"+optArg+"="+procArg)
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
|
||||
// a testProc with a key.
|
||||
func ExitsCorrectly(t *testing.T, procName string) {
|
||||
s := testProcs[procName]
|
||||
arg := "-"
|
||||
if s.arg != nil {
|
||||
arg = s.arg(t)
|
||||
}
|
||||
c, err := testCmd(procName, arg)
|
||||
defer func(arg string) {
|
||||
if err := s.cleanup(arg); err != nil {
|
||||
t.Fatalf("Failed to run cleanup for %s %s %#v", procName, err, err)
|
||||
}
|
||||
}(arg)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to construct command for %s", procName)
|
||||
}
|
||||
if (c.Run() == nil) != s.success {
|
||||
result := "succeed"
|
||||
if !s.success {
|
||||
result = "fail"
|
||||
}
|
||||
t.Fatalf("Process did not %s when it was supposed to", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
if procName != "" {
|
||||
t := testProcs[procName]
|
||||
t.fn()
|
||||
os.Stderr.WriteString("test function did not exit\n")
|
||||
if t.success {
|
||||
os.Exit(1)
|
||||
} else {
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// end of infrastructure
|
||||
|
||||
const testfile = "gocapmodetest"
|
||||
const testfile2 = testfile + "2"
|
||||
|
||||
func CapEnterTest() {
|
||||
_, err := os.OpenFile(path.Join(procArg, testfile), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("OpenFile: %s", err))
|
||||
}
|
||||
|
||||
err = unix.CapEnter()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("CapEnter: %s", err))
|
||||
}
|
||||
|
||||
_, err = os.OpenFile(path.Join(procArg, testfile2), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err == nil {
|
||||
panic("OpenFile works!")
|
||||
}
|
||||
if err.(*os.PathError).Err != unix.ECAPMODE {
|
||||
panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func makeTempDir(t *testing.T) string {
|
||||
d, err := ioutil.TempDir("", "go_openat_test")
|
||||
if err != nil {
|
||||
t.Fatalf("TempDir failed: %s", err)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func removeTempDir(arg string) error {
|
||||
err := os.RemoveAll(arg)
|
||||
if err != nil && err.(*os.PathError).Err == unix.ENOENT {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func init() {
|
||||
testProcs["cap_enter"] = testProc{
|
||||
CapEnterTest,
|
||||
makeTempDir,
|
||||
removeTempDir,
|
||||
true,
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapEnter(t *testing.T) {
|
||||
if runtime.GOARCH != "amd64" {
|
||||
t.Skipf("skipping test on %s", runtime.GOARCH)
|
||||
}
|
||||
ExitsCorrectly(t, "cap_enter")
|
||||
}
|
||||
|
||||
func OpenatTest() {
|
||||
f, err := os.Open(procArg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = unix.CapEnter()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("CapEnter: %s", err))
|
||||
}
|
||||
|
||||
fxx, err := unix.Openat(int(f.Fd()), "xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
unix.Close(fxx)
|
||||
|
||||
// The right to open BASE/xx is not ambient
|
||||
_, err = os.OpenFile(procArg+"/xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err == nil {
|
||||
panic("OpenFile succeeded")
|
||||
}
|
||||
if err.(*os.PathError).Err != unix.ECAPMODE {
|
||||
panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
|
||||
}
|
||||
|
||||
// Can't make a new directory either
|
||||
err = os.Mkdir(procArg+"2", 0777)
|
||||
if err == nil {
|
||||
panic("MKdir succeeded")
|
||||
}
|
||||
if err.(*os.PathError).Err != unix.ECAPMODE {
|
||||
panic(fmt.Sprintf("Mkdir failed wrong: %s %#v", err, err))
|
||||
}
|
||||
|
||||
// Remove all caps except read and lookup.
|
||||
r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_LOOKUP})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("CapRightsInit failed: %s %#v", err, err))
|
||||
}
|
||||
err = unix.CapRightsLimit(f.Fd(), r)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("CapRightsLimit failed: %s %#v", err, err))
|
||||
}
|
||||
|
||||
// Check we can get the rights back again
|
||||
r, err = unix.CapRightsGet(f.Fd())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("CapRightsGet failed: %s %#v", err, err))
|
||||
}
|
||||
b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
|
||||
}
|
||||
if !b {
|
||||
panic(fmt.Sprintf("Unexpected rights"))
|
||||
}
|
||||
b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP, unix.CAP_WRITE})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
|
||||
}
|
||||
if b {
|
||||
panic(fmt.Sprintf("Unexpected rights (2)"))
|
||||
}
|
||||
|
||||
// Can no longer create a file
|
||||
_, err = unix.Openat(int(f.Fd()), "xx2", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err == nil {
|
||||
panic("Openat succeeded")
|
||||
}
|
||||
if err != unix.ENOTCAPABLE {
|
||||
panic(fmt.Sprintf("OpenFileAt failed wrong: %s %#v", err, err))
|
||||
}
|
||||
|
||||
// But can read an existing one
|
||||
_, err = unix.Openat(int(f.Fd()), "xx", os.O_RDONLY, 0666)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Openat failed: %s %#v", err, err))
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func init() {
|
||||
testProcs["openat"] = testProc{
|
||||
OpenatTest,
|
||||
makeTempDir,
|
||||
removeTempDir,
|
||||
true,
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenat(t *testing.T) {
|
||||
if runtime.GOARCH != "amd64" {
|
||||
t.Skipf("skipping test on %s", runtime.GOARCH)
|
||||
}
|
||||
ExitsCorrectly(t, "openat")
|
||||
}
|
||||
|
||||
func TestCapRightsSetAndClear(t *testing.T) {
|
||||
r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT})
|
||||
if err != nil {
|
||||
t.Fatalf("CapRightsInit failed: %s", err)
|
||||
}
|
||||
|
||||
err = unix.CapRightsSet(r, []uint64{unix.CAP_EVENT, unix.CAP_LISTEN})
|
||||
if err != nil {
|
||||
t.Fatalf("CapRightsSet failed: %s", err)
|
||||
}
|
||||
|
||||
b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT, unix.CAP_EVENT, unix.CAP_LISTEN})
|
||||
if err != nil {
|
||||
t.Fatalf("CapRightsIsSet failed: %s", err)
|
||||
}
|
||||
if !b {
|
||||
t.Fatalf("Wrong rights set")
|
||||
}
|
||||
|
||||
err = unix.CapRightsClear(r, []uint64{unix.CAP_READ, unix.CAP_PDWAIT})
|
||||
if err != nil {
|
||||
t.Fatalf("CapRightsClear failed: %s", err)
|
||||
}
|
||||
|
||||
b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_WRITE, unix.CAP_EVENT, unix.CAP_LISTEN})
|
||||
if err != nil {
|
||||
t.Fatalf("CapRightsIsSet failed: %s", err)
|
||||
}
|
||||
if !b {
|
||||
t.Fatalf("Wrong rights set")
|
||||
}
|
||||
}
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On FreeBSD, each entry consists of a single byte containing the length
|
||||
// of the attribute name, followed by the attribute name.
|
||||
// The name is _not_ NULL-terminated.
|
||||
func stringsFromByteSlice(buf []byte) []string {
|
||||
var result []string
|
||||
i := 0
|
||||
for i < len(buf) {
|
||||
next := i + 1 + int(buf[i])
|
||||
result = append(result, string(buf[i+1:next]))
|
||||
i = next
|
||||
}
|
||||
return result
|
||||
}
|
517
vendor/golang.org/x/sys/unix/syscall_linux_test.go
generated
vendored
517
vendor/golang.org/x/sys/unix/syscall_linux_test.go
generated
vendored
@ -1,517 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build linux
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestIoctlGetInt(t *testing.T) {
|
||||
f, err := os.Open("/dev/random")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open device: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to perform ioctl: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("%d bits of entropy available", v)
|
||||
}
|
||||
|
||||
func TestPpoll(t *testing.T) {
|
||||
if runtime.GOOS == "android" {
|
||||
t.Skip("mkfifo syscall is not available on android, skipping test")
|
||||
}
|
||||
|
||||
f, cleanup := mktmpfifo(t)
|
||||
defer cleanup()
|
||||
|
||||
const timeout = 100 * time.Millisecond
|
||||
|
||||
ok := make(chan bool, 1)
|
||||
go func() {
|
||||
select {
|
||||
case <-time.After(10 * timeout):
|
||||
t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
|
||||
case <-ok:
|
||||
}
|
||||
}()
|
||||
|
||||
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
|
||||
timeoutTs := unix.NsecToTimespec(int64(timeout))
|
||||
n, err := unix.Ppoll(fds, &timeoutTs, nil)
|
||||
ok <- true
|
||||
if err != nil {
|
||||
t.Errorf("Ppoll: unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
if n != 0 {
|
||||
t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestTime(t *testing.T) {
|
||||
var ut unix.Time_t
|
||||
ut2, err := unix.Time(&ut)
|
||||
if err != nil {
|
||||
t.Fatalf("Time: %v", err)
|
||||
}
|
||||
if ut != ut2 {
|
||||
t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut)
|
||||
}
|
||||
|
||||
var now time.Time
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
ut, err = unix.Time(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Time: %v", err)
|
||||
}
|
||||
|
||||
now = time.Now()
|
||||
|
||||
if int64(ut) == now.Unix() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix())
|
||||
}
|
||||
|
||||
func TestUtime(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
touch(t, "file1")
|
||||
|
||||
buf := &unix.Utimbuf{
|
||||
Modtime: 12345,
|
||||
}
|
||||
|
||||
err := unix.Utime("file1", buf)
|
||||
if err != nil {
|
||||
t.Fatalf("Utime: %v", err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat("file1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if fi.ModTime().Unix() != 12345 {
|
||||
t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUtimesNanoAt(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
symlink := "symlink1"
|
||||
os.Remove(symlink)
|
||||
err := os.Symlink("nonexisting", symlink)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ts := []unix.Timespec{
|
||||
{Sec: 1111, Nsec: 2222},
|
||||
{Sec: 3333, Nsec: 4444},
|
||||
}
|
||||
err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != nil {
|
||||
t.Fatalf("UtimesNanoAt: %v", err)
|
||||
}
|
||||
|
||||
var st unix.Stat_t
|
||||
err = unix.Lstat(symlink, &st)
|
||||
if err != nil {
|
||||
t.Fatalf("Lstat: %v", err)
|
||||
}
|
||||
|
||||
// Only check Mtim, Atim might not be supported by the underlying filesystem
|
||||
expected := ts[1]
|
||||
if st.Mtim.Nsec == 0 {
|
||||
// Some filesystems only support 1-second time stamp resolution
|
||||
// and will always set Nsec to 0.
|
||||
expected.Nsec = 0
|
||||
}
|
||||
if st.Mtim != expected {
|
||||
t.Errorf("UtimesNanoAt: wrong mtime: expected %v, got %v", expected, st.Mtim)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRlimitAs(t *testing.T) {
|
||||
// disable GC during to avoid flaky test
|
||||
defer debug.SetGCPercent(debug.SetGCPercent(-1))
|
||||
|
||||
var rlim unix.Rlimit
|
||||
err := unix.Getrlimit(unix.RLIMIT_AS, &rlim)
|
||||
if err != nil {
|
||||
t.Fatalf("Getrlimit: %v", err)
|
||||
}
|
||||
var zero unix.Rlimit
|
||||
if zero == rlim {
|
||||
t.Fatalf("Getrlimit: got zero value %#v", rlim)
|
||||
}
|
||||
set := rlim
|
||||
set.Cur = uint64(unix.Getpagesize())
|
||||
err = unix.Setrlimit(unix.RLIMIT_AS, &set)
|
||||
if err != nil {
|
||||
t.Fatalf("Setrlimit: set failed: %#v %v", set, err)
|
||||
}
|
||||
|
||||
// RLIMIT_AS was set to the page size, so mmap()'ing twice the page size
|
||||
// should fail. See 'man 2 getrlimit'.
|
||||
_, err = unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
||||
if err == nil {
|
||||
t.Fatal("Mmap: unexpectedly succeeded after setting RLIMIT_AS")
|
||||
}
|
||||
|
||||
err = unix.Setrlimit(unix.RLIMIT_AS, &rlim)
|
||||
if err != nil {
|
||||
t.Fatalf("Setrlimit: restore failed: %#v %v", rlim, err)
|
||||
}
|
||||
|
||||
b, err := unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
||||
if err != nil {
|
||||
t.Fatalf("Mmap: %v", err)
|
||||
}
|
||||
err = unix.Munmap(b)
|
||||
if err != nil {
|
||||
t.Fatalf("Munmap: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelect(t *testing.T) {
|
||||
_, err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
|
||||
if err != nil {
|
||||
t.Fatalf("Select: %v", err)
|
||||
}
|
||||
|
||||
dur := 150 * time.Millisecond
|
||||
tv := unix.NsecToTimeval(int64(dur))
|
||||
start := time.Now()
|
||||
_, err = unix.Select(0, nil, nil, nil, &tv)
|
||||
took := time.Since(start)
|
||||
if err != nil {
|
||||
t.Fatalf("Select: %v", err)
|
||||
}
|
||||
|
||||
if took < dur {
|
||||
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPselect(t *testing.T) {
|
||||
_, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 0, Nsec: 0}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Pselect: %v", err)
|
||||
}
|
||||
|
||||
dur := 2500 * time.Microsecond
|
||||
ts := unix.NsecToTimespec(int64(dur))
|
||||
start := time.Now()
|
||||
_, err = unix.Pselect(0, nil, nil, nil, &ts, nil)
|
||||
took := time.Since(start)
|
||||
if err != nil {
|
||||
t.Fatalf("Pselect: %v", err)
|
||||
}
|
||||
|
||||
if took < dur {
|
||||
t.Errorf("Pselect: timeout should have been at least %v, got %v", dur, took)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSchedSetaffinity(t *testing.T) {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
var oldMask unix.CPUSet
|
||||
err := unix.SchedGetaffinity(0, &oldMask)
|
||||
if err != nil {
|
||||
t.Fatalf("SchedGetaffinity: %v", err)
|
||||
}
|
||||
|
||||
var newMask unix.CPUSet
|
||||
newMask.Zero()
|
||||
if newMask.Count() != 0 {
|
||||
t.Errorf("CpuZero: didn't zero CPU set: %v", newMask)
|
||||
}
|
||||
cpu := 1
|
||||
newMask.Set(cpu)
|
||||
if newMask.Count() != 1 || !newMask.IsSet(cpu) {
|
||||
t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
|
||||
}
|
||||
cpu = 5
|
||||
newMask.Set(cpu)
|
||||
if newMask.Count() != 2 || !newMask.IsSet(cpu) {
|
||||
t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
|
||||
}
|
||||
newMask.Clear(cpu)
|
||||
if newMask.Count() != 1 || newMask.IsSet(cpu) {
|
||||
t.Errorf("CpuClr: didn't clear CPU %d in set: %v", cpu, newMask)
|
||||
}
|
||||
|
||||
if runtime.NumCPU() < 2 {
|
||||
t.Skip("skipping setaffinity tests on single CPU system")
|
||||
}
|
||||
if runtime.GOOS == "android" {
|
||||
t.Skip("skipping setaffinity tests on android")
|
||||
}
|
||||
|
||||
// On a system like ppc64x where some cores can be disabled using ppc64_cpu,
|
||||
// setaffinity should only be called with enabled cores. The valid cores
|
||||
// are found from the oldMask, but if none are found then the setaffinity
|
||||
// tests are skipped. Issue #27875.
|
||||
if !oldMask.IsSet(cpu) {
|
||||
newMask.Zero()
|
||||
for i := 0; i < len(oldMask); i++ {
|
||||
if oldMask.IsSet(i) {
|
||||
newMask.Set(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if newMask.Count() == 0 {
|
||||
t.Skip("skipping setaffinity tests if CPU not available")
|
||||
}
|
||||
}
|
||||
|
||||
err = unix.SchedSetaffinity(0, &newMask)
|
||||
if err != nil {
|
||||
t.Fatalf("SchedSetaffinity: %v", err)
|
||||
}
|
||||
|
||||
var gotMask unix.CPUSet
|
||||
err = unix.SchedGetaffinity(0, &gotMask)
|
||||
if err != nil {
|
||||
t.Fatalf("SchedGetaffinity: %v", err)
|
||||
}
|
||||
|
||||
if gotMask != newMask {
|
||||
t.Errorf("SchedSetaffinity: returned affinity mask does not match set affinity mask")
|
||||
}
|
||||
|
||||
// Restore old mask so it doesn't affect successive tests
|
||||
err = unix.SchedSetaffinity(0, &oldMask)
|
||||
if err != nil {
|
||||
t.Fatalf("SchedSetaffinity: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatx(t *testing.T) {
|
||||
var stx unix.Statx_t
|
||||
err := unix.Statx(unix.AT_FDCWD, ".", 0, 0, &stx)
|
||||
if err == unix.ENOSYS || err == unix.EPERM {
|
||||
t.Skip("statx syscall is not available, skipping test")
|
||||
} else if err != nil {
|
||||
t.Fatalf("Statx: %v", err)
|
||||
}
|
||||
|
||||
defer chtmpdir(t)()
|
||||
touch(t, "file1")
|
||||
|
||||
var st unix.Stat_t
|
||||
err = unix.Stat("file1", &st)
|
||||
if err != nil {
|
||||
t.Fatalf("Stat: %v", err)
|
||||
}
|
||||
|
||||
flags := unix.AT_STATX_SYNC_AS_STAT
|
||||
err = unix.Statx(unix.AT_FDCWD, "file1", flags, unix.STATX_ALL, &stx)
|
||||
if err != nil {
|
||||
t.Fatalf("Statx: %v", err)
|
||||
}
|
||||
|
||||
if uint32(stx.Mode) != st.Mode {
|
||||
t.Errorf("Statx: returned stat mode does not match Stat")
|
||||
}
|
||||
|
||||
ctime := unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
|
||||
mtime := unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
|
||||
|
||||
if stx.Ctime != ctime {
|
||||
t.Errorf("Statx: returned stat ctime does not match Stat")
|
||||
}
|
||||
if stx.Mtime != mtime {
|
||||
t.Errorf("Statx: returned stat mtime does not match Stat")
|
||||
}
|
||||
|
||||
err = os.Symlink("file1", "symlink1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = unix.Lstat("symlink1", &st)
|
||||
if err != nil {
|
||||
t.Fatalf("Lstat: %v", err)
|
||||
}
|
||||
|
||||
err = unix.Statx(unix.AT_FDCWD, "symlink1", flags, unix.STATX_BASIC_STATS, &stx)
|
||||
if err != nil {
|
||||
t.Fatalf("Statx: %v", err)
|
||||
}
|
||||
|
||||
// follow symlink, expect a regulat file
|
||||
if stx.Mode&unix.S_IFREG == 0 {
|
||||
t.Errorf("Statx: didn't follow symlink")
|
||||
}
|
||||
|
||||
err = unix.Statx(unix.AT_FDCWD, "symlink1", flags|unix.AT_SYMLINK_NOFOLLOW, unix.STATX_ALL, &stx)
|
||||
if err != nil {
|
||||
t.Fatalf("Statx: %v", err)
|
||||
}
|
||||
|
||||
// follow symlink, expect a symlink
|
||||
if stx.Mode&unix.S_IFLNK == 0 {
|
||||
t.Errorf("Statx: unexpectedly followed symlink")
|
||||
}
|
||||
if uint32(stx.Mode) != st.Mode {
|
||||
t.Errorf("Statx: returned stat mode does not match Lstat")
|
||||
}
|
||||
|
||||
ctime = unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
|
||||
mtime = unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
|
||||
|
||||
if stx.Ctime != ctime {
|
||||
t.Errorf("Statx: returned stat ctime does not match Lstat")
|
||||
}
|
||||
if stx.Mtime != mtime {
|
||||
t.Errorf("Statx: returned stat mtime does not match Lstat")
|
||||
}
|
||||
}
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On Linux, each entry is a NULL-terminated string.
|
||||
func stringsFromByteSlice(buf []byte) []string {
|
||||
var result []string
|
||||
off := 0
|
||||
for i, b := range buf {
|
||||
if b == 0 {
|
||||
result = append(result, string(buf[off:i]))
|
||||
off = i + 1
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func TestFaccessat(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
touch(t, "file1")
|
||||
|
||||
err := unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Faccessat: unexpected error: %v", err)
|
||||
}
|
||||
|
||||
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, 2)
|
||||
if err != unix.EINVAL {
|
||||
t.Errorf("Faccessat: unexpected error: %v, want EINVAL", err)
|
||||
}
|
||||
|
||||
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, unix.AT_EACCESS)
|
||||
if err != nil {
|
||||
t.Errorf("Faccessat: unexpected error: %v", err)
|
||||
}
|
||||
|
||||
err = os.Symlink("file1", "symlink1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = unix.Faccessat(unix.AT_FDCWD, "symlink1", unix.R_OK, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != nil {
|
||||
t.Errorf("Faccessat SYMLINK_NOFOLLOW: unexpected error %v", err)
|
||||
}
|
||||
|
||||
// We can't really test AT_SYMLINK_NOFOLLOW, because there
|
||||
// doesn't seem to be any way to change the mode of a symlink.
|
||||
// We don't test AT_EACCESS because such tests are only
|
||||
// meaningful if run as root.
|
||||
|
||||
err = unix.Fchmodat(unix.AT_FDCWD, "file1", 0, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Fchmodat: unexpected error %v", err)
|
||||
}
|
||||
|
||||
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.F_OK, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != nil {
|
||||
t.Errorf("Faccessat: unexpected error: %v", err)
|
||||
}
|
||||
|
||||
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != unix.EACCES {
|
||||
if unix.Getuid() != 0 {
|
||||
t.Errorf("Faccessat: unexpected error: %v, want EACCES", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncFileRange(t *testing.T) {
|
||||
file, err := ioutil.TempFile("", "TestSyncFileRange")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(file.Name())
|
||||
defer file.Close()
|
||||
|
||||
err = unix.SyncFileRange(int(file.Fd()), 0, 0, 0)
|
||||
if err == unix.ENOSYS || err == unix.EPERM {
|
||||
t.Skip("sync_file_range syscall is not available, skipping test")
|
||||
} else if err != nil {
|
||||
t.Fatalf("SyncFileRange: %v", err)
|
||||
}
|
||||
|
||||
// invalid flags
|
||||
flags := 0xf00
|
||||
err = unix.SyncFileRange(int(file.Fd()), 0, 0, flags)
|
||||
if err != unix.EINVAL {
|
||||
t.Fatalf("SyncFileRange: unexpected error: %v, want EINVAL", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClockNanosleep(t *testing.T) {
|
||||
delay := 100 * time.Millisecond
|
||||
|
||||
// Relative timespec.
|
||||
start := time.Now()
|
||||
rel := unix.NsecToTimespec(delay.Nanoseconds())
|
||||
err := unix.ClockNanosleep(unix.CLOCK_MONOTONIC, 0, &rel, nil)
|
||||
if err == unix.ENOSYS || err == unix.EPERM {
|
||||
t.Skip("clock_nanosleep syscall is not available, skipping test")
|
||||
} else if err != nil {
|
||||
t.Errorf("ClockNanosleep(CLOCK_MONOTONIC, 0, %#v, nil) = %v", &rel, err)
|
||||
} else if slept := time.Now().Sub(start); slept < delay {
|
||||
t.Errorf("ClockNanosleep(CLOCK_MONOTONIC, 0, %#v, nil) slept only %v", &rel, slept)
|
||||
}
|
||||
|
||||
// Absolute timespec.
|
||||
start = time.Now()
|
||||
until := start.Add(delay)
|
||||
abs := unix.NsecToTimespec(until.UnixNano())
|
||||
err = unix.ClockNanosleep(unix.CLOCK_REALTIME, unix.TIMER_ABSTIME, &abs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("ClockNanosleep(CLOCK_REALTIME, TIMER_ABSTIME, %#v (=%v), nil) = %v", &abs, until, err)
|
||||
} else if slept := time.Now().Sub(start); slept < delay {
|
||||
t.Errorf("ClockNanosleep(CLOCK_REALTIME, TIMER_ABSTIME, %#v (=%v), nil) slept only %v", &abs, until, slept)
|
||||
}
|
||||
|
||||
// Invalid clock. clock_nanosleep(2) says EINVAL, but it’s actually EOPNOTSUPP.
|
||||
err = unix.ClockNanosleep(unix.CLOCK_THREAD_CPUTIME_ID, 0, &rel, nil)
|
||||
if err != unix.EINVAL && err != unix.EOPNOTSUPP {
|
||||
t.Errorf("ClockNanosleep(CLOCK_THREAD_CPUTIME_ID, 0, %#v, nil) = %v, want EINVAL or EOPNOTSUPP", &rel, err)
|
||||
}
|
||||
}
|
51
vendor/golang.org/x/sys/unix/syscall_netbsd_test.go
generated
vendored
51
vendor/golang.org/x/sys/unix/syscall_netbsd_test.go
generated
vendored
@ -1,51 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On NetBSD, each entry consists of a single byte containing the length
|
||||
// of the attribute name, followed by the attribute name.
|
||||
// The name is _not_ NULL-terminated.
|
||||
func stringsFromByteSlice(buf []byte) []string {
|
||||
var result []string
|
||||
i := 0
|
||||
for i < len(buf) {
|
||||
next := i + 1 + int(buf[i])
|
||||
result = append(result, string(buf[i+1:next]))
|
||||
i = next
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func TestSysctlClockinfo(t *testing.T) {
|
||||
ci, err := unix.SysctlClockinfo("kern.clockrate")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("tick = %v, tickadj = %v, hz = %v, profhz = %v, stathz = %v",
|
||||
ci.Tick, ci.Tickadj, ci.Hz, ci.Profhz, ci.Stathz)
|
||||
}
|
||||
|
||||
func TestIoctlPtmget(t *testing.T) {
|
||||
fd, err := unix.Open("/dev/ptmx", unix.O_NOCTTY|unix.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
t.Skip("failed to open /dev/ptmx, skipping test")
|
||||
}
|
||||
defer unix.Close(fd)
|
||||
|
||||
ptm, err := unix.IoctlGetPtmget(fd, unix.TIOCPTSNAME)
|
||||
if err != nil {
|
||||
t.Fatalf("IoctlGetPtmget: %v\n", err)
|
||||
}
|
||||
|
||||
t.Logf("sfd = %v, ptsname = %v", ptm.Sfd, string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]))
|
||||
}
|
49
vendor/golang.org/x/sys/unix/syscall_openbsd_test.go
generated
vendored
49
vendor/golang.org/x/sys/unix/syscall_openbsd_test.go
generated
vendored
@ -1,49 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestPpoll(t *testing.T) {
|
||||
f, cleanup := mktmpfifo(t)
|
||||
defer cleanup()
|
||||
|
||||
const timeout = 100 * time.Millisecond
|
||||
|
||||
ok := make(chan bool, 1)
|
||||
go func() {
|
||||
select {
|
||||
case <-time.After(10 * timeout):
|
||||
t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
|
||||
case <-ok:
|
||||
}
|
||||
}()
|
||||
|
||||
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
|
||||
timeoutTs := unix.NsecToTimespec(int64(timeout))
|
||||
n, err := unix.Ppoll(fds, &timeoutTs, nil)
|
||||
ok <- true
|
||||
if err != nil {
|
||||
t.Errorf("Ppoll: unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
if n != 0 {
|
||||
t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestSysctlUvmexp(t *testing.T) {
|
||||
uvm, err := unix.SysctlUvmexp("vm.uvmexp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("free = %v", uvm.Free)
|
||||
}
|
55
vendor/golang.org/x/sys/unix/syscall_solaris_test.go
generated
vendored
55
vendor/golang.org/x/sys/unix/syscall_solaris_test.go
generated
vendored
@ -1,55 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// +build solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestSelect(t *testing.T) {
|
||||
err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
|
||||
if err != nil {
|
||||
t.Fatalf("Select: %v", err)
|
||||
}
|
||||
|
||||
dur := 150 * time.Millisecond
|
||||
tv := unix.NsecToTimeval(int64(dur))
|
||||
start := time.Now()
|
||||
err = unix.Select(0, nil, nil, nil, &tv)
|
||||
took := time.Since(start)
|
||||
if err != nil {
|
||||
t.Fatalf("Select: %v", err)
|
||||
}
|
||||
|
||||
if took < dur {
|
||||
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatvfs(t *testing.T) {
|
||||
if err := unix.Statvfs("", nil); err == nil {
|
||||
t.Fatal(`Statvfs("") expected failure`)
|
||||
}
|
||||
|
||||
statvfs := unix.Statvfs_t{}
|
||||
if err := unix.Statvfs("/", &statvfs); err != nil {
|
||||
t.Errorf(`Statvfs("/") failed: %v`, err)
|
||||
}
|
||||
|
||||
if t.Failed() {
|
||||
mount, err := exec.Command("mount").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("mount: %v\n%s", err, mount)
|
||||
} else {
|
||||
t.Logf("mount: %s", mount)
|
||||
}
|
||||
}
|
||||
}
|
60
vendor/golang.org/x/sys/unix/syscall_test.go
generated
vendored
60
vendor/golang.org/x/sys/unix/syscall_test.go
generated
vendored
@ -1,60 +0,0 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func testSetGetenv(t *testing.T, key, value string) {
|
||||
err := unix.Setenv(key, value)
|
||||
if err != nil {
|
||||
t.Fatalf("Setenv failed to set %q: %v", value, err)
|
||||
}
|
||||
newvalue, found := unix.Getenv(key)
|
||||
if !found {
|
||||
t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value)
|
||||
}
|
||||
if newvalue != value {
|
||||
t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
testSetGetenv(t, "TESTENV", "AVALUE")
|
||||
// make sure TESTENV gets set to "", not deleted
|
||||
testSetGetenv(t, "TESTENV", "")
|
||||
}
|
||||
|
||||
func TestItoa(t *testing.T) {
|
||||
// Make most negative integer: 0x8000...
|
||||
i := 1
|
||||
for i<<1 != 0 {
|
||||
i <<= 1
|
||||
}
|
||||
if i >= 0 {
|
||||
t.Fatal("bad math")
|
||||
}
|
||||
s := unix.Itoa(i)
|
||||
f := fmt.Sprint(i)
|
||||
if s != f {
|
||||
t.Fatalf("itoa(%d) = %s, want %s", i, s, f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUname(t *testing.T) {
|
||||
var utsname unix.Utsname
|
||||
err := unix.Uname(&utsname)
|
||||
if err != nil {
|
||||
t.Fatalf("Uname: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("OS: %s/%s %s", utsname.Sysname[:], utsname.Machine[:], utsname.Release[:])
|
||||
}
|
677
vendor/golang.org/x/sys/unix/syscall_unix_test.go
generated
vendored
677
vendor/golang.org/x/sys/unix/syscall_unix_test.go
generated
vendored
@ -1,677 +0,0 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"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, "EPERM"},
|
||||
{syscall.EINVAL, "EINVAL"},
|
||||
{syscall.ENOENT, "ENOENT"},
|
||||
}
|
||||
|
||||
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 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 runtime.GOOS == "aix" {
|
||||
t.Skip("getsockname issue on AIX 7.2 tl1, skipping test")
|
||||
}
|
||||
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
|
||||
passFDChild()
|
||||
return
|
||||
}
|
||||
|
||||
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 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)
|
||||
}
|
||||
|
||||
err = unix.Dup2(newFd, newFd+1)
|
||||
if err != nil {
|
||||
t.Fatalf("Dup2: %v", err)
|
||||
}
|
||||
|
||||
b1 := []byte("Test123")
|
||||
b2 := make([]byte, 7)
|
||||
_, err = unix.Write(newFd+1, 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 TestPoll(t *testing.T) {
|
||||
if runtime.GOOS == "android" ||
|
||||
(runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64")) {
|
||||
t.Skip("mkfifo syscall is not available on android and iOS, skipping test")
|
||||
}
|
||||
|
||||
f, cleanup := mktmpfifo(t)
|
||||
defer cleanup()
|
||||
|
||||
const timeout = 100
|
||||
|
||||
ok := make(chan bool, 1)
|
||||
go func() {
|
||||
select {
|
||||
case <-time.After(10 * timeout * time.Millisecond):
|
||||
t.Errorf("Poll: failed to timeout after %d milliseconds", 10*timeout)
|
||||
case <-ok:
|
||||
}
|
||||
}()
|
||||
|
||||
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
|
||||
n, err := unix.Poll(fds, timeout)
|
||||
ok <- true
|
||||
if err != nil {
|
||||
t.Errorf("Poll: unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
if n != 0 {
|
||||
t.Errorf("Poll: wrong number of events: got %v, expected %v", n, 0)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
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 TestFstatat(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
touch(t, "file1")
|
||||
|
||||
var st1 unix.Stat_t
|
||||
err := unix.Stat("file1", &st1)
|
||||
if err != nil {
|
||||
t.Fatalf("Stat: %v", err)
|
||||
}
|
||||
|
||||
var st2 unix.Stat_t
|
||||
err = unix.Fstatat(unix.AT_FDCWD, "file1", &st2, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Fstatat: %v", err)
|
||||
}
|
||||
|
||||
if st1 != st2 {
|
||||
t.Errorf("Fstatat: returned stat does not match Stat")
|
||||
}
|
||||
|
||||
err = os.Symlink("file1", "symlink1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = unix.Lstat("symlink1", &st1)
|
||||
if err != nil {
|
||||
t.Fatalf("Lstat: %v", err)
|
||||
}
|
||||
|
||||
err = unix.Fstatat(unix.AT_FDCWD, "symlink1", &st2, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != nil {
|
||||
t.Fatalf("Fstatat: %v", err)
|
||||
}
|
||||
|
||||
if st1 != st2 {
|
||||
t.Errorf("Fstatat: returned stat does not match Lstat")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFchmodat(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
touch(t, "file1")
|
||||
err := os.Symlink("file1", "symlink1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mode := os.FileMode(0444)
|
||||
err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", uint32(mode), 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Fchmodat: unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat("file1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if fi.Mode() != mode {
|
||||
t.Errorf("Fchmodat: failed to change file mode: expected %v, got %v", mode, fi.Mode())
|
||||
}
|
||||
|
||||
mode = os.FileMode(0644)
|
||||
didChmodSymlink := true
|
||||
err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", uint32(mode), unix.AT_SYMLINK_NOFOLLOW)
|
||||
if err != nil {
|
||||
if (runtime.GOOS == "android" || runtime.GOOS == "linux" || runtime.GOOS == "solaris") && err == unix.EOPNOTSUPP {
|
||||
// Linux and Illumos don't support flags != 0
|
||||
didChmodSymlink = false
|
||||
} else {
|
||||
t.Fatalf("Fchmodat: unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !didChmodSymlink {
|
||||
// Didn't change mode of the symlink. On Linux, the permissions
|
||||
// of a symbolic link are always 0777 according to symlink(7)
|
||||
mode = os.FileMode(0777)
|
||||
}
|
||||
|
||||
var st unix.Stat_t
|
||||
err = unix.Lstat("symlink1", &st)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
got := os.FileMode(st.Mode & 0777)
|
||||
if got != mode {
|
||||
t.Errorf("Fchmodat: failed to change symlink mode: expected %v, got %v", mode, got)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
54
vendor/golang.org/x/sys/unix/timestruct_test.go
generated
vendored
54
vendor/golang.org/x/sys/unix/timestruct_test.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All right reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestTimeToTimespec(t *testing.T) {
|
||||
timeTests := []struct {
|
||||
time time.Time
|
||||
valid bool
|
||||
}{
|
||||
{time.Unix(0, 0), true},
|
||||
{time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), true},
|
||||
{time.Date(2262, time.December, 31, 23, 0, 0, 0, time.UTC), false},
|
||||
{time.Unix(0x7FFFFFFF, 0), true},
|
||||
{time.Unix(0x80000000, 0), false},
|
||||
{time.Unix(0x7FFFFFFF, 1000000000), false},
|
||||
{time.Unix(0x7FFFFFFF, 999999999), true},
|
||||
{time.Unix(-0x80000000, 0), true},
|
||||
{time.Unix(-0x80000001, 0), false},
|
||||
{time.Date(2038, time.January, 19, 3, 14, 7, 0, time.UTC), true},
|
||||
{time.Date(2038, time.January, 19, 3, 14, 8, 0, time.UTC), false},
|
||||
{time.Date(1901, time.December, 13, 20, 45, 52, 0, time.UTC), true},
|
||||
{time.Date(1901, time.December, 13, 20, 45, 51, 0, time.UTC), false},
|
||||
}
|
||||
|
||||
// Currently all targets have either int32 or int64 for Timespec.Sec.
|
||||
// If there were a new target with unsigned or floating point type for
|
||||
// it, this test must be adjusted.
|
||||
have64BitTime := (unsafe.Sizeof(unix.Timespec{}.Sec) == 8)
|
||||
for _, tt := range timeTests {
|
||||
ts, err := unix.TimeToTimespec(tt.time)
|
||||
tt.valid = tt.valid || have64BitTime
|
||||
if tt.valid && err != nil {
|
||||
t.Errorf("TimeToTimespec(%v): %v", tt.time, err)
|
||||
}
|
||||
if err == nil {
|
||||
tstime := time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||
if !tstime.Equal(tt.time) {
|
||||
t.Errorf("TimeToTimespec(%v) is the time %v", tt.time, tstime)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
207
vendor/golang.org/x/sys/unix/xattr_test.go
generated
vendored
207
vendor/golang.org/x/sys/unix/xattr_test.go
generated
vendored
@ -1,207 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build darwin freebsd linux netbsd
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestXattr(t *testing.T) {
|
||||
defer chtmpdir(t)()
|
||||
|
||||
f := "xattr1"
|
||||
touch(t, f)
|
||||
|
||||
xattrName := "user.test"
|
||||
xattrDataSet := "gopher"
|
||||
|
||||
err := unix.Setxattr(f, xattrName, []byte{}, 0)
|
||||
if err == unix.ENOTSUP || err == unix.EOPNOTSUPP {
|
||||
t.Skip("filesystem does not support extended attributes, skipping test")
|
||||
} else if err != nil {
|
||||
t.Fatalf("Setxattr: %v", err)
|
||||
}
|
||||
|
||||
err = unix.Setxattr(f, xattrName, []byte(xattrDataSet), 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Setxattr: %v", err)
|
||||
}
|
||||
|
||||
// find size
|
||||
size, err := unix.Listxattr(f, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Listxattr: %v", err)
|
||||
}
|
||||
|
||||
if size <= 0 {
|
||||
t.Fatalf("Listxattr returned an empty list of attributes")
|
||||
}
|
||||
|
||||
buf := make([]byte, size)
|
||||
read, err := unix.Listxattr(f, buf)
|
||||
if err != nil {
|
||||
t.Fatalf("Listxattr: %v", err)
|
||||
}
|
||||
|
||||
xattrs := stringsFromByteSlice(buf[:read])
|
||||
|
||||
xattrWant := xattrName
|
||||
if runtime.GOOS == "freebsd" {
|
||||
// On FreeBSD, the namespace is stored separately from the xattr
|
||||
// name and Listxattr doesn't return the namespace prefix.
|
||||
xattrWant = strings.TrimPrefix(xattrWant, "user.")
|
||||
}
|
||||
found := false
|
||||
for _, name := range xattrs {
|
||||
if name == xattrWant {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Errorf("Listxattr did not return previously set attribute '%s'", xattrName)
|
||||
}
|
||||
|
||||
// find size
|
||||
size, err = unix.Getxattr(f, xattrName, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Getxattr: %v", err)
|
||||
}
|
||||
|
||||
if size <= 0 {
|
||||
t.Fatalf("Getxattr returned an empty attribute")
|
||||
}
|
||||
|
||||
xattrDataGet := make([]byte, size)
|
||||
_, err = unix.Getxattr(f, xattrName, xattrDataGet)
|
||||
if err != nil {
|
||||
t.Fatalf("Getxattr: %v", err)
|
||||
}
|
||||
|
||||
got := string(xattrDataGet)
|
||||
if got != xattrDataSet {
|
||||
t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got)
|
||||
}
|
||||
|
||||
err = unix.Removexattr(f, xattrName)
|
||||
if err != nil {
|
||||
t.Fatalf("Removexattr: %v", err)
|
||||
}
|
||||
|
||||
n := "nonexistent"
|
||||
err = unix.Lsetxattr(n, xattrName, []byte(xattrDataSet), 0)
|
||||
if err != unix.ENOENT {
|
||||
t.Errorf("Lsetxattr: expected %v on non-existent file, got %v", unix.ENOENT, err)
|
||||
}
|
||||
|
||||
_, err = unix.Lgetxattr(n, xattrName, nil)
|
||||
if err != unix.ENOENT {
|
||||
t.Errorf("Lgetxattr: %v", err)
|
||||
}
|
||||
|
||||
s := "symlink1"
|
||||
err = os.Symlink(n, s)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = unix.Lsetxattr(s, xattrName, []byte(xattrDataSet), 0)
|
||||
if err != nil {
|
||||
// Linux and Android doen't support xattrs on symlinks according
|
||||
// to xattr(7), so just test that we get the proper error.
|
||||
if (runtime.GOOS != "linux" && runtime.GOOS != "android") || err != unix.EPERM {
|
||||
t.Fatalf("Lsetxattr: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFdXattr(t *testing.T) {
|
||||
file, err := ioutil.TempFile("", "TestFdXattr")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(file.Name())
|
||||
defer file.Close()
|
||||
|
||||
fd := int(file.Fd())
|
||||
xattrName := "user.test"
|
||||
xattrDataSet := "gopher"
|
||||
|
||||
err = unix.Fsetxattr(fd, xattrName, []byte(xattrDataSet), 0)
|
||||
if err == unix.ENOTSUP || err == unix.EOPNOTSUPP {
|
||||
t.Skip("filesystem does not support extended attributes, skipping test")
|
||||
} else if err != nil {
|
||||
t.Fatalf("Fsetxattr: %v", err)
|
||||
}
|
||||
|
||||
// find size
|
||||
size, err := unix.Flistxattr(fd, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Flistxattr: %v", err)
|
||||
}
|
||||
|
||||
if size <= 0 {
|
||||
t.Fatalf("Flistxattr returned an empty list of attributes")
|
||||
}
|
||||
|
||||
buf := make([]byte, size)
|
||||
read, err := unix.Flistxattr(fd, buf)
|
||||
if err != nil {
|
||||
t.Fatalf("Flistxattr: %v", err)
|
||||
}
|
||||
|
||||
xattrs := stringsFromByteSlice(buf[:read])
|
||||
|
||||
xattrWant := xattrName
|
||||
if runtime.GOOS == "freebsd" {
|
||||
// On FreeBSD, the namespace is stored separately from the xattr
|
||||
// name and Listxattr doesn't return the namespace prefix.
|
||||
xattrWant = strings.TrimPrefix(xattrWant, "user.")
|
||||
}
|
||||
found := false
|
||||
for _, name := range xattrs {
|
||||
if name == xattrWant {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Errorf("Flistxattr did not return previously set attribute '%s'", xattrName)
|
||||
}
|
||||
|
||||
// find size
|
||||
size, err = unix.Fgetxattr(fd, xattrName, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Fgetxattr: %v", err)
|
||||
}
|
||||
|
||||
if size <= 0 {
|
||||
t.Fatalf("Fgetxattr returned an empty attribute")
|
||||
}
|
||||
|
||||
xattrDataGet := make([]byte, size)
|
||||
_, err = unix.Fgetxattr(fd, xattrName, xattrDataGet)
|
||||
if err != nil {
|
||||
t.Fatalf("Fgetxattr: %v", err)
|
||||
}
|
||||
|
||||
got := string(xattrDataGet)
|
||||
if got != xattrDataSet {
|
||||
t.Errorf("Fgetxattr: expected attribute value %s, got %s", xattrDataSet, got)
|
||||
}
|
||||
|
||||
err = unix.Fremovexattr(fd, xattrName)
|
||||
if err != nil {
|
||||
t.Fatalf("Fremovexattr: %v", err)
|
||||
}
|
||||
}
|
11
vendor/golang.org/x/sys/windows/registry/export_test.go
generated
vendored
11
vendor/golang.org/x/sys/windows/registry/export_test.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package registry
|
||||
|
||||
func (k Key) SetValue(name string, valtype uint32, data []byte) error {
|
||||
return k.setValue(name, valtype, data)
|
||||
}
|
198
vendor/golang.org/x/sys/windows/registry/key.go
generated
vendored
198
vendor/golang.org/x/sys/windows/registry/key.go
generated
vendored
@ -1,198 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
// Package registry provides access to the Windows registry.
|
||||
//
|
||||
// Here is a simple example, opening a registry key and reading a string value from it.
|
||||
//
|
||||
// k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// defer k.Close()
|
||||
//
|
||||
// s, _, err := k.GetStringValue("SystemRoot")
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// fmt.Printf("Windows system root is %q\n", s)
|
||||
//
|
||||
package registry
|
||||
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// Registry key security and access rights.
|
||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
|
||||
// for details.
|
||||
ALL_ACCESS = 0xf003f
|
||||
CREATE_LINK = 0x00020
|
||||
CREATE_SUB_KEY = 0x00004
|
||||
ENUMERATE_SUB_KEYS = 0x00008
|
||||
EXECUTE = 0x20019
|
||||
NOTIFY = 0x00010
|
||||
QUERY_VALUE = 0x00001
|
||||
READ = 0x20019
|
||||
SET_VALUE = 0x00002
|
||||
WOW64_32KEY = 0x00200
|
||||
WOW64_64KEY = 0x00100
|
||||
WRITE = 0x20006
|
||||
)
|
||||
|
||||
// Key is a handle to an open Windows registry key.
|
||||
// Keys can be obtained by calling OpenKey; there are
|
||||
// also some predefined root keys such as CURRENT_USER.
|
||||
// Keys can be used directly in the Windows API.
|
||||
type Key syscall.Handle
|
||||
|
||||
const (
|
||||
// Windows defines some predefined root keys that are always open.
|
||||
// An application can use these keys as entry points to the registry.
|
||||
// Normally these keys are used in OpenKey to open new keys,
|
||||
// but they can also be used anywhere a Key is required.
|
||||
CLASSES_ROOT = Key(syscall.HKEY_CLASSES_ROOT)
|
||||
CURRENT_USER = Key(syscall.HKEY_CURRENT_USER)
|
||||
LOCAL_MACHINE = Key(syscall.HKEY_LOCAL_MACHINE)
|
||||
USERS = Key(syscall.HKEY_USERS)
|
||||
CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG)
|
||||
PERFORMANCE_DATA = Key(syscall.HKEY_PERFORMANCE_DATA)
|
||||
)
|
||||
|
||||
// Close closes open key k.
|
||||
func (k Key) Close() error {
|
||||
return syscall.RegCloseKey(syscall.Handle(k))
|
||||
}
|
||||
|
||||
// OpenKey opens a new key with path name relative to key k.
|
||||
// It accepts any open key, including CURRENT_USER and others,
|
||||
// and returns the new key and an error.
|
||||
// The access parameter specifies desired access rights to the
|
||||
// key to be opened.
|
||||
func OpenKey(k Key, path string, access uint32) (Key, error) {
|
||||
p, err := syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var subkey syscall.Handle
|
||||
err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return Key(subkey), nil
|
||||
}
|
||||
|
||||
// OpenRemoteKey opens a predefined registry key on another
|
||||
// computer pcname. The key to be opened is specified by k, but
|
||||
// can only be one of LOCAL_MACHINE, PERFORMANCE_DATA or USERS.
|
||||
// If pcname is "", OpenRemoteKey returns local computer key.
|
||||
func OpenRemoteKey(pcname string, k Key) (Key, error) {
|
||||
var err error
|
||||
var p *uint16
|
||||
if pcname != "" {
|
||||
p, err = syscall.UTF16PtrFromString(`\\` + pcname)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
var remoteKey syscall.Handle
|
||||
err = regConnectRegistry(p, syscall.Handle(k), &remoteKey)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return Key(remoteKey), nil
|
||||
}
|
||||
|
||||
// ReadSubKeyNames returns the names of subkeys of key k.
|
||||
// The parameter n controls the number of returned names,
|
||||
// analogous to the way os.File.Readdirnames works.
|
||||
func (k Key) ReadSubKeyNames(n int) ([]string, error) {
|
||||
names := make([]string, 0)
|
||||
// Registry key size limit is 255 bytes and described there:
|
||||
// https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx
|
||||
buf := make([]uint16, 256) //plus extra room for terminating zero byte
|
||||
loopItems:
|
||||
for i := uint32(0); ; i++ {
|
||||
if n > 0 {
|
||||
if len(names) == n {
|
||||
return names, nil
|
||||
}
|
||||
}
|
||||
l := uint32(len(buf))
|
||||
for {
|
||||
err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if err == syscall.ERROR_MORE_DATA {
|
||||
// Double buffer size and try again.
|
||||
l = uint32(2 * len(buf))
|
||||
buf = make([]uint16, l)
|
||||
continue
|
||||
}
|
||||
if err == _ERROR_NO_MORE_ITEMS {
|
||||
break loopItems
|
||||
}
|
||||
return names, err
|
||||
}
|
||||
names = append(names, syscall.UTF16ToString(buf[:l]))
|
||||
}
|
||||
if n > len(names) {
|
||||
return names, io.EOF
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
// CreateKey creates a key named path under open key k.
|
||||
// CreateKey returns the new key and a boolean flag that reports
|
||||
// whether the key already existed.
|
||||
// The access parameter specifies the access rights for the key
|
||||
// to be created.
|
||||
func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
|
||||
var h syscall.Handle
|
||||
var d uint32
|
||||
err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
|
||||
0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
return Key(h), d == _REG_OPENED_EXISTING_KEY, nil
|
||||
}
|
||||
|
||||
// DeleteKey deletes the subkey path of key k and its values.
|
||||
func DeleteKey(k Key, path string) error {
|
||||
return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
|
||||
}
|
||||
|
||||
// A KeyInfo describes the statistics of a key. It is returned by Stat.
|
||||
type KeyInfo struct {
|
||||
SubKeyCount uint32
|
||||
MaxSubKeyLen uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
|
||||
ValueCount uint32
|
||||
MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
|
||||
MaxValueLen uint32 // longest data component among the key's values, in bytes
|
||||
lastWriteTime syscall.Filetime
|
||||
}
|
||||
|
||||
// ModTime returns the key's last write time.
|
||||
func (ki *KeyInfo) ModTime() time.Time {
|
||||
return time.Unix(0, ki.lastWriteTime.Nanoseconds())
|
||||
}
|
||||
|
||||
// Stat retrieves information about the open key k.
|
||||
func (k Key) Stat() (*KeyInfo, error) {
|
||||
var ki KeyInfo
|
||||
err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil,
|
||||
&ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount,
|
||||
&ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ki, nil
|
||||
}
|
7
vendor/golang.org/x/sys/windows/registry/mksyscall.go
generated
vendored
7
vendor/golang.org/x/sys/windows/registry/mksyscall.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
package registry
|
||||
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go
|
756
vendor/golang.org/x/sys/windows/registry/registry_test.go
generated
vendored
756
vendor/golang.org/x/sys/windows/registry/registry_test.go
generated
vendored
@ -1,756 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package registry_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
func randKeyName(prefix string) string {
|
||||
const numbers = "0123456789"
|
||||
buf := make([]byte, 10)
|
||||
rand.Read(buf)
|
||||
for i, b := range buf {
|
||||
buf[i] = numbers[b%byte(len(numbers))]
|
||||
}
|
||||
return prefix + string(buf)
|
||||
}
|
||||
|
||||
func TestReadSubKeyNames(t *testing.T) {
|
||||
k, err := registry.OpenKey(registry.CLASSES_ROOT, "TypeLib", registry.ENUMERATE_SUB_KEYS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer k.Close()
|
||||
|
||||
names, err := k.ReadSubKeyNames(-1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var foundStdOle bool
|
||||
for _, name := range names {
|
||||
// Every PC has "stdole 2.0 OLE Automation" library installed.
|
||||
if name == "{00020430-0000-0000-C000-000000000046}" {
|
||||
foundStdOle = true
|
||||
}
|
||||
}
|
||||
if !foundStdOle {
|
||||
t.Fatal("could not find stdole 2.0 OLE Automation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOpenDeleteKey(t *testing.T) {
|
||||
k, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer k.Close()
|
||||
|
||||
testKName := randKeyName("TestCreateOpenDeleteKey_")
|
||||
|
||||
testK, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testK.Close()
|
||||
|
||||
if exist {
|
||||
t.Fatalf("key %q already exists", testKName)
|
||||
}
|
||||
|
||||
testKAgain, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testKAgain.Close()
|
||||
|
||||
if !exist {
|
||||
t.Fatalf("key %q should already exist", testKName)
|
||||
}
|
||||
|
||||
testKOpened, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testKOpened.Close()
|
||||
|
||||
err = registry.DeleteKey(k, testKName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testKOpenedAgain, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS)
|
||||
if err == nil {
|
||||
defer testKOpenedAgain.Close()
|
||||
t.Fatalf("key %q should already been deleted", testKName)
|
||||
}
|
||||
if err != registry.ErrNotExist {
|
||||
t.Fatalf(`unexpected error ("not exist" expected): %v`, err)
|
||||
}
|
||||
}
|
||||
|
||||
func equalStringSlice(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
if a == nil {
|
||||
return true
|
||||
}
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type ValueTest struct {
|
||||
Type uint32
|
||||
Name string
|
||||
Value interface{}
|
||||
WillFail bool
|
||||
}
|
||||
|
||||
var ValueTests = []ValueTest{
|
||||
{Type: registry.SZ, Name: "String1", Value: ""},
|
||||
{Type: registry.SZ, Name: "String2", Value: "\000", WillFail: true},
|
||||
{Type: registry.SZ, Name: "String3", Value: "Hello World"},
|
||||
{Type: registry.SZ, Name: "String4", Value: "Hello World\000", WillFail: true},
|
||||
{Type: registry.EXPAND_SZ, Name: "ExpString1", Value: ""},
|
||||
{Type: registry.EXPAND_SZ, Name: "ExpString2", Value: "\000", WillFail: true},
|
||||
{Type: registry.EXPAND_SZ, Name: "ExpString3", Value: "Hello World"},
|
||||
{Type: registry.EXPAND_SZ, Name: "ExpString4", Value: "Hello\000World", WillFail: true},
|
||||
{Type: registry.EXPAND_SZ, Name: "ExpString5", Value: "%PATH%"},
|
||||
{Type: registry.EXPAND_SZ, Name: "ExpString6", Value: "%NO_SUCH_VARIABLE%"},
|
||||
{Type: registry.EXPAND_SZ, Name: "ExpString7", Value: "%PATH%;."},
|
||||
{Type: registry.BINARY, Name: "Binary1", Value: []byte{}},
|
||||
{Type: registry.BINARY, Name: "Binary2", Value: []byte{1, 2, 3}},
|
||||
{Type: registry.BINARY, Name: "Binary3", Value: []byte{3, 2, 1, 0, 1, 2, 3}},
|
||||
{Type: registry.DWORD, Name: "Dword1", Value: uint64(0)},
|
||||
{Type: registry.DWORD, Name: "Dword2", Value: uint64(1)},
|
||||
{Type: registry.DWORD, Name: "Dword3", Value: uint64(0xff)},
|
||||
{Type: registry.DWORD, Name: "Dword4", Value: uint64(0xffff)},
|
||||
{Type: registry.QWORD, Name: "Qword1", Value: uint64(0)},
|
||||
{Type: registry.QWORD, Name: "Qword2", Value: uint64(1)},
|
||||
{Type: registry.QWORD, Name: "Qword3", Value: uint64(0xff)},
|
||||
{Type: registry.QWORD, Name: "Qword4", Value: uint64(0xffff)},
|
||||
{Type: registry.QWORD, Name: "Qword5", Value: uint64(0xffffff)},
|
||||
{Type: registry.QWORD, Name: "Qword6", Value: uint64(0xffffffff)},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString1", Value: []string{"a", "b", "c"}},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString2", Value: []string{"abc", "", "cba"}},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString3", Value: []string{""}},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString4", Value: []string{"abcdef"}},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString5", Value: []string{"\000"}, WillFail: true},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString6", Value: []string{"a\000b"}, WillFail: true},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString7", Value: []string{"ab", "\000", "cd"}, WillFail: true},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString8", Value: []string{"\000", "cd"}, WillFail: true},
|
||||
{Type: registry.MULTI_SZ, Name: "MultiString9", Value: []string{"ab", "\000"}, WillFail: true},
|
||||
}
|
||||
|
||||
func setValues(t *testing.T, k registry.Key) {
|
||||
for _, test := range ValueTests {
|
||||
var err error
|
||||
switch test.Type {
|
||||
case registry.SZ:
|
||||
err = k.SetStringValue(test.Name, test.Value.(string))
|
||||
case registry.EXPAND_SZ:
|
||||
err = k.SetExpandStringValue(test.Name, test.Value.(string))
|
||||
case registry.MULTI_SZ:
|
||||
err = k.SetStringsValue(test.Name, test.Value.([]string))
|
||||
case registry.BINARY:
|
||||
err = k.SetBinaryValue(test.Name, test.Value.([]byte))
|
||||
case registry.DWORD:
|
||||
err = k.SetDWordValue(test.Name, uint32(test.Value.(uint64)))
|
||||
case registry.QWORD:
|
||||
err = k.SetQWordValue(test.Name, test.Value.(uint64))
|
||||
default:
|
||||
t.Fatalf("unsupported type %d for %s value", test.Type, test.Name)
|
||||
}
|
||||
if test.WillFail {
|
||||
if err == nil {
|
||||
t.Fatalf("setting %s value %q should fail, but succeeded", test.Name, test.Value)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func enumerateValues(t *testing.T, k registry.Key) {
|
||||
names, err := k.ReadValueNames(-1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
haveNames := make(map[string]bool)
|
||||
for _, n := range names {
|
||||
haveNames[n] = false
|
||||
}
|
||||
for _, test := range ValueTests {
|
||||
wantFound := !test.WillFail
|
||||
_, haveFound := haveNames[test.Name]
|
||||
if wantFound && !haveFound {
|
||||
t.Errorf("value %s is not found while enumerating", test.Name)
|
||||
}
|
||||
if haveFound && !wantFound {
|
||||
t.Errorf("value %s is found while enumerating, but expected to fail", test.Name)
|
||||
}
|
||||
if haveFound {
|
||||
delete(haveNames, test.Name)
|
||||
}
|
||||
}
|
||||
for n, v := range haveNames {
|
||||
t.Errorf("value %s (%v) is found while enumerating, but has not been cretaed", n, v)
|
||||
}
|
||||
}
|
||||
|
||||
func testErrNotExist(t *testing.T, name string, err error) {
|
||||
if err == nil {
|
||||
t.Errorf("%s value should not exist", name)
|
||||
return
|
||||
}
|
||||
if err != registry.ErrNotExist {
|
||||
t.Errorf("reading %s value should return 'not exist' error, but got: %s", name, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testErrUnexpectedType(t *testing.T, test ValueTest, gottype uint32, err error) {
|
||||
if err == nil {
|
||||
t.Errorf("GetXValue(%q) should not succeed", test.Name)
|
||||
return
|
||||
}
|
||||
if err != registry.ErrUnexpectedType {
|
||||
t.Errorf("reading %s value should return 'unexpected key value type' error, but got: %s", test.Name, err)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testGetStringValue(t *testing.T, k registry.Key, test ValueTest) {
|
||||
got, gottype, err := k.GetStringValue(test.Name)
|
||||
if err != nil {
|
||||
t.Errorf("GetStringValue(%s) failed: %v", test.Name, err)
|
||||
return
|
||||
}
|
||||
if got != test.Value {
|
||||
t.Errorf("want %s value %q, got %q", test.Name, test.Value, got)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
if gottype == registry.EXPAND_SZ {
|
||||
_, err = registry.ExpandString(got)
|
||||
if err != nil {
|
||||
t.Errorf("ExpandString(%s) failed: %v", got, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testGetIntegerValue(t *testing.T, k registry.Key, test ValueTest) {
|
||||
got, gottype, err := k.GetIntegerValue(test.Name)
|
||||
if err != nil {
|
||||
t.Errorf("GetIntegerValue(%s) failed: %v", test.Name, err)
|
||||
return
|
||||
}
|
||||
if got != test.Value.(uint64) {
|
||||
t.Errorf("want %s value %v, got %v", test.Name, test.Value, got)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testGetBinaryValue(t *testing.T, k registry.Key, test ValueTest) {
|
||||
got, gottype, err := k.GetBinaryValue(test.Name)
|
||||
if err != nil {
|
||||
t.Errorf("GetBinaryValue(%s) failed: %v", test.Name, err)
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(got, test.Value.([]byte)) {
|
||||
t.Errorf("want %s value %v, got %v", test.Name, test.Value, got)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testGetStringsValue(t *testing.T, k registry.Key, test ValueTest) {
|
||||
got, gottype, err := k.GetStringsValue(test.Name)
|
||||
if err != nil {
|
||||
t.Errorf("GetStringsValue(%s) failed: %v", test.Name, err)
|
||||
return
|
||||
}
|
||||
if !equalStringSlice(got, test.Value.([]string)) {
|
||||
t.Errorf("want %s value %#v, got %#v", test.Name, test.Value, got)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testGetValue(t *testing.T, k registry.Key, test ValueTest, size int) {
|
||||
if size <= 0 {
|
||||
return
|
||||
}
|
||||
// read data with no buffer
|
||||
gotsize, gottype, err := k.GetValue(test.Name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err)
|
||||
return
|
||||
}
|
||||
if gotsize != size {
|
||||
t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
// read data with short buffer
|
||||
gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size-1))
|
||||
if err == nil {
|
||||
t.Errorf("GetValue(%s, [%d]byte) should fail, but succeeded", test.Name, size-1)
|
||||
return
|
||||
}
|
||||
if err != registry.ErrShortBuffer {
|
||||
t.Errorf("reading %s value should return 'short buffer' error, but got: %s", test.Name, err)
|
||||
return
|
||||
}
|
||||
if gotsize != size {
|
||||
t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
// read full data
|
||||
gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size))
|
||||
if err != nil {
|
||||
t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err)
|
||||
return
|
||||
}
|
||||
if gotsize != size {
|
||||
t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)
|
||||
return
|
||||
}
|
||||
if gottype != test.Type {
|
||||
t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)
|
||||
return
|
||||
}
|
||||
// check GetValue returns ErrNotExist as required
|
||||
_, _, err = k.GetValue(test.Name+"_not_there", make([]byte, size))
|
||||
if err == nil {
|
||||
t.Errorf("GetValue(%q) should not succeed", test.Name)
|
||||
return
|
||||
}
|
||||
if err != registry.ErrNotExist {
|
||||
t.Errorf("GetValue(%q) should return 'not exist' error, but got: %s", test.Name, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testValues(t *testing.T, k registry.Key) {
|
||||
for _, test := range ValueTests {
|
||||
switch test.Type {
|
||||
case registry.SZ, registry.EXPAND_SZ:
|
||||
if test.WillFail {
|
||||
_, _, err := k.GetStringValue(test.Name)
|
||||
testErrNotExist(t, test.Name, err)
|
||||
} else {
|
||||
testGetStringValue(t, k, test)
|
||||
_, gottype, err := k.GetIntegerValue(test.Name)
|
||||
testErrUnexpectedType(t, test, gottype, err)
|
||||
// Size of utf16 string in bytes is not perfect,
|
||||
// but correct for current test values.
|
||||
// Size also includes terminating 0.
|
||||
testGetValue(t, k, test, (len(test.Value.(string))+1)*2)
|
||||
}
|
||||
_, _, err := k.GetStringValue(test.Name + "_string_not_created")
|
||||
testErrNotExist(t, test.Name+"_string_not_created", err)
|
||||
case registry.DWORD, registry.QWORD:
|
||||
testGetIntegerValue(t, k, test)
|
||||
_, gottype, err := k.GetBinaryValue(test.Name)
|
||||
testErrUnexpectedType(t, test, gottype, err)
|
||||
_, _, err = k.GetIntegerValue(test.Name + "_int_not_created")
|
||||
testErrNotExist(t, test.Name+"_int_not_created", err)
|
||||
size := 8
|
||||
if test.Type == registry.DWORD {
|
||||
size = 4
|
||||
}
|
||||
testGetValue(t, k, test, size)
|
||||
case registry.BINARY:
|
||||
testGetBinaryValue(t, k, test)
|
||||
_, gottype, err := k.GetStringsValue(test.Name)
|
||||
testErrUnexpectedType(t, test, gottype, err)
|
||||
_, _, err = k.GetBinaryValue(test.Name + "_byte_not_created")
|
||||
testErrNotExist(t, test.Name+"_byte_not_created", err)
|
||||
testGetValue(t, k, test, len(test.Value.([]byte)))
|
||||
case registry.MULTI_SZ:
|
||||
if test.WillFail {
|
||||
_, _, err := k.GetStringsValue(test.Name)
|
||||
testErrNotExist(t, test.Name, err)
|
||||
} else {
|
||||
testGetStringsValue(t, k, test)
|
||||
_, gottype, err := k.GetStringValue(test.Name)
|
||||
testErrUnexpectedType(t, test, gottype, err)
|
||||
size := 0
|
||||
for _, s := range test.Value.([]string) {
|
||||
size += len(s) + 1 // nil terminated
|
||||
}
|
||||
size += 1 // extra nil at the end
|
||||
size *= 2 // count bytes, not uint16
|
||||
testGetValue(t, k, test, size)
|
||||
}
|
||||
_, _, err := k.GetStringsValue(test.Name + "_strings_not_created")
|
||||
testErrNotExist(t, test.Name+"_strings_not_created", err)
|
||||
default:
|
||||
t.Errorf("unsupported type %d for %s value", test.Type, test.Name)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testStat(t *testing.T, k registry.Key) {
|
||||
subk, _, err := registry.CreateKey(k, "subkey", registry.CREATE_SUB_KEY)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer subk.Close()
|
||||
|
||||
defer registry.DeleteKey(k, "subkey")
|
||||
|
||||
ki, err := k.Stat()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if ki.SubKeyCount != 1 {
|
||||
t.Error("key must have 1 subkey")
|
||||
}
|
||||
if ki.MaxSubKeyLen != 6 {
|
||||
t.Error("key max subkey name length must be 6")
|
||||
}
|
||||
if ki.ValueCount != 24 {
|
||||
t.Errorf("key must have 24 values, but is %d", ki.ValueCount)
|
||||
}
|
||||
if ki.MaxValueNameLen != 12 {
|
||||
t.Errorf("key max value name length must be 10, but is %d", ki.MaxValueNameLen)
|
||||
}
|
||||
if ki.MaxValueLen != 38 {
|
||||
t.Errorf("key max value length must be 38, but is %d", ki.MaxValueLen)
|
||||
}
|
||||
if mt, ct := ki.ModTime(), time.Now(); ct.Sub(mt) > 100*time.Millisecond {
|
||||
t.Errorf("key mod time is not close to current time: mtime=%v current=%v delta=%v", mt, ct, ct.Sub(mt))
|
||||
}
|
||||
}
|
||||
|
||||
func deleteValues(t *testing.T, k registry.Key) {
|
||||
for _, test := range ValueTests {
|
||||
if test.WillFail {
|
||||
continue
|
||||
}
|
||||
err := k.DeleteValue(test.Name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
names, err := k.ReadValueNames(-1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if len(names) != 0 {
|
||||
t.Errorf("some values remain after deletion: %v", names)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValues(t *testing.T) {
|
||||
softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer softwareK.Close()
|
||||
|
||||
testKName := randKeyName("TestValues_")
|
||||
|
||||
k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer k.Close()
|
||||
|
||||
if exist {
|
||||
t.Fatalf("key %q already exists", testKName)
|
||||
}
|
||||
|
||||
defer registry.DeleteKey(softwareK, testKName)
|
||||
|
||||
setValues(t, k)
|
||||
|
||||
enumerateValues(t, k)
|
||||
|
||||
testValues(t, k)
|
||||
|
||||
testStat(t, k)
|
||||
|
||||
deleteValues(t, k)
|
||||
}
|
||||
|
||||
func walkKey(t *testing.T, k registry.Key, kname string) {
|
||||
names, err := k.ReadValueNames(-1)
|
||||
if err != nil {
|
||||
t.Fatalf("reading value names of %s failed: %v", kname, err)
|
||||
}
|
||||
for _, name := range names {
|
||||
_, valtype, err := k.GetValue(name, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("reading value type of %s of %s failed: %v", name, kname, err)
|
||||
}
|
||||
switch valtype {
|
||||
case registry.NONE:
|
||||
case registry.SZ:
|
||||
_, _, err := k.GetStringValue(name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
case registry.EXPAND_SZ:
|
||||
s, _, err := k.GetStringValue(name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = registry.ExpandString(s)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
case registry.DWORD, registry.QWORD:
|
||||
_, _, err := k.GetIntegerValue(name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
case registry.BINARY:
|
||||
_, _, err := k.GetBinaryValue(name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
case registry.MULTI_SZ:
|
||||
_, _, err := k.GetStringsValue(name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
case registry.FULL_RESOURCE_DESCRIPTOR, registry.RESOURCE_LIST, registry.RESOURCE_REQUIREMENTS_LIST:
|
||||
// TODO: not implemented
|
||||
default:
|
||||
t.Fatalf("value type %d of %s of %s failed: %v", valtype, name, kname, err)
|
||||
}
|
||||
}
|
||||
|
||||
names, err = k.ReadSubKeyNames(-1)
|
||||
if err != nil {
|
||||
t.Fatalf("reading sub-keys of %s failed: %v", kname, err)
|
||||
}
|
||||
for _, name := range names {
|
||||
func() {
|
||||
subk, err := registry.OpenKey(k, name, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
if err == syscall.ERROR_ACCESS_DENIED {
|
||||
// ignore error, if we are not allowed to access this key
|
||||
return
|
||||
}
|
||||
t.Fatalf("opening sub-keys %s of %s failed: %v", name, kname, err)
|
||||
}
|
||||
defer subk.Close()
|
||||
|
||||
walkKey(t, subk, kname+`\`+name)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkFullRegistry(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping long running test in short mode")
|
||||
}
|
||||
walkKey(t, registry.CLASSES_ROOT, "CLASSES_ROOT")
|
||||
walkKey(t, registry.CURRENT_USER, "CURRENT_USER")
|
||||
walkKey(t, registry.LOCAL_MACHINE, "LOCAL_MACHINE")
|
||||
walkKey(t, registry.USERS, "USERS")
|
||||
walkKey(t, registry.CURRENT_CONFIG, "CURRENT_CONFIG")
|
||||
}
|
||||
|
||||
func TestExpandString(t *testing.T) {
|
||||
got, err := registry.ExpandString("%PATH%")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := os.Getenv("PATH")
|
||||
if got != want {
|
||||
t.Errorf("want %q string expanded, got %q", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidValues(t *testing.T) {
|
||||
softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer softwareK.Close()
|
||||
|
||||
testKName := randKeyName("TestInvalidValues_")
|
||||
|
||||
k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer k.Close()
|
||||
|
||||
if exist {
|
||||
t.Fatalf("key %q already exists", testKName)
|
||||
}
|
||||
|
||||
defer registry.DeleteKey(softwareK, testKName)
|
||||
|
||||
var tests = []struct {
|
||||
Type uint32
|
||||
Name string
|
||||
Data []byte
|
||||
}{
|
||||
{registry.DWORD, "Dword1", nil},
|
||||
{registry.DWORD, "Dword2", []byte{1, 2, 3}},
|
||||
{registry.QWORD, "Qword1", nil},
|
||||
{registry.QWORD, "Qword2", []byte{1, 2, 3}},
|
||||
{registry.QWORD, "Qword3", []byte{1, 2, 3, 4, 5, 6, 7}},
|
||||
{registry.MULTI_SZ, "MultiString1", nil},
|
||||
{registry.MULTI_SZ, "MultiString2", []byte{0}},
|
||||
{registry.MULTI_SZ, "MultiString3", []byte{'a', 'b', 0}},
|
||||
{registry.MULTI_SZ, "MultiString4", []byte{'a', 0, 0, 'b', 0}},
|
||||
{registry.MULTI_SZ, "MultiString5", []byte{'a', 0, 0}},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := k.SetValue(test.Name, test.Type, test.Data)
|
||||
if err != nil {
|
||||
t.Fatalf("SetValue for %q failed: %v", test.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
switch test.Type {
|
||||
case registry.DWORD, registry.QWORD:
|
||||
value, valType, err := k.GetIntegerValue(test.Name)
|
||||
if err == nil {
|
||||
t.Errorf("GetIntegerValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value)
|
||||
}
|
||||
case registry.MULTI_SZ:
|
||||
value, valType, err := k.GetStringsValue(test.Name)
|
||||
if err == nil {
|
||||
if len(value) != 0 {
|
||||
t.Errorf("GetStringsValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value)
|
||||
}
|
||||
}
|
||||
default:
|
||||
t.Errorf("unsupported type %d for %s value", test.Type, test.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMUIStringValue(t *testing.T) {
|
||||
if err := registry.LoadRegLoadMUIString(); err != nil {
|
||||
t.Skip("regLoadMUIString not supported; skipping")
|
||||
}
|
||||
if err := procGetDynamicTimeZoneInformation.Find(); err != nil {
|
||||
t.Skipf("%s not supported; skipping", procGetDynamicTimeZoneInformation.Name)
|
||||
}
|
||||
var dtzi DynamicTimezoneinformation
|
||||
if _, err := GetDynamicTimeZoneInformation(&dtzi); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tzKeyName := syscall.UTF16ToString(dtzi.TimeZoneKeyName[:])
|
||||
timezoneK, err := registry.OpenKey(registry.LOCAL_MACHINE,
|
||||
`SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\`+tzKeyName, registry.READ)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer timezoneK.Close()
|
||||
|
||||
type testType struct {
|
||||
name string
|
||||
want string
|
||||
}
|
||||
var tests = []testType{
|
||||
{"MUI_Std", syscall.UTF16ToString(dtzi.StandardName[:])},
|
||||
}
|
||||
if dtzi.DynamicDaylightTimeDisabled == 0 {
|
||||
tests = append(tests, testType{"MUI_Dlt", syscall.UTF16ToString(dtzi.DaylightName[:])})
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := timezoneK.GetMUIStringValue(test.name)
|
||||
if err != nil {
|
||||
t.Error("GetMUIStringValue:", err)
|
||||
}
|
||||
|
||||
if got != test.want {
|
||||
t.Errorf("GetMUIStringValue: %s: Got %q, want %q", test.name, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type DynamicTimezoneinformation struct {
|
||||
Bias int32
|
||||
StandardName [32]uint16
|
||||
StandardDate syscall.Systemtime
|
||||
StandardBias int32
|
||||
DaylightName [32]uint16
|
||||
DaylightDate syscall.Systemtime
|
||||
DaylightBias int32
|
||||
TimeZoneKeyName [128]uint16
|
||||
DynamicDaylightTimeDisabled uint8
|
||||
}
|
||||
|
||||
var (
|
||||
kernel32DLL = syscall.NewLazyDLL("kernel32")
|
||||
|
||||
procGetDynamicTimeZoneInformation = kernel32DLL.NewProc("GetDynamicTimeZoneInformation")
|
||||
)
|
||||
|
||||
func GetDynamicTimeZoneInformation(dtzi *DynamicTimezoneinformation) (rc uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procGetDynamicTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(dtzi)), 0, 0)
|
||||
rc = uint32(r0)
|
||||
if rc == 0xffffffff {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
32
vendor/golang.org/x/sys/windows/registry/syscall.go
generated
vendored
32
vendor/golang.org/x/sys/windows/registry/syscall.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package registry
|
||||
|
||||
import "syscall"
|
||||
|
||||
const (
|
||||
_REG_OPTION_NON_VOLATILE = 0
|
||||
|
||||
_REG_CREATED_NEW_KEY = 1
|
||||
_REG_OPENED_EXISTING_KEY = 2
|
||||
|
||||
_ERROR_NO_MORE_ITEMS syscall.Errno = 259
|
||||
)
|
||||
|
||||
func LoadRegLoadMUIString() error {
|
||||
return procRegLoadMUIStringW.Find()
|
||||
}
|
||||
|
||||
//sys regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW
|
||||
//sys regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW
|
||||
//sys regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW
|
||||
//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW
|
||||
//sys regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW
|
||||
//sys regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW
|
||||
//sys regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) = advapi32.RegConnectRegistryW
|
||||
|
||||
//sys expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW
|
384
vendor/golang.org/x/sys/windows/registry/value.go
generated
vendored
384
vendor/golang.org/x/sys/windows/registry/value.go
generated
vendored
@ -1,384 +0,0 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package registry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Registry value types.
|
||||
NONE = 0
|
||||
SZ = 1
|
||||
EXPAND_SZ = 2
|
||||
BINARY = 3
|
||||
DWORD = 4
|
||||
DWORD_BIG_ENDIAN = 5
|
||||
LINK = 6
|
||||
MULTI_SZ = 7
|
||||
RESOURCE_LIST = 8
|
||||
FULL_RESOURCE_DESCRIPTOR = 9
|
||||
RESOURCE_REQUIREMENTS_LIST = 10
|
||||
QWORD = 11
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrShortBuffer is returned when the buffer was too short for the operation.
|
||||
ErrShortBuffer = syscall.ERROR_MORE_DATA
|
||||
|
||||
// ErrNotExist is returned when a registry key or value does not exist.
|
||||
ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
|
||||
|
||||
// ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
|
||||
ErrUnexpectedType = errors.New("unexpected key value type")
|
||||
)
|
||||
|
||||
// GetValue retrieves the type and data for the specified value associated
|
||||
// with an open key k. It fills up buffer buf and returns the retrieved
|
||||
// byte count n. If buf is too small to fit the stored value it returns
|
||||
// ErrShortBuffer error along with the required buffer size n.
|
||||
// If no buffer is provided, it returns true and actual buffer size n.
|
||||
// If no buffer is provided, GetValue returns the value's type only.
|
||||
// If the value does not exist, the error returned is ErrNotExist.
|
||||
//
|
||||
// GetValue is a low level function. If value's type is known, use the appropriate
|
||||
// Get*Value function instead.
|
||||
func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
|
||||
pname, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
var pbuf *byte
|
||||
if len(buf) > 0 {
|
||||
pbuf = (*byte)(unsafe.Pointer(&buf[0]))
|
||||
}
|
||||
l := uint32(len(buf))
|
||||
err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
|
||||
if err != nil {
|
||||
return int(l), valtype, err
|
||||
}
|
||||
return int(l), valtype, nil
|
||||
}
|
||||
|
||||
func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
|
||||
p, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var t uint32
|
||||
n := uint32(len(buf))
|
||||
for {
|
||||
err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
|
||||
if err == nil {
|
||||
return buf[:n], t, nil
|
||||
}
|
||||
if err != syscall.ERROR_MORE_DATA {
|
||||
return nil, 0, err
|
||||
}
|
||||
if n <= uint32(len(buf)) {
|
||||
return nil, 0, err
|
||||
}
|
||||
buf = make([]byte, n)
|
||||
}
|
||||
}
|
||||
|
||||
// GetStringValue retrieves the string value for the specified
|
||||
// value name associated with an open key k. It also returns the value's type.
|
||||
// If value does not exist, GetStringValue returns ErrNotExist.
|
||||
// If value is not SZ or EXPAND_SZ, it will return the correct value
|
||||
// type and ErrUnexpectedType.
|
||||
func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
|
||||
data, typ, err2 := k.getValue(name, make([]byte, 64))
|
||||
if err2 != nil {
|
||||
return "", typ, err2
|
||||
}
|
||||
switch typ {
|
||||
case SZ, EXPAND_SZ:
|
||||
default:
|
||||
return "", typ, ErrUnexpectedType
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return "", typ, nil
|
||||
}
|
||||
u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:]
|
||||
return syscall.UTF16ToString(u), typ, nil
|
||||
}
|
||||
|
||||
// GetMUIStringValue retrieves the localized string value for
|
||||
// the specified value name associated with an open key k.
|
||||
// If the value name doesn't exist or the localized string value
|
||||
// can't be resolved, GetMUIStringValue returns ErrNotExist.
|
||||
// GetMUIStringValue panics if the system doesn't support
|
||||
// regLoadMUIString; use LoadRegLoadMUIString to check if
|
||||
// regLoadMUIString is supported before calling this function.
|
||||
func (k Key) GetMUIStringValue(name string) (string, error) {
|
||||
pname, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
buf := make([]uint16, 1024)
|
||||
var buflen uint32
|
||||
var pdir *uint16
|
||||
|
||||
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
|
||||
|
||||
// Try to resolve the string value using the system directory as
|
||||
// a DLL search path; this assumes the string value is of the form
|
||||
// @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
|
||||
|
||||
// This approach works with tzres.dll but may have to be revised
|
||||
// in the future to allow callers to provide custom search paths.
|
||||
|
||||
var s string
|
||||
s, err = ExpandString("%SystemRoot%\\system32\\")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pdir, err = syscall.UTF16PtrFromString(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
|
||||
}
|
||||
|
||||
for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
|
||||
if buflen <= uint32(len(buf)) {
|
||||
break // Buffer not growing, assume race; break
|
||||
}
|
||||
buf = make([]uint16, buflen)
|
||||
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return syscall.UTF16ToString(buf), nil
|
||||
}
|
||||
|
||||
// ExpandString expands environment-variable strings and replaces
|
||||
// them with the values defined for the current user.
|
||||
// Use ExpandString to expand EXPAND_SZ strings.
|
||||
func ExpandString(value string) (string, error) {
|
||||
if value == "" {
|
||||
return "", nil
|
||||
}
|
||||
p, err := syscall.UTF16PtrFromString(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
r := make([]uint16, 100)
|
||||
for {
|
||||
n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if n <= uint32(len(r)) {
|
||||
u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:]
|
||||
return syscall.UTF16ToString(u), nil
|
||||
}
|
||||
r = make([]uint16, n)
|
||||
}
|
||||
}
|
||||
|
||||
// GetStringsValue retrieves the []string value for the specified
|
||||
// value name associated with an open key k. It also returns the value's type.
|
||||
// If value does not exist, GetStringsValue returns ErrNotExist.
|
||||
// If value is not MULTI_SZ, it will return the correct value
|
||||
// type and ErrUnexpectedType.
|
||||
func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
|
||||
data, typ, err2 := k.getValue(name, make([]byte, 64))
|
||||
if err2 != nil {
|
||||
return nil, typ, err2
|
||||
}
|
||||
if typ != MULTI_SZ {
|
||||
return nil, typ, ErrUnexpectedType
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return nil, typ, nil
|
||||
}
|
||||
p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2]
|
||||
if len(p) == 0 {
|
||||
return nil, typ, nil
|
||||
}
|
||||
if p[len(p)-1] == 0 {
|
||||
p = p[:len(p)-1] // remove terminating null
|
||||
}
|
||||
val = make([]string, 0, 5)
|
||||
from := 0
|
||||
for i, c := range p {
|
||||
if c == 0 {
|
||||
val = append(val, string(utf16.Decode(p[from:i])))
|
||||
from = i + 1
|
||||
}
|
||||
}
|
||||
return val, typ, nil
|
||||
}
|
||||
|
||||
// GetIntegerValue retrieves the integer value for the specified
|
||||
// value name associated with an open key k. It also returns the value's type.
|
||||
// If value does not exist, GetIntegerValue returns ErrNotExist.
|
||||
// If value is not DWORD or QWORD, it will return the correct value
|
||||
// type and ErrUnexpectedType.
|
||||
func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
|
||||
data, typ, err2 := k.getValue(name, make([]byte, 8))
|
||||
if err2 != nil {
|
||||
return 0, typ, err2
|
||||
}
|
||||
switch typ {
|
||||
case DWORD:
|
||||
if len(data) != 4 {
|
||||
return 0, typ, errors.New("DWORD value is not 4 bytes long")
|
||||
}
|
||||
return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
|
||||
case QWORD:
|
||||
if len(data) != 8 {
|
||||
return 0, typ, errors.New("QWORD value is not 8 bytes long")
|
||||
}
|
||||
return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
|
||||
default:
|
||||
return 0, typ, ErrUnexpectedType
|
||||
}
|
||||
}
|
||||
|
||||
// GetBinaryValue retrieves the binary value for the specified
|
||||
// value name associated with an open key k. It also returns the value's type.
|
||||
// If value does not exist, GetBinaryValue returns ErrNotExist.
|
||||
// If value is not BINARY, it will return the correct value
|
||||
// type and ErrUnexpectedType.
|
||||
func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
|
||||
data, typ, err2 := k.getValue(name, make([]byte, 64))
|
||||
if err2 != nil {
|
||||
return nil, typ, err2
|
||||
}
|
||||
if typ != BINARY {
|
||||
return nil, typ, ErrUnexpectedType
|
||||
}
|
||||
return data, typ, nil
|
||||
}
|
||||
|
||||
func (k Key) setValue(name string, valtype uint32, data []byte) error {
|
||||
p, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
|
||||
}
|
||||
return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
|
||||
}
|
||||
|
||||
// SetDWordValue sets the data and type of a name value
|
||||
// under key k to value and DWORD.
|
||||
func (k Key) SetDWordValue(name string, value uint32) error {
|
||||
return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
|
||||
}
|
||||
|
||||
// SetQWordValue sets the data and type of a name value
|
||||
// under key k to value and QWORD.
|
||||
func (k Key) SetQWordValue(name string, value uint64) error {
|
||||
return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
|
||||
}
|
||||
|
||||
func (k Key) setStringValue(name string, valtype uint32, value string) error {
|
||||
v, err := syscall.UTF16FromString(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
|
||||
return k.setValue(name, valtype, buf)
|
||||
}
|
||||
|
||||
// SetStringValue sets the data and type of a name value
|
||||
// under key k to value and SZ. The value must not contain a zero byte.
|
||||
func (k Key) SetStringValue(name, value string) error {
|
||||
return k.setStringValue(name, SZ, value)
|
||||
}
|
||||
|
||||
// SetExpandStringValue sets the data and type of a name value
|
||||
// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
|
||||
func (k Key) SetExpandStringValue(name, value string) error {
|
||||
return k.setStringValue(name, EXPAND_SZ, value)
|
||||
}
|
||||
|
||||
// SetStringsValue sets the data and type of a name value
|
||||
// under key k to value and MULTI_SZ. The value strings
|
||||
// must not contain a zero byte.
|
||||
func (k Key) SetStringsValue(name string, value []string) error {
|
||||
ss := ""
|
||||
for _, s := range value {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == 0 {
|
||||
return errors.New("string cannot have 0 inside")
|
||||
}
|
||||
}
|
||||
ss += s + "\x00"
|
||||
}
|
||||
v := utf16.Encode([]rune(ss + "\x00"))
|
||||
buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
|
||||
return k.setValue(name, MULTI_SZ, buf)
|
||||
}
|
||||
|
||||
// SetBinaryValue sets the data and type of a name value
|
||||
// under key k to value and BINARY.
|
||||
func (k Key) SetBinaryValue(name string, value []byte) error {
|
||||
return k.setValue(name, BINARY, value)
|
||||
}
|
||||
|
||||
// DeleteValue removes a named value from the key k.
|
||||
func (k Key) DeleteValue(name string) error {
|
||||
return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
|
||||
}
|
||||
|
||||
// ReadValueNames returns the value names of key k.
|
||||
// The parameter n controls the number of returned names,
|
||||
// analogous to the way os.File.Readdirnames works.
|
||||
func (k Key) ReadValueNames(n int) ([]string, error) {
|
||||
ki, err := k.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names := make([]string, 0, ki.ValueCount)
|
||||
buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
|
||||
loopItems:
|
||||
for i := uint32(0); ; i++ {
|
||||
if n > 0 {
|
||||
if len(names) == n {
|
||||
return names, nil
|
||||
}
|
||||
}
|
||||
l := uint32(len(buf))
|
||||
for {
|
||||
err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if err == syscall.ERROR_MORE_DATA {
|
||||
// Double buffer size and try again.
|
||||
l = uint32(2 * len(buf))
|
||||
buf = make([]uint16, l)
|
||||
continue
|
||||
}
|
||||
if err == _ERROR_NO_MORE_ITEMS {
|
||||
break loopItems
|
||||
}
|
||||
return names, err
|
||||
}
|
||||
names = append(names, syscall.UTF16ToString(buf[:l]))
|
||||
}
|
||||
if n > len(names) {
|
||||
return names, io.EOF
|
||||
}
|
||||
return names, nil
|
||||
}
|
120
vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
generated
vendored
120
vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
generated
vendored
@ -1,120 +0,0 @@
|
||||
// Code generated by 'go generate'; DO NOT EDIT.
|
||||
|
||||
package registry
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
|
||||
procRegCreateKeyExW = modadvapi32.NewProc("RegCreateKeyExW")
|
||||
procRegDeleteKeyW = modadvapi32.NewProc("RegDeleteKeyW")
|
||||
procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW")
|
||||
procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW")
|
||||
procRegDeleteValueW = modadvapi32.NewProc("RegDeleteValueW")
|
||||
procRegLoadMUIStringW = modadvapi32.NewProc("RegLoadMUIStringW")
|
||||
procRegConnectRegistryW = modadvapi32.NewProc("RegConnectRegistryW")
|
||||
procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
|
||||
)
|
||||
|
||||
func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0)
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize))
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0)
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0)
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0)
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall(procRegConnectRegistryW.Addr(), 3, uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result)))
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size))
|
||||
n = uint32(r0)
|
||||
if n == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
56
vendor/golang.org/x/sys/windows/svc/debug/log.go
generated
vendored
56
vendor/golang.org/x/sys/windows/svc/debug/log.go
generated
vendored
@ -1,56 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package debug
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Log interface allows different log implementations to be used.
|
||||
type Log interface {
|
||||
Close() error
|
||||
Info(eid uint32, msg string) error
|
||||
Warning(eid uint32, msg string) error
|
||||
Error(eid uint32, msg string) error
|
||||
}
|
||||
|
||||
// ConsoleLog provides access to the console.
|
||||
type ConsoleLog struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// New creates new ConsoleLog.
|
||||
func New(source string) *ConsoleLog {
|
||||
return &ConsoleLog{Name: source}
|
||||
}
|
||||
|
||||
// Close closes console log l.
|
||||
func (l *ConsoleLog) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *ConsoleLog) report(kind string, eid uint32, msg string) error {
|
||||
s := l.Name + "." + kind + "(" + strconv.Itoa(int(eid)) + "): " + msg + "\n"
|
||||
_, err := os.Stdout.Write([]byte(s))
|
||||
return err
|
||||
}
|
||||
|
||||
// Info writes an information event msg with event id eid to the console l.
|
||||
func (l *ConsoleLog) Info(eid uint32, msg string) error {
|
||||
return l.report("info", eid, msg)
|
||||
}
|
||||
|
||||
// Warning writes an warning event msg with event id eid to the console l.
|
||||
func (l *ConsoleLog) Warning(eid uint32, msg string) error {
|
||||
return l.report("warn", eid, msg)
|
||||
}
|
||||
|
||||
// Error writes an error event msg with event id eid to the console l.
|
||||
func (l *ConsoleLog) Error(eid uint32, msg string) error {
|
||||
return l.report("error", eid, msg)
|
||||
}
|
45
vendor/golang.org/x/sys/windows/svc/debug/service.go
generated
vendored
45
vendor/golang.org/x/sys/windows/svc/debug/service.go
generated
vendored
@ -1,45 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
// Package debug provides facilities to execute svc.Handler on console.
|
||||
//
|
||||
package debug
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
)
|
||||
|
||||
// Run executes service name by calling appropriate handler function.
|
||||
// The process is running on console, unlike real service. Use Ctrl+C to
|
||||
// send "Stop" command to your service.
|
||||
func Run(name string, handler svc.Handler) error {
|
||||
cmds := make(chan svc.ChangeRequest)
|
||||
changes := make(chan svc.Status)
|
||||
|
||||
sig := make(chan os.Signal)
|
||||
signal.Notify(sig)
|
||||
|
||||
go func() {
|
||||
status := svc.Status{State: svc.Stopped}
|
||||
for {
|
||||
select {
|
||||
case <-sig:
|
||||
cmds <- svc.ChangeRequest{Cmd: svc.Stop, CurrentStatus: status}
|
||||
case status = <-changes:
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
_, errno := handler.Execute([]string{name}, cmds, changes)
|
||||
if errno != 0 {
|
||||
return syscall.Errno(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
48
vendor/golang.org/x/sys/windows/svc/event.go
generated
vendored
48
vendor/golang.org/x/sys/windows/svc/event.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package svc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// event represents auto-reset, initially non-signaled Windows event.
|
||||
// It is used to communicate between go and asm parts of this package.
|
||||
type event struct {
|
||||
h windows.Handle
|
||||
}
|
||||
|
||||
func newEvent() (*event, error) {
|
||||
h, err := windows.CreateEvent(nil, 0, 0, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &event{h: h}, nil
|
||||
}
|
||||
|
||||
func (e *event) Close() error {
|
||||
return windows.CloseHandle(e.h)
|
||||
}
|
||||
|
||||
func (e *event) Set() error {
|
||||
return windows.SetEvent(e.h)
|
||||
}
|
||||
|
||||
func (e *event) Wait() error {
|
||||
s, err := windows.WaitForSingleObject(e.h, windows.INFINITE)
|
||||
switch s {
|
||||
case windows.WAIT_OBJECT_0:
|
||||
break
|
||||
case windows.WAIT_FAILED:
|
||||
return err
|
||||
default:
|
||||
return errors.New("unexpected result from WaitForSingleObject")
|
||||
}
|
||||
return nil
|
||||
}
|
80
vendor/golang.org/x/sys/windows/svc/eventlog/install.go
generated
vendored
80
vendor/golang.org/x/sys/windows/svc/eventlog/install.go
generated
vendored
@ -1,80 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package eventlog
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
// Log levels.
|
||||
Info = windows.EVENTLOG_INFORMATION_TYPE
|
||||
Warning = windows.EVENTLOG_WARNING_TYPE
|
||||
Error = windows.EVENTLOG_ERROR_TYPE
|
||||
)
|
||||
|
||||
const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
|
||||
|
||||
// Install modifies PC registry to allow logging with an event source src.
|
||||
// It adds all required keys and values to the event log registry key.
|
||||
// Install uses msgFile as the event message file. If useExpandKey is true,
|
||||
// the event message file is installed as REG_EXPAND_SZ value,
|
||||
// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
|
||||
// log.Info to specify events supported by the new event source.
|
||||
func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error {
|
||||
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer appkey.Close()
|
||||
|
||||
sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sk.Close()
|
||||
if alreadyExist {
|
||||
return errors.New(addKeyName + `\` + src + " registry key already exists")
|
||||
}
|
||||
|
||||
err = sk.SetDWordValue("CustomSource", 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if useExpandKey {
|
||||
err = sk.SetExpandStringValue("EventMessageFile", msgFile)
|
||||
} else {
|
||||
err = sk.SetStringValue("EventMessageFile", msgFile)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sk.SetDWordValue("TypesSupported", eventsSupported)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InstallAsEventCreate is the same as Install, but uses
|
||||
// %SystemRoot%\System32\EventCreate.exe as the event message file.
|
||||
func InstallAsEventCreate(src string, eventsSupported uint32) error {
|
||||
return Install(src, "%SystemRoot%\\System32\\EventCreate.exe", true, eventsSupported)
|
||||
}
|
||||
|
||||
// Remove deletes all registry elements installed by the correspondent Install.
|
||||
func Remove(src string) error {
|
||||
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.SET_VALUE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer appkey.Close()
|
||||
return registry.DeleteKey(appkey, src)
|
||||
}
|
70
vendor/golang.org/x/sys/windows/svc/eventlog/log.go
generated
vendored
70
vendor/golang.org/x/sys/windows/svc/eventlog/log.go
generated
vendored
@ -1,70 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
// Package eventlog implements access to Windows event log.
|
||||
//
|
||||
package eventlog
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Log provides access to the system log.
|
||||
type Log struct {
|
||||
Handle windows.Handle
|
||||
}
|
||||
|
||||
// Open retrieves a handle to the specified event log.
|
||||
func Open(source string) (*Log, error) {
|
||||
return OpenRemote("", source)
|
||||
}
|
||||
|
||||
// OpenRemote does the same as Open, but on different computer host.
|
||||
func OpenRemote(host, source string) (*Log, error) {
|
||||
if source == "" {
|
||||
return nil, errors.New("Specify event log source")
|
||||
}
|
||||
var s *uint16
|
||||
if host != "" {
|
||||
s = syscall.StringToUTF16Ptr(host)
|
||||
}
|
||||
h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Log{Handle: h}, nil
|
||||
}
|
||||
|
||||
// Close closes event log l.
|
||||
func (l *Log) Close() error {
|
||||
return windows.DeregisterEventSource(l.Handle)
|
||||
}
|
||||
|
||||
func (l *Log) report(etype uint16, eid uint32, msg string) error {
|
||||
ss := []*uint16{syscall.StringToUTF16Ptr(msg)}
|
||||
return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
|
||||
}
|
||||
|
||||
// Info writes an information event msg with event id eid to the end of event log l.
|
||||
// When EventCreate.exe is used, eid must be between 1 and 1000.
|
||||
func (l *Log) Info(eid uint32, msg string) error {
|
||||
return l.report(windows.EVENTLOG_INFORMATION_TYPE, eid, msg)
|
||||
}
|
||||
|
||||
// Warning writes an warning event msg with event id eid to the end of event log l.
|
||||
// When EventCreate.exe is used, eid must be between 1 and 1000.
|
||||
func (l *Log) Warning(eid uint32, msg string) error {
|
||||
return l.report(windows.EVENTLOG_WARNING_TYPE, eid, msg)
|
||||
}
|
||||
|
||||
// Error writes an error event msg with event id eid to the end of event log l.
|
||||
// When EventCreate.exe is used, eid must be between 1 and 1000.
|
||||
func (l *Log) Error(eid uint32, msg string) error {
|
||||
return l.report(windows.EVENTLOG_ERROR_TYPE, eid, msg)
|
||||
}
|
51
vendor/golang.org/x/sys/windows/svc/eventlog/log_test.go
generated
vendored
51
vendor/golang.org/x/sys/windows/svc/eventlog/log_test.go
generated
vendored
@ -1,51 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package eventlog_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/windows/svc/eventlog"
|
||||
)
|
||||
|
||||
func TestLog(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode - it modifies system logs")
|
||||
}
|
||||
|
||||
const name = "mylog"
|
||||
const supports = eventlog.Error | eventlog.Warning | eventlog.Info
|
||||
err := eventlog.InstallAsEventCreate(name, supports)
|
||||
if err != nil {
|
||||
t.Fatalf("Install failed: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
err = eventlog.Remove(name)
|
||||
if err != nil {
|
||||
t.Fatalf("Remove failed: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
l, err := eventlog.Open(name)
|
||||
if err != nil {
|
||||
t.Fatalf("Open failed: %s", err)
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
err = l.Info(1, "info")
|
||||
if err != nil {
|
||||
t.Fatalf("Info failed: %s", err)
|
||||
}
|
||||
err = l.Warning(2, "warning")
|
||||
if err != nil {
|
||||
t.Fatalf("Warning failed: %s", err)
|
||||
}
|
||||
err = l.Error(3, "error")
|
||||
if err != nil {
|
||||
t.Fatalf("Error failed: %s", err)
|
||||
}
|
||||
}
|
22
vendor/golang.org/x/sys/windows/svc/example/beep.go
generated
vendored
22
vendor/golang.org/x/sys/windows/svc/example/beep.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// BUG(brainman): MessageBeep Windows api is broken on Windows 7,
|
||||
// so this example does not beep when runs as service on Windows 7.
|
||||
|
||||
var (
|
||||
beepFunc = syscall.MustLoadDLL("user32.dll").MustFindProc("MessageBeep")
|
||||
)
|
||||
|
||||
func beep() {
|
||||
beepFunc.Call(0xffffffff)
|
||||
}
|
92
vendor/golang.org/x/sys/windows/svc/example/install.go
generated
vendored
92
vendor/golang.org/x/sys/windows/svc/example/install.go
generated
vendored
@ -1,92 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/sys/windows/svc/eventlog"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
)
|
||||
|
||||
func exePath() (string, error) {
|
||||
prog := os.Args[0]
|
||||
p, err := filepath.Abs(prog)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fi, err := os.Stat(p)
|
||||
if err == nil {
|
||||
if !fi.Mode().IsDir() {
|
||||
return p, nil
|
||||
}
|
||||
err = fmt.Errorf("%s is directory", p)
|
||||
}
|
||||
if filepath.Ext(p) == "" {
|
||||
p += ".exe"
|
||||
fi, err := os.Stat(p)
|
||||
if err == nil {
|
||||
if !fi.Mode().IsDir() {
|
||||
return p, nil
|
||||
}
|
||||
err = fmt.Errorf("%s is directory", p)
|
||||
}
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
func installService(name, desc string) error {
|
||||
exepath, err := exePath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer m.Disconnect()
|
||||
s, err := m.OpenService(name)
|
||||
if err == nil {
|
||||
s.Close()
|
||||
return fmt.Errorf("service %s already exists", name)
|
||||
}
|
||||
s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc}, "is", "auto-started")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer s.Close()
|
||||
err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
|
||||
if err != nil {
|
||||
s.Delete()
|
||||
return fmt.Errorf("SetupEventLogSource() failed: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeService(name string) error {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer m.Disconnect()
|
||||
s, err := m.OpenService(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("service %s is not installed", name)
|
||||
}
|
||||
defer s.Close()
|
||||
err = s.Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = eventlog.Remove(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("RemoveEventLogSource() failed: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
76
vendor/golang.org/x/sys/windows/svc/example/main.go
generated
vendored
76
vendor/golang.org/x/sys/windows/svc/example/main.go
generated
vendored
@ -1,76 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
// Example service program that beeps.
|
||||
//
|
||||
// The program demonstrates how to create Windows service and
|
||||
// install / remove it on a computer. It also shows how to
|
||||
// stop / start / pause / continue any service, and how to
|
||||
// write to event log. It also shows how to use debug
|
||||
// facilities available in debug package.
|
||||
//
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
)
|
||||
|
||||
func usage(errmsg string) {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"%s\n\n"+
|
||||
"usage: %s <command>\n"+
|
||||
" where <command> is one of\n"+
|
||||
" install, remove, debug, start, stop, pause or continue.\n",
|
||||
errmsg, os.Args[0])
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
func main() {
|
||||
const svcName = "myservice"
|
||||
|
||||
isIntSess, err := svc.IsAnInteractiveSession()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
|
||||
}
|
||||
if !isIntSess {
|
||||
runService(svcName, false)
|
||||
return
|
||||
}
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
usage("no command specified")
|
||||
}
|
||||
|
||||
cmd := strings.ToLower(os.Args[1])
|
||||
switch cmd {
|
||||
case "debug":
|
||||
runService(svcName, true)
|
||||
return
|
||||
case "install":
|
||||
err = installService(svcName, "my service")
|
||||
case "remove":
|
||||
err = removeService(svcName)
|
||||
case "start":
|
||||
err = startService(svcName)
|
||||
case "stop":
|
||||
err = controlService(svcName, svc.Stop, svc.Stopped)
|
||||
case "pause":
|
||||
err = controlService(svcName, svc.Pause, svc.Paused)
|
||||
case "continue":
|
||||
err = controlService(svcName, svc.Continue, svc.Running)
|
||||
default:
|
||||
usage(fmt.Sprintf("invalid command %s", cmd))
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("failed to %s %s: %v", cmd, svcName, err)
|
||||
}
|
||||
return
|
||||
}
|
62
vendor/golang.org/x/sys/windows/svc/example/manage.go
generated
vendored
62
vendor/golang.org/x/sys/windows/svc/example/manage.go
generated
vendored
@ -1,62 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
)
|
||||
|
||||
func startService(name string) error {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer m.Disconnect()
|
||||
s, err := m.OpenService(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not access service: %v", err)
|
||||
}
|
||||
defer s.Close()
|
||||
err = s.Start("is", "manual-started")
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not start service: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func controlService(name string, c svc.Cmd, to svc.State) error {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer m.Disconnect()
|
||||
s, err := m.OpenService(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not access service: %v", err)
|
||||
}
|
||||
defer s.Close()
|
||||
status, err := s.Control(c)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not send control=%d: %v", c, err)
|
||||
}
|
||||
timeout := time.Now().Add(10 * time.Second)
|
||||
for status.State != to {
|
||||
if timeout.Before(time.Now()) {
|
||||
return fmt.Errorf("timeout waiting for service to go to state=%d", to)
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
status, err = s.Query()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not retrieve service status: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
84
vendor/golang.org/x/sys/windows/svc/example/service.go
generated
vendored
84
vendor/golang.org/x/sys/windows/svc/example/service.go
generated
vendored
@ -1,84 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/debug"
|
||||
"golang.org/x/sys/windows/svc/eventlog"
|
||||
)
|
||||
|
||||
var elog debug.Log
|
||||
|
||||
type myservice struct{}
|
||||
|
||||
func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
|
||||
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
|
||||
changes <- svc.Status{State: svc.StartPending}
|
||||
fasttick := time.Tick(500 * time.Millisecond)
|
||||
slowtick := time.Tick(2 * time.Second)
|
||||
tick := fasttick
|
||||
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
||||
elog.Info(1, strings.Join(args, "-"))
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case <-tick:
|
||||
beep()
|
||||
elog.Info(1, "beep")
|
||||
case c := <-r:
|
||||
switch c.Cmd {
|
||||
case svc.Interrogate:
|
||||
changes <- c.CurrentStatus
|
||||
// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
changes <- c.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
break loop
|
||||
case svc.Pause:
|
||||
changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
|
||||
tick = slowtick
|
||||
case svc.Continue:
|
||||
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
||||
tick = fasttick
|
||||
default:
|
||||
elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
|
||||
}
|
||||
}
|
||||
}
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
return
|
||||
}
|
||||
|
||||
func runService(name string, isDebug bool) {
|
||||
var err error
|
||||
if isDebug {
|
||||
elog = debug.New(name)
|
||||
} else {
|
||||
elog, err = eventlog.Open(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
defer elog.Close()
|
||||
|
||||
elog.Info(1, fmt.Sprintf("starting %s service", name))
|
||||
run := svc.Run
|
||||
if isDebug {
|
||||
run = debug.Run
|
||||
}
|
||||
err = run(name, &myservice{})
|
||||
if err != nil {
|
||||
elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
|
||||
return
|
||||
}
|
||||
elog.Info(1, fmt.Sprintf("%s service stopped", name))
|
||||
}
|
24
vendor/golang.org/x/sys/windows/svc/go12.c
generated
vendored
24
vendor/golang.org/x/sys/windows/svc/go12.c
generated
vendored
@ -1,24 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
// +build !go1.3
|
||||
|
||||
// copied from pkg/runtime
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long int uint64;
|
||||
#ifdef _64BIT
|
||||
typedef uint64 uintptr;
|
||||
#else
|
||||
typedef uint32 uintptr;
|
||||
#endif
|
||||
|
||||
// from sys_386.s or sys_amd64.s
|
||||
void ·servicemain(void);
|
||||
|
||||
void
|
||||
·getServiceMain(uintptr *r)
|
||||
{
|
||||
*r = (uintptr)·servicemain;
|
||||
}
|
11
vendor/golang.org/x/sys/windows/svc/go12.go
generated
vendored
11
vendor/golang.org/x/sys/windows/svc/go12.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// +build windows
|
||||
// +build !go1.3
|
||||
|
||||
package svc
|
||||
|
||||
// from go12.c
|
||||
func getServiceMain(r *uintptr)
|
31
vendor/golang.org/x/sys/windows/svc/go13.go
generated
vendored
31
vendor/golang.org/x/sys/windows/svc/go13.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// +build windows
|
||||
// +build go1.3
|
||||
|
||||
package svc
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
|
||||
|
||||
// Should be a built-in for unsafe.Pointer?
|
||||
func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
|
||||
return unsafe.Pointer(uintptr(p) + x)
|
||||
}
|
||||
|
||||
// funcPC returns the entry PC of the function f.
|
||||
// It assumes that f is a func value. Otherwise the behavior is undefined.
|
||||
func funcPC(f interface{}) uintptr {
|
||||
return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
|
||||
}
|
||||
|
||||
// from sys_386.s and sys_amd64.s
|
||||
func servicectlhandler(ctl uint32) uintptr
|
||||
func servicemain(argc uint32, argv **uint16)
|
||||
|
||||
func getServiceMain(r *uintptr) {
|
||||
*r = funcPC(servicemain)
|
||||
}
|
145
vendor/golang.org/x/sys/windows/svc/mgr/config.go
generated
vendored
145
vendor/golang.org/x/sys/windows/svc/mgr/config.go
generated
vendored
@ -1,145 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
// Service start types.
|
||||
StartManual = windows.SERVICE_DEMAND_START // the service must be started manually
|
||||
StartAutomatic = windows.SERVICE_AUTO_START // the service will start by itself whenever the computer reboots
|
||||
StartDisabled = windows.SERVICE_DISABLED // the service cannot be started
|
||||
|
||||
// The severity of the error, and action taken,
|
||||
// if this service fails to start.
|
||||
ErrorCritical = windows.SERVICE_ERROR_CRITICAL
|
||||
ErrorIgnore = windows.SERVICE_ERROR_IGNORE
|
||||
ErrorNormal = windows.SERVICE_ERROR_NORMAL
|
||||
ErrorSevere = windows.SERVICE_ERROR_SEVERE
|
||||
)
|
||||
|
||||
// TODO(brainman): Password is not returned by windows.QueryServiceConfig, not sure how to get it.
|
||||
|
||||
type Config struct {
|
||||
ServiceType uint32
|
||||
StartType uint32
|
||||
ErrorControl uint32
|
||||
BinaryPathName string // fully qualified path to the service binary file, can also include arguments for an auto-start service
|
||||
LoadOrderGroup string
|
||||
TagId uint32
|
||||
Dependencies []string
|
||||
ServiceStartName string // name of the account under which the service should run
|
||||
DisplayName string
|
||||
Password string
|
||||
Description string
|
||||
}
|
||||
|
||||
func toString(p *uint16) string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
|
||||
}
|
||||
|
||||
func toStringSlice(ps *uint16) []string {
|
||||
if ps == nil {
|
||||
return nil
|
||||
}
|
||||
r := make([]string, 0)
|
||||
for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(ps)); true; i++ {
|
||||
if p[i] == 0 {
|
||||
// empty string marks the end
|
||||
if i <= from {
|
||||
break
|
||||
}
|
||||
r = append(r, string(utf16.Decode(p[from:i])))
|
||||
from = i + 1
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Config retrieves service s configuration paramteres.
|
||||
func (s *Service) Config() (Config, error) {
|
||||
var p *windows.QUERY_SERVICE_CONFIG
|
||||
n := uint32(1024)
|
||||
for {
|
||||
b := make([]byte, n)
|
||||
p = (*windows.QUERY_SERVICE_CONFIG)(unsafe.Pointer(&b[0]))
|
||||
err := windows.QueryServiceConfig(s.Handle, p, n, &n)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
|
||||
return Config{}, err
|
||||
}
|
||||
if n <= uint32(len(b)) {
|
||||
return Config{}, err
|
||||
}
|
||||
}
|
||||
|
||||
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_DESCRIPTION)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
p2 := (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0]))
|
||||
|
||||
return Config{
|
||||
ServiceType: p.ServiceType,
|
||||
StartType: p.StartType,
|
||||
ErrorControl: p.ErrorControl,
|
||||
BinaryPathName: toString(p.BinaryPathName),
|
||||
LoadOrderGroup: toString(p.LoadOrderGroup),
|
||||
TagId: p.TagId,
|
||||
Dependencies: toStringSlice(p.Dependencies),
|
||||
ServiceStartName: toString(p.ServiceStartName),
|
||||
DisplayName: toString(p.DisplayName),
|
||||
Description: toString(p2.Description),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func updateDescription(handle windows.Handle, desc string) error {
|
||||
d := windows.SERVICE_DESCRIPTION{Description: toPtr(desc)}
|
||||
return windows.ChangeServiceConfig2(handle,
|
||||
windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
|
||||
}
|
||||
|
||||
// UpdateConfig updates service s configuration parameters.
|
||||
func (s *Service) UpdateConfig(c Config) error {
|
||||
err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
|
||||
c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup),
|
||||
nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName),
|
||||
toPtr(c.Password), toPtr(c.DisplayName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return updateDescription(s.Handle, c.Description)
|
||||
}
|
||||
|
||||
// queryServiceConfig2 calls Windows QueryServiceConfig2 with infoLevel parameter and returns retrieved service configuration information.
|
||||
func (s *Service) queryServiceConfig2(infoLevel uint32) ([]byte, error) {
|
||||
n := uint32(1024)
|
||||
for {
|
||||
b := make([]byte, n)
|
||||
err := windows.QueryServiceConfig2(s.Handle, infoLevel, &b[0], n, &n)
|
||||
if err == nil {
|
||||
return b, nil
|
||||
}
|
||||
if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
|
||||
return nil, err
|
||||
}
|
||||
if n <= uint32(len(b)) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
162
vendor/golang.org/x/sys/windows/svc/mgr/mgr.go
generated
vendored
162
vendor/golang.org/x/sys/windows/svc/mgr/mgr.go
generated
vendored
@ -1,162 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
// Package mgr can be used to manage Windows service programs.
|
||||
// It can be used to install and remove them. It can also start,
|
||||
// stop and pause them. The package can query / change current
|
||||
// service state and config parameters.
|
||||
//
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Mgr is used to manage Windows service.
|
||||
type Mgr struct {
|
||||
Handle windows.Handle
|
||||
}
|
||||
|
||||
// Connect establishes a connection to the service control manager.
|
||||
func Connect() (*Mgr, error) {
|
||||
return ConnectRemote("")
|
||||
}
|
||||
|
||||
// ConnectRemote establishes a connection to the
|
||||
// service control manager on computer named host.
|
||||
func ConnectRemote(host string) (*Mgr, error) {
|
||||
var s *uint16
|
||||
if host != "" {
|
||||
s = syscall.StringToUTF16Ptr(host)
|
||||
}
|
||||
h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Mgr{Handle: h}, nil
|
||||
}
|
||||
|
||||
// Disconnect closes connection to the service control manager m.
|
||||
func (m *Mgr) Disconnect() error {
|
||||
return windows.CloseServiceHandle(m.Handle)
|
||||
}
|
||||
|
||||
func toPtr(s string) *uint16 {
|
||||
if len(s) == 0 {
|
||||
return nil
|
||||
}
|
||||
return syscall.StringToUTF16Ptr(s)
|
||||
}
|
||||
|
||||
// toStringBlock terminates strings in ss with 0, and then
|
||||
// concatenates them together. It also adds extra 0 at the end.
|
||||
func toStringBlock(ss []string) *uint16 {
|
||||
if len(ss) == 0 {
|
||||
return nil
|
||||
}
|
||||
t := ""
|
||||
for _, s := range ss {
|
||||
if s != "" {
|
||||
t += s + "\x00"
|
||||
}
|
||||
}
|
||||
if t == "" {
|
||||
return nil
|
||||
}
|
||||
t += "\x00"
|
||||
return &utf16.Encode([]rune(t))[0]
|
||||
}
|
||||
|
||||
// CreateService installs new service name on the system.
|
||||
// The service will be executed by running exepath binary.
|
||||
// Use config c to specify service parameters.
|
||||
// Any args will be passed as command-line arguments when
|
||||
// the service is started; these arguments are distinct from
|
||||
// the arguments passed to Service.Start or via the "Start
|
||||
// parameters" field in the service's Properties dialog box.
|
||||
func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) {
|
||||
if c.StartType == 0 {
|
||||
c.StartType = StartManual
|
||||
}
|
||||
if c.ErrorControl == 0 {
|
||||
c.ErrorControl = ErrorNormal
|
||||
}
|
||||
if c.ServiceType == 0 {
|
||||
c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
|
||||
}
|
||||
s := syscall.EscapeArg(exepath)
|
||||
for _, v := range args {
|
||||
s += " " + syscall.EscapeArg(v)
|
||||
}
|
||||
h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
|
||||
windows.SERVICE_ALL_ACCESS, c.ServiceType,
|
||||
c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup),
|
||||
nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c.Description != "" {
|
||||
err = updateDescription(h, c.Description)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &Service{Name: name, Handle: h}, nil
|
||||
}
|
||||
|
||||
// OpenService retrieves access to service name, so it can
|
||||
// be interrogated and controlled.
|
||||
func (m *Mgr) OpenService(name string) (*Service, error) {
|
||||
h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Service{Name: name, Handle: h}, nil
|
||||
}
|
||||
|
||||
// ListServices enumerates services in the specified
|
||||
// service control manager database m.
|
||||
// If the caller does not have the SERVICE_QUERY_STATUS
|
||||
// access right to a service, the service is silently
|
||||
// omitted from the list of services returned.
|
||||
func (m *Mgr) ListServices() ([]string, error) {
|
||||
var err error
|
||||
var bytesNeeded, servicesReturned uint32
|
||||
var buf []byte
|
||||
for {
|
||||
var p *byte
|
||||
if len(buf) > 0 {
|
||||
p = &buf[0]
|
||||
}
|
||||
err = windows.EnumServicesStatusEx(m.Handle, windows.SC_ENUM_PROCESS_INFO,
|
||||
windows.SERVICE_WIN32, windows.SERVICE_STATE_ALL,
|
||||
p, uint32(len(buf)), &bytesNeeded, &servicesReturned, nil, nil)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if err != syscall.ERROR_MORE_DATA {
|
||||
return nil, err
|
||||
}
|
||||
if bytesNeeded <= uint32(len(buf)) {
|
||||
return nil, err
|
||||
}
|
||||
buf = make([]byte, bytesNeeded)
|
||||
}
|
||||
if servicesReturned == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned]
|
||||
var names []string
|
||||
for _, s := range services {
|
||||
name := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(s.ServiceName))[:])
|
||||
names = append(names, name)
|
||||
}
|
||||
return names, nil
|
||||
}
|
282
vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go
generated
vendored
282
vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go
generated
vendored
@ -1,282 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package mgr_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
)
|
||||
|
||||
func TestOpenLanManServer(t *testing.T) {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
|
||||
t.Skip("Skipping test: we don't have rights to manage services.")
|
||||
}
|
||||
t.Fatalf("SCM connection failed: %s", err)
|
||||
}
|
||||
defer m.Disconnect()
|
||||
|
||||
s, err := m.OpenService("LanmanServer")
|
||||
if err != nil {
|
||||
t.Fatalf("OpenService(lanmanserver) failed: %s", err)
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
_, err = s.Config()
|
||||
if err != nil {
|
||||
t.Fatalf("Config failed: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func install(t *testing.T, m *mgr.Mgr, name, exepath string, c mgr.Config) {
|
||||
// Sometimes it takes a while for the service to get
|
||||
// removed after previous test run.
|
||||
for i := 0; ; i++ {
|
||||
s, err := m.OpenService(name)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
s.Close()
|
||||
|
||||
if i > 10 {
|
||||
t.Fatalf("service %s already exists", name)
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
}
|
||||
|
||||
s, err := m.CreateService(name, exepath, c)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateService(%s) failed: %v", name, err)
|
||||
}
|
||||
defer s.Close()
|
||||
}
|
||||
|
||||
func depString(d []string) string {
|
||||
if len(d) == 0 {
|
||||
return ""
|
||||
}
|
||||
for i := range d {
|
||||
d[i] = strings.ToLower(d[i])
|
||||
}
|
||||
ss := sort.StringSlice(d)
|
||||
ss.Sort()
|
||||
return strings.Join([]string(ss), " ")
|
||||
}
|
||||
|
||||
func testConfig(t *testing.T, s *mgr.Service, should mgr.Config) mgr.Config {
|
||||
is, err := s.Config()
|
||||
if err != nil {
|
||||
t.Fatalf("Config failed: %s", err)
|
||||
}
|
||||
if should.DisplayName != is.DisplayName {
|
||||
t.Fatalf("config mismatch: DisplayName is %q, but should have %q", is.DisplayName, should.DisplayName)
|
||||
}
|
||||
if should.StartType != is.StartType {
|
||||
t.Fatalf("config mismatch: StartType is %v, but should have %v", is.StartType, should.StartType)
|
||||
}
|
||||
if should.Description != is.Description {
|
||||
t.Fatalf("config mismatch: Description is %q, but should have %q", is.Description, should.Description)
|
||||
}
|
||||
if depString(should.Dependencies) != depString(is.Dependencies) {
|
||||
t.Fatalf("config mismatch: Dependencies is %v, but should have %v", is.Dependencies, should.Dependencies)
|
||||
}
|
||||
return is
|
||||
}
|
||||
|
||||
func testRecoveryActions(t *testing.T, s *mgr.Service, should []mgr.RecoveryAction) {
|
||||
is, err := s.RecoveryActions()
|
||||
if err != nil {
|
||||
t.Fatalf("RecoveryActions failed: %s", err)
|
||||
}
|
||||
if len(should) != len(is) {
|
||||
t.Errorf("recovery action mismatch: contains %v actions, but should have %v", len(is), len(should))
|
||||
}
|
||||
for i, _ := range is {
|
||||
if should[i].Type != is[i].Type {
|
||||
t.Errorf("recovery action mismatch: Type is %v, but should have %v", is[i].Type, should[i].Type)
|
||||
}
|
||||
if should[i].Delay != is[i].Delay {
|
||||
t.Errorf("recovery action mismatch: Delay is %v, but should have %v", is[i].Delay, should[i].Delay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testResetPeriod(t *testing.T, s *mgr.Service, should uint32) {
|
||||
is, err := s.ResetPeriod()
|
||||
if err != nil {
|
||||
t.Fatalf("ResetPeriod failed: %s", err)
|
||||
}
|
||||
if should != is {
|
||||
t.Errorf("reset period mismatch: reset period is %v, but should have %v", is, should)
|
||||
}
|
||||
}
|
||||
|
||||
func testSetRecoveryActions(t *testing.T, s *mgr.Service) {
|
||||
r := []mgr.RecoveryAction{
|
||||
mgr.RecoveryAction{
|
||||
Type: mgr.NoAction,
|
||||
Delay: 60000 * time.Millisecond,
|
||||
},
|
||||
mgr.RecoveryAction{
|
||||
Type: mgr.ServiceRestart,
|
||||
Delay: 4 * time.Minute,
|
||||
},
|
||||
mgr.RecoveryAction{
|
||||
Type: mgr.ServiceRestart,
|
||||
Delay: time.Minute,
|
||||
},
|
||||
mgr.RecoveryAction{
|
||||
Type: mgr.RunCommand,
|
||||
Delay: 4000 * time.Millisecond,
|
||||
},
|
||||
}
|
||||
|
||||
// 4 recovery actions with reset period
|
||||
err := s.SetRecoveryActions(r, uint32(10000))
|
||||
if err != nil {
|
||||
t.Fatalf("SetRecoveryActions failed: %v", err)
|
||||
}
|
||||
testRecoveryActions(t, s, r)
|
||||
testResetPeriod(t, s, uint32(10000))
|
||||
|
||||
// Infinite reset period
|
||||
err = s.SetRecoveryActions(r, syscall.INFINITE)
|
||||
if err != nil {
|
||||
t.Fatalf("SetRecoveryActions failed: %v", err)
|
||||
}
|
||||
testRecoveryActions(t, s, r)
|
||||
testResetPeriod(t, s, syscall.INFINITE)
|
||||
|
||||
// nil recovery actions
|
||||
err = s.SetRecoveryActions(nil, 0)
|
||||
if err.Error() != "recoveryActions cannot be nil" {
|
||||
t.Fatalf("SetRecoveryActions failed with unexpected error message of %q", err)
|
||||
}
|
||||
|
||||
// Delete all recovery actions and reset period
|
||||
err = s.ResetRecoveryActions()
|
||||
if err != nil {
|
||||
t.Fatalf("ResetRecoveryActions failed: %v", err)
|
||||
}
|
||||
testRecoveryActions(t, s, nil)
|
||||
testResetPeriod(t, s, 0)
|
||||
}
|
||||
|
||||
func testRebootMessage(t *testing.T, s *mgr.Service, should string) {
|
||||
err := s.SetRebootMessage(should)
|
||||
if err != nil {
|
||||
t.Fatalf("SetRebootMessage failed: %v", err)
|
||||
}
|
||||
is, err := s.RebootMessage()
|
||||
if err != nil {
|
||||
t.Fatalf("RebootMessage failed: %v", err)
|
||||
}
|
||||
if should != is {
|
||||
t.Errorf("reboot message mismatch: message is %q, but should have %q", is, should)
|
||||
}
|
||||
}
|
||||
|
||||
func testRecoveryCommand(t *testing.T, s *mgr.Service, should string) {
|
||||
err := s.SetRecoveryCommand(should)
|
||||
if err != nil {
|
||||
t.Fatalf("SetRecoveryCommand failed: %v", err)
|
||||
}
|
||||
is, err := s.RecoveryCommand()
|
||||
if err != nil {
|
||||
t.Fatalf("RecoveryCommand failed: %v", err)
|
||||
}
|
||||
if should != is {
|
||||
t.Errorf("recovery command mismatch: command is %q, but should have %q", is, should)
|
||||
}
|
||||
}
|
||||
|
||||
func remove(t *testing.T, s *mgr.Service) {
|
||||
err := s.Delete()
|
||||
if err != nil {
|
||||
t.Fatalf("Delete failed: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMyService(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode - it modifies system services")
|
||||
}
|
||||
|
||||
const name = "myservice"
|
||||
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
|
||||
t.Skip("Skipping test: we don't have rights to manage services.")
|
||||
}
|
||||
t.Fatalf("SCM connection failed: %s", err)
|
||||
}
|
||||
defer m.Disconnect()
|
||||
|
||||
c := mgr.Config{
|
||||
StartType: mgr.StartDisabled,
|
||||
DisplayName: "my service",
|
||||
Description: "my service is just a test",
|
||||
Dependencies: []string{"LanmanServer", "W32Time"},
|
||||
}
|
||||
|
||||
exename := os.Args[0]
|
||||
exepath, err := filepath.Abs(exename)
|
||||
if err != nil {
|
||||
t.Fatalf("filepath.Abs(%s) failed: %s", exename, err)
|
||||
}
|
||||
|
||||
install(t, m, name, exepath, c)
|
||||
|
||||
s, err := m.OpenService(name)
|
||||
if err != nil {
|
||||
t.Fatalf("service %s is not installed", name)
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
c.BinaryPathName = exepath
|
||||
c = testConfig(t, s, c)
|
||||
|
||||
c.StartType = mgr.StartManual
|
||||
err = s.UpdateConfig(c)
|
||||
if err != nil {
|
||||
t.Fatalf("UpdateConfig failed: %v", err)
|
||||
}
|
||||
|
||||
testConfig(t, s, c)
|
||||
|
||||
svcnames, err := m.ListServices()
|
||||
if err != nil {
|
||||
t.Fatalf("ListServices failed: %v", err)
|
||||
}
|
||||
var myserviceIsInstalled bool
|
||||
for _, sn := range svcnames {
|
||||
if sn == name {
|
||||
myserviceIsInstalled = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !myserviceIsInstalled {
|
||||
t.Errorf("ListServices failed to find %q service", name)
|
||||
}
|
||||
|
||||
testSetRecoveryActions(t, s)
|
||||
testRebootMessage(t, s, "myservice failed")
|
||||
testRebootMessage(t, s, "") // delete reboot message
|
||||
testRecoveryCommand(t, s, "sc query myservice")
|
||||
testRecoveryCommand(t, s, "") // delete recovery command
|
||||
|
||||
remove(t, s)
|
||||
}
|
135
vendor/golang.org/x/sys/windows/svc/mgr/recovery.go
generated
vendored
135
vendor/golang.org/x/sys/windows/svc/mgr/recovery.go
generated
vendored
@ -1,135 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
// Possible recovery actions that the service control manager can perform.
|
||||
NoAction = windows.SC_ACTION_NONE // no action
|
||||
ComputerReboot = windows.SC_ACTION_REBOOT // reboot the computer
|
||||
ServiceRestart = windows.SC_ACTION_RESTART // restart the service
|
||||
RunCommand = windows.SC_ACTION_RUN_COMMAND // run a command
|
||||
)
|
||||
|
||||
// RecoveryAction represents an action that the service control manager can perform when service fails.
|
||||
// A service is considered failed when it terminates without reporting a status of SERVICE_STOPPED to the service controller.
|
||||
type RecoveryAction struct {
|
||||
Type int // one of NoAction, ComputerReboot, ServiceRestart or RunCommand
|
||||
Delay time.Duration // the time to wait before performing the specified action
|
||||
}
|
||||
|
||||
// SetRecoveryActions sets actions that service controller performs when service fails and
|
||||
// the time after which to reset the service failure count to zero if there are no failures, in seconds.
|
||||
// Specify INFINITE to indicate that service failure count should never be reset.
|
||||
func (s *Service) SetRecoveryActions(recoveryActions []RecoveryAction, resetPeriod uint32) error {
|
||||
if recoveryActions == nil {
|
||||
return errors.New("recoveryActions cannot be nil")
|
||||
}
|
||||
actions := []windows.SC_ACTION{}
|
||||
for _, a := range recoveryActions {
|
||||
action := windows.SC_ACTION{
|
||||
Type: uint32(a.Type),
|
||||
Delay: uint32(a.Delay.Nanoseconds() / 1000000),
|
||||
}
|
||||
actions = append(actions, action)
|
||||
}
|
||||
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||
ActionsCount: uint32(len(actions)),
|
||||
Actions: &actions[0],
|
||||
ResetPeriod: resetPeriod,
|
||||
}
|
||||
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||
}
|
||||
|
||||
// RecoveryActions returns actions that service controller performs when service fails.
|
||||
// The service control manager counts the number of times service s has failed since the system booted.
|
||||
// The count is reset to 0 if the service has not failed for ResetPeriod seconds.
|
||||
// When the service fails for the Nth time, the service controller performs the action specified in element [N-1] of returned slice.
|
||||
// If N is greater than slice length, the service controller repeats the last action in the slice.
|
||||
func (s *Service) RecoveryActions() ([]RecoveryAction, error) {
|
||||
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
|
||||
if p.Actions == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var recoveryActions []RecoveryAction
|
||||
actions := (*[1024]windows.SC_ACTION)(unsafe.Pointer(p.Actions))[:p.ActionsCount]
|
||||
for _, action := range actions {
|
||||
recoveryActions = append(recoveryActions, RecoveryAction{Type: int(action.Type), Delay: time.Duration(action.Delay) * time.Millisecond})
|
||||
}
|
||||
return recoveryActions, nil
|
||||
}
|
||||
|
||||
// ResetRecoveryActions deletes both reset period and array of failure actions.
|
||||
func (s *Service) ResetRecoveryActions() error {
|
||||
actions := make([]windows.SC_ACTION, 1)
|
||||
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||
Actions: &actions[0],
|
||||
}
|
||||
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||
}
|
||||
|
||||
// ResetPeriod is the time after which to reset the service failure
|
||||
// count to zero if there are no failures, in seconds.
|
||||
func (s *Service) ResetPeriod() (uint32, error) {
|
||||
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
|
||||
return p.ResetPeriod, nil
|
||||
}
|
||||
|
||||
// SetRebootMessage sets service s reboot message.
|
||||
// If msg is "", the reboot message is deleted and no message is broadcast.
|
||||
func (s *Service) SetRebootMessage(msg string) error {
|
||||
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||
RebootMsg: syscall.StringToUTF16Ptr(msg),
|
||||
}
|
||||
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||
}
|
||||
|
||||
// RebootMessage is broadcast to server users before rebooting in response to the ComputerReboot service controller action.
|
||||
func (s *Service) RebootMessage() (string, error) {
|
||||
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
|
||||
return toString(p.RebootMsg), nil
|
||||
}
|
||||
|
||||
// SetRecoveryCommand sets the command line of the process to execute in response to the RunCommand service controller action.
|
||||
// If cmd is "", the command is deleted and no program is run when the service fails.
|
||||
func (s *Service) SetRecoveryCommand(cmd string) error {
|
||||
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||
Command: syscall.StringToUTF16Ptr(cmd),
|
||||
}
|
||||
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||
}
|
||||
|
||||
// RecoveryCommand is the command line of the process to execute in response to the RunCommand service controller action. This process runs under the same account as the service.
|
||||
func (s *Service) RecoveryCommand() (string, error) {
|
||||
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
|
||||
return toString(p.Command), nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user