Compare commits

...

1 commit

Author SHA1 Message Date
3da4271c66 chore(deps): update module github.com/rs/zerolog to v1.33.0
Some checks are pending
/ Release (push) Waiting to run
2024-08-23 23:11:20 +00:00
299 changed files with 45701 additions and 10576 deletions

6
go.mod
View file

@ -4,7 +4,7 @@ go 1.17
require ( require (
github.com/mackerelio/go-osstat v0.2.0 github.com/mackerelio/go-osstat v0.2.0
github.com/rs/zerolog v1.25.0 github.com/rs/zerolog v1.33.0
github.com/shirou/gopsutil v3.21.8+incompatible github.com/shirou/gopsutil v3.21.8+incompatible
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
@ -12,5 +12,7 @@ require (
require ( require (
github.com/StackExchange/wmi v1.2.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-ole/go-ole v1.2.5 // indirect
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
golang.org/x/sys v0.12.0 // indirect
) )

13
go.sum
View file

@ -1,15 +1,24 @@
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/mackerelio/go-osstat v0.2.0 h1:UVn9Am/OOj2Ig0LNNHLqiHeXsZWmMNcMPZ3h+z/8+h8= github.com/mackerelio/go-osstat v0.2.0 h1:UVn9Am/OOj2Ig0LNNHLqiHeXsZWmMNcMPZ3h+z/8+h8=
github.com/mackerelio/go-osstat v0.2.0/go.mod h1:UzRL8dMCCTqG5WdRtsxbuljMpZt9PCAGXqxPst5QtaY= github.com/mackerelio/go-osstat v0.2.0/go.mod h1:UzRL8dMCCTqG5WdRtsxbuljMpZt9PCAGXqxPst5QtaY=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II= github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II=
github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI= github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/shirou/gopsutil v3.21.8+incompatible h1:sh0foI8tMRlCidUJR+KzqWYWxrkuuPIGiO6Vp+KXdCU= github.com/shirou/gopsutil v3.21.8+incompatible h1:sh0foI8tMRlCidUJR+KzqWYWxrkuuPIGiO6Vp+KXdCU=
github.com/shirou/gopsutil v3.21.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
@ -30,6 +39,10 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 h1:7ZDGnxgHAMw7thfC5bEos0RDAccZKxioiWBhfIe+tvw= golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 h1:7ZDGnxgHAMw7thfC5bEos0RDAccZKxioiWBhfIe+tvw=
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

21
vendor/github.com/mattn/go-colorable/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Yasuhiro Matsumoto
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

48
vendor/github.com/mattn/go-colorable/README.md generated vendored Normal file
View file

@ -0,0 +1,48 @@
# go-colorable
[![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest)
[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable)
[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable)
[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)
Colorable writer for windows.
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
This package is possible to handle escape sequence for ansi color on windows.
## Too Bad!
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)
## So Good!
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)
## Usage
```go
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
logrus.SetOutput(colorable.NewColorableStdout())
logrus.Info("succeeded")
logrus.Warn("not correct")
logrus.Error("something error")
logrus.Fatal("panic")
```
You can compile above code on non-windows OSs.
## Installation
```
$ go get github.com/mattn/go-colorable
```
# License
MIT
# Author
Yasuhiro Matsumoto (a.k.a mattn)

View file

@ -0,0 +1,38 @@
//go:build appengine
// +build appengine
package colorable
import (
"io"
"os"
_ "github.com/mattn/go-isatty"
)
// NewColorable returns new instance of Writer which handles escape sequence.
func NewColorable(file *os.File) io.Writer {
if file == nil {
panic("nil passed instead of *os.File to NewColorable()")
}
return file
}
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
func NewColorableStdout() io.Writer {
return os.Stdout
}
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
func NewColorableStderr() io.Writer {
return os.Stderr
}
// EnableColorsStdout enable colors if possible.
func EnableColorsStdout(enabled *bool) func() {
if enabled != nil {
*enabled = true
}
return func() {}
}

View file

@ -0,0 +1,38 @@
//go:build !windows && !appengine
// +build !windows,!appengine
package colorable
import (
"io"
"os"
_ "github.com/mattn/go-isatty"
)
// NewColorable returns new instance of Writer which handles escape sequence.
func NewColorable(file *os.File) io.Writer {
if file == nil {
panic("nil passed instead of *os.File to NewColorable()")
}
return file
}
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
func NewColorableStdout() io.Writer {
return os.Stdout
}
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
func NewColorableStderr() io.Writer {
return os.Stderr
}
// EnableColorsStdout enable colors if possible.
func EnableColorsStdout(enabled *bool) func() {
if enabled != nil {
*enabled = true
}
return func() {}
}

1047
vendor/github.com/mattn/go-colorable/colorable_windows.go generated vendored Normal file

File diff suppressed because it is too large Load diff

12
vendor/github.com/mattn/go-colorable/go.test.sh generated vendored Normal file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
echo "" > coverage.txt
for d in $(go list ./... | grep -v vendor); do
go test -race -coverprofile=profile.out -covermode=atomic "$d"
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
rm profile.out
fi
done

57
vendor/github.com/mattn/go-colorable/noncolorable.go generated vendored Normal file
View file

@ -0,0 +1,57 @@
package colorable
import (
"bytes"
"io"
)
// NonColorable holds writer but removes escape sequence.
type NonColorable struct {
out io.Writer
}
// NewNonColorable returns new instance of Writer which removes escape sequence from Writer.
func NewNonColorable(w io.Writer) io.Writer {
return &NonColorable{out: w}
}
// Write writes data on console
func (w *NonColorable) Write(data []byte) (n int, err error) {
er := bytes.NewReader(data)
var plaintext bytes.Buffer
loop:
for {
c1, err := er.ReadByte()
if err != nil {
plaintext.WriteTo(w.out)
break loop
}
if c1 != 0x1b {
plaintext.WriteByte(c1)
continue
}
_, err = plaintext.WriteTo(w.out)
if err != nil {
break loop
}
c2, err := er.ReadByte()
if err != nil {
break loop
}
if c2 != 0x5b {
continue
}
for {
c, err := er.ReadByte()
if err != nil {
break loop
}
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
break
}
}
}
return len(data), nil
}

9
vendor/github.com/mattn/go-isatty/LICENSE generated vendored Normal file
View file

@ -0,0 +1,9 @@
Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>
MIT License (Expat)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

50
vendor/github.com/mattn/go-isatty/README.md generated vendored Normal file
View file

@ -0,0 +1,50 @@
# go-isatty
[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)
[![Codecov](https://codecov.io/gh/mattn/go-isatty/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-isatty)
[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)
[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty)
isatty for golang
## Usage
```go
package main
import (
"fmt"
"github.com/mattn/go-isatty"
"os"
)
func main() {
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Println("Is Terminal")
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
fmt.Println("Is Cygwin/MSYS2 Terminal")
} else {
fmt.Println("Is Not Terminal")
}
}
```
## Installation
```
$ go get github.com/mattn/go-isatty
```
## License
MIT
## Author
Yasuhiro Matsumoto (a.k.a mattn)
## Thanks
* k-takata: base idea for IsCygwinTerminal
https://github.com/k-takata/go-iscygpty

2
vendor/github.com/mattn/go-isatty/doc.go generated vendored Normal file
View file

@ -0,0 +1,2 @@
// Package isatty implements interface to isatty
package isatty

12
vendor/github.com/mattn/go-isatty/go.test.sh generated vendored Normal file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
echo "" > coverage.txt
for d in $(go list ./... | grep -v vendor); do
go test -race -coverprofile=profile.out -covermode=atomic "$d"
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
rm profile.out
fi
done

19
vendor/github.com/mattn/go-isatty/isatty_bsd.go generated vendored Normal file
View file

@ -0,0 +1,19 @@
//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine
// +build darwin freebsd openbsd netbsd dragonfly hurd
// +build !appengine
package isatty
import "golang.org/x/sys/unix"
// IsTerminal return true if the file descriptor is terminal.
func IsTerminal(fd uintptr) bool {
_, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA)
return err == nil
}
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}

16
vendor/github.com/mattn/go-isatty/isatty_others.go generated vendored Normal file
View file

@ -0,0 +1,16 @@
//go:build appengine || js || nacl || wasm
// +build appengine js nacl wasm
package isatty
// IsTerminal returns true if the file descriptor is terminal which
// is always false on js and appengine classic which is a sandboxed PaaS.
func IsTerminal(fd uintptr) bool {
return false
}
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}

23
vendor/github.com/mattn/go-isatty/isatty_plan9.go generated vendored Normal file
View file

@ -0,0 +1,23 @@
//go:build plan9
// +build plan9
package isatty
import (
"syscall"
)
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd uintptr) bool {
path, err := syscall.Fd2path(int(fd))
if err != nil {
return false
}
return path == "/dev/cons" || path == "/mnt/term/dev/cons"
}
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}

21
vendor/github.com/mattn/go-isatty/isatty_solaris.go generated vendored Normal file
View file

@ -0,0 +1,21 @@
//go:build solaris && !appengine
// +build solaris,!appengine
package isatty
import (
"golang.org/x/sys/unix"
)
// IsTerminal returns true if the given file descriptor is a terminal.
// see: https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c
func IsTerminal(fd uintptr) bool {
_, err := unix.IoctlGetTermio(int(fd), unix.TCGETA)
return err == nil
}
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}

19
vendor/github.com/mattn/go-isatty/isatty_tcgets.go generated vendored Normal file
View file

@ -0,0 +1,19 @@
//go:build (linux || aix || zos) && !appengine
// +build linux aix zos
// +build !appengine
package isatty
import "golang.org/x/sys/unix"
// IsTerminal return true if the file descriptor is terminal.
func IsTerminal(fd uintptr) bool {
_, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
return err == nil
}
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}

125
vendor/github.com/mattn/go-isatty/isatty_windows.go generated vendored Normal file
View file

@ -0,0 +1,125 @@
//go:build windows && !appengine
// +build windows,!appengine
package isatty
import (
"errors"
"strings"
"syscall"
"unicode/utf16"
"unsafe"
)
const (
objectNameInfo uintptr = 1
fileNameInfo = 2
fileTypePipe = 3
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
ntdll = syscall.NewLazyDLL("ntdll.dll")
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
procGetFileType = kernel32.NewProc("GetFileType")
procNtQueryObject = ntdll.NewProc("NtQueryObject")
)
func init() {
// Check if GetFileInformationByHandleEx is available.
if procGetFileInformationByHandleEx.Find() != nil {
procGetFileInformationByHandleEx = nil
}
}
// IsTerminal return true if the file descriptor is terminal.
func IsTerminal(fd uintptr) bool {
var st uint32
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
return r != 0 && e == 0
}
// Check pipe name is used for cygwin/msys2 pty.
// Cygwin/MSYS2 PTY has a name like:
// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
func isCygwinPipeName(name string) bool {
token := strings.Split(name, "-")
if len(token) < 5 {
return false
}
if token[0] != `\msys` &&
token[0] != `\cygwin` &&
token[0] != `\Device\NamedPipe\msys` &&
token[0] != `\Device\NamedPipe\cygwin` {
return false
}
if token[1] == "" {
return false
}
if !strings.HasPrefix(token[2], "pty") {
return false
}
if token[3] != `from` && token[3] != `to` {
return false
}
if token[4] != "master" {
return false
}
return true
}
// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion
// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
// Windows vista to 10
// see https://stackoverflow.com/a/18792477 for details
func getFileNameByHandle(fd uintptr) (string, error) {
if procNtQueryObject == nil {
return "", errors.New("ntdll.dll: NtQueryObject not supported")
}
var buf [4 + syscall.MAX_PATH]uint16
var result int
r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,
fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)
if r != 0 {
return "", e
}
return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil
}
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
// terminal.
func IsCygwinTerminal(fd uintptr) bool {
if procGetFileInformationByHandleEx == nil {
name, err := getFileNameByHandle(fd)
if err != nil {
return false
}
return isCygwinPipeName(name)
}
// Cygwin/msys's pty is a pipe.
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
if ft != fileTypePipe || e != 0 {
return false
}
var buf [2 + syscall.MAX_PATH]uint16
r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
uintptr(len(buf)*2), 0, 0)
if r == 0 || e != 0 {
return false
}
l := *(*uint32)(unsafe.Pointer(&buf))
return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
}

View file

@ -1,6 +1,6 @@
# Zero Allocation JSON Logger # Zero Allocation JSON Logger
[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/zerolog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/zerolog/master/LICENSE) [![Build Status](https://travis-ci.org/rs/zerolog.svg?branch=master)](https://travis-ci.org/rs/zerolog) [![Coverage](http://gocover.io/_badge/github.com/rs/zerolog)](http://gocover.io/github.com/rs/zerolog) [![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/zerolog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/zerolog/master/LICENSE) [![Build Status](https://github.com/rs/zerolog/actions/workflows/test.yml/badge.svg)](https://github.com/rs/zerolog/actions/workflows/test.yml) [![Go Coverage](https://github.com/rs/zerolog/wiki/coverage.svg)](https://raw.githack.com/wiki/rs/zerolog/coverage.html)
The zerolog package provides a fast and simple logger dedicated to JSON output. The zerolog package provides a fast and simple logger dedicated to JSON output.
@ -24,7 +24,7 @@ Find out [who uses zerolog](https://github.com/rs/zerolog/wiki/Who-uses-zerolog)
* [Sampling](#log-sampling) * [Sampling](#log-sampling)
* [Hooks](#hooks) * [Hooks](#hooks)
* [Contextual fields](#contextual-logging) * [Contextual fields](#contextual-logging)
* `context.Context` integration * [`context.Context` integration](#contextcontext-integration)
* [Integration with `net/http`](#integration-with-nethttp) * [Integration with `net/http`](#integration-with-nethttp)
* [JSON and CBOR encoding formats](#binary-encoding) * [JSON and CBOR encoding formats](#binary-encoding)
* [Pretty logging for development](#pretty-logging) * [Pretty logging for development](#pretty-logging)
@ -60,7 +60,7 @@ func main() {
// Output: {"time":1516134303,"level":"debug","message":"hello world"} // Output: {"time":1516134303,"level":"debug","message":"hello world"}
``` ```
> Note: By default log writes to `os.Stderr` > Note: By default log writes to `os.Stderr`
> Note: The default log level for `log.Print` is *debug* > Note: The default log level for `log.Print` is *trace*
### Contextual Logging ### Contextual Logging
@ -399,6 +399,8 @@ log.Logger = log.With().Str("foo", "bar").Logger()
### Add file and line number to log ### Add file and line number to log
Equivalent of `Llongfile`:
```go ```go
log.Logger = log.With().Caller().Logger() log.Logger = log.With().Caller().Logger()
log.Info().Msg("hello world") log.Info().Msg("hello world")
@ -406,10 +408,21 @@ log.Info().Msg("hello world")
// Output: {"level": "info", "message": "hello world", "caller": "/go/src/your_project/some_file:21"} // Output: {"level": "info", "message": "hello world", "caller": "/go/src/your_project/some_file:21"}
``` ```
Equivalent of `Lshortfile`:
```go
zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string {
return filepath.Base(file) + ":" + strconv.Itoa(line)
}
log.Logger = log.With().Caller().Logger()
log.Info().Msg("hello world")
// Output: {"level": "info", "message": "hello world", "caller": "some_file:21"}
```
### Thread-safe, lock-free, non-blocking writer ### Thread-safe, lock-free, non-blocking writer
If your writer might be slow or not thread-safe and you need your log producers to never get slowed down by a slow writer, you can use a `diode.Writer` as follow: If your writer might be slow or not thread-safe and you need your log producers to never get slowed down by a slow writer, you can use a `diode.Writer` as follows:
```go ```go
wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) { wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) {
@ -490,6 +503,58 @@ stdlog.Print("hello world")
// Output: {"foo":"bar","message":"hello world"} // Output: {"foo":"bar","message":"hello world"}
``` ```
### context.Context integration
Go contexts are commonly passed throughout Go code, and this can help you pass
your Logger into places it might otherwise be hard to inject. The `Logger`
instance may be attached to Go context (`context.Context`) using
`Logger.WithContext(ctx)` and extracted from it using `zerolog.Ctx(ctx)`.
For example:
```go
func f() {
logger := zerolog.New(os.Stdout)
ctx := context.Background()
// Attach the Logger to the context.Context
ctx = logger.WithContext(ctx)
someFunc(ctx)
}
func someFunc(ctx context.Context) {
// Get Logger from the go Context. if it's nil, then
// `zerolog.DefaultContextLogger` is returned, if
// `DefaultContextLogger` is nil, then a disabled logger is returned.
logger := zerolog.Ctx(ctx)
logger.Info().Msg("Hello")
}
```
A second form of `context.Context` integration allows you to pass the current
context.Context into the logged event, and retrieve it from hooks. This can be
useful to log trace and span IDs or other information stored in the go context,
and facilitates the unification of logging and tracing in some systems:
```go
type TracingHook struct{}
func (h TracingHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
ctx := e.GetCtx()
spanId := getSpanIdFromContext(ctx) // as per your tracing framework
e.Str("span-id", spanId)
}
func f() {
// Setup the logger
logger := zerolog.New(os.Stdout)
logger = logger.Hook(TracingHook{})
ctx := context.Background()
// Use the Ctx function to make the context available to the hook
logger.Info().Ctx(ctx).Msg("Hello")
}
```
### Integration with `net/http` ### Integration with `net/http`
The `github.com/rs/zerolog/hlog` package provides some helpers to integrate zerolog with `http.Handler`. The `github.com/rs/zerolog/hlog` package provides some helpers to integrate zerolog with `http.Handler`.
@ -564,7 +629,7 @@ func main() {
## Global Settings ## Global Settings
Some settings can be changed and will by applied to all loggers: Some settings can be changed and will be applied to all loggers:
* `log.Logger`: You can set this value to customize the global logger (the one used by package level methods). * `log.Logger`: You can set this value to customize the global logger (the one used by package level methods).
* `zerolog.SetGlobalLevel`: Can raise the minimum level of all loggers. Call this with `zerolog.Disabled` to disable logging altogether (quiet mode). * `zerolog.SetGlobalLevel`: Can raise the minimum level of all loggers. Call this with `zerolog.Disabled` to disable logging altogether (quiet mode).
@ -573,10 +638,14 @@ Some settings can be changed and will by applied to all loggers:
* `zerolog.LevelFieldName`: Can be set to customize level field name. * `zerolog.LevelFieldName`: Can be set to customize level field name.
* `zerolog.MessageFieldName`: Can be set to customize message field name. * `zerolog.MessageFieldName`: Can be set to customize message field name.
* `zerolog.ErrorFieldName`: Can be set to customize `Err` field name. * `zerolog.ErrorFieldName`: Can be set to customize `Err` field name.
* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formated as UNIX timestamp. * `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formatted as UNIX timestamp.
* `zerolog.DurationFieldUnit`: Can be set to customize the unit for time.Duration type fields added by `Dur` (default: `time.Millisecond`). * `zerolog.DurationFieldUnit`: Can be set to customize the unit for time.Duration type fields added by `Dur` (default: `time.Millisecond`).
* `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`). * `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`).
* `zerolog.ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking. * `zerolog.ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking.
* `zerolog.FloatingPointPrecision`: If set to a value other than -1, controls the number
of digits when formatting float numbers in JSON. See
[strconv.FormatFloat](https://pkg.go.dev/strconv#FormatFloat)
for more details.
## Field Types ## Field Types
@ -604,7 +673,7 @@ Most fields are also available in the slice format (`Strs` for `[]string`, `Errs
## Binary Encoding ## Binary Encoding
In addition to the default JSON encoding, `zerolog` can produce binary logs using [CBOR](http://cbor.io) encoding. The choice of encoding can be decided at compile time using the build tag `binary_log` as follows: In addition to the default JSON encoding, `zerolog` can produce binary logs using [CBOR](https://cbor.io) encoding. The choice of encoding can be decided at compile time using the build tag `binary_log` as follows:
```bash ```bash
go build -tags binary_log . go build -tags binary_log .
@ -617,11 +686,11 @@ with zerolog library is [CSD](https://github.com/toravir/csd/).
* [grpc-zerolog](https://github.com/cheapRoc/grpc-zerolog): Implementation of `grpclog.LoggerV2` interface using `zerolog` * [grpc-zerolog](https://github.com/cheapRoc/grpc-zerolog): Implementation of `grpclog.LoggerV2` interface using `zerolog`
* [overlog](https://github.com/Trendyol/overlog): Implementation of `Mapped Diagnostic Context` interface using `zerolog` * [overlog](https://github.com/Trendyol/overlog): Implementation of `Mapped Diagnostic Context` interface using `zerolog`
* [zerologr](https://github.com/hn8/zerologr): Implementation of `logr.LogSink` interface using `zerolog` * [zerologr](https://github.com/go-logr/zerologr): Implementation of `logr.LogSink` interface using `zerolog`
## Benchmarks ## Benchmarks
See [logbench](http://hackemist.com/logbench/) for more comprehensive and up-to-date benchmarks. See [logbench](http://bench.zerolog.io/) for more comprehensive and up-to-date benchmarks.
All operations are allocation free (those numbers *include* JSON encoding): All operations are allocation free (those numbers *include* JSON encoding):
@ -682,6 +751,8 @@ Log a static string, without any context or `printf`-style templating:
## Caveats ## Caveats
### Field duplication
Note that zerolog does no de-duplication of fields. Using the same key multiple times creates multiple keys in final JSON: Note that zerolog does no de-duplication of fields. Using the same key multiple times creates multiple keys in final JSON:
```go ```go
@ -693,3 +764,19 @@ logger.Info().
``` ```
In this case, many consumers will take the last value, but this is not guaranteed; check yours if in doubt. In this case, many consumers will take the last value, but this is not guaranteed; check yours if in doubt.
### Concurrency safety
Be careful when calling UpdateContext. It is not concurrency safe. Use the With method to create a child logger:
```go
func handler(w http.ResponseWriter, r *http.Request) {
// Create a child logger for concurrency safety
logger := log.Logger.With().Logger()
// Add context fields, for example User-Agent from HTTP headers
logger.UpdateContext(func(c zerolog.Context) zerolog.Context {
...
})
}
```

View file

@ -49,7 +49,7 @@ func (*Array) MarshalZerologArray(*Array) {
func (a *Array) write(dst []byte) []byte { func (a *Array) write(dst []byte) []byte {
dst = enc.AppendArrayStart(dst) dst = enc.AppendArrayStart(dst)
if len(a.buf) > 0 { if len(a.buf) > 0 {
dst = append(append(dst, a.buf...)) dst = append(dst, a.buf...)
} }
dst = enc.AppendArrayEnd(dst) dst = enc.AppendArrayEnd(dst)
putArray(a) putArray(a)
@ -57,7 +57,7 @@ func (a *Array) write(dst []byte) []byte {
} }
// Object marshals an object that implement the LogObjectMarshaler // Object marshals an object that implement the LogObjectMarshaler
// interface and append append it to the array. // interface and appends it to the array.
func (a *Array) Object(obj LogObjectMarshaler) *Array { func (a *Array) Object(obj LogObjectMarshaler) *Array {
e := Dict() e := Dict()
obj.MarshalZerologObject(e) obj.MarshalZerologObject(e)
@ -67,19 +67,19 @@ func (a *Array) Object(obj LogObjectMarshaler) *Array {
return a return a
} }
// Str append append the val as a string to the array. // Str appends the val as a string to the array.
func (a *Array) Str(val string) *Array { func (a *Array) Str(val string) *Array {
a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), val) a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), val)
return a return a
} }
// Bytes append append the val as a string to the array. // Bytes appends the val as a string to the array.
func (a *Array) Bytes(val []byte) *Array { func (a *Array) Bytes(val []byte) *Array {
a.buf = enc.AppendBytes(enc.AppendArrayDelim(a.buf), val) a.buf = enc.AppendBytes(enc.AppendArrayDelim(a.buf), val)
return a return a
} }
// Hex append append the val as a hex string to the array. // Hex appends the val as a hex string to the array.
func (a *Array) Hex(val []byte) *Array { func (a *Array) Hex(val []byte) *Array {
a.buf = enc.AppendHex(enc.AppendArrayDelim(a.buf), val) a.buf = enc.AppendHex(enc.AppendArrayDelim(a.buf), val)
return a return a
@ -115,97 +115,97 @@ func (a *Array) Err(err error) *Array {
return a return a
} }
// Bool append append the val as a bool to the array. // Bool appends the val as a bool to the array.
func (a *Array) Bool(b bool) *Array { func (a *Array) Bool(b bool) *Array {
a.buf = enc.AppendBool(enc.AppendArrayDelim(a.buf), b) a.buf = enc.AppendBool(enc.AppendArrayDelim(a.buf), b)
return a return a
} }
// Int append append i as a int to the array. // Int appends i as a int to the array.
func (a *Array) Int(i int) *Array { func (a *Array) Int(i int) *Array {
a.buf = enc.AppendInt(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendInt(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Int8 append append i as a int8 to the array. // Int8 appends i as a int8 to the array.
func (a *Array) Int8(i int8) *Array { func (a *Array) Int8(i int8) *Array {
a.buf = enc.AppendInt8(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendInt8(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Int16 append append i as a int16 to the array. // Int16 appends i as a int16 to the array.
func (a *Array) Int16(i int16) *Array { func (a *Array) Int16(i int16) *Array {
a.buf = enc.AppendInt16(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendInt16(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Int32 append append i as a int32 to the array. // Int32 appends i as a int32 to the array.
func (a *Array) Int32(i int32) *Array { func (a *Array) Int32(i int32) *Array {
a.buf = enc.AppendInt32(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendInt32(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Int64 append append i as a int64 to the array. // Int64 appends i as a int64 to the array.
func (a *Array) Int64(i int64) *Array { func (a *Array) Int64(i int64) *Array {
a.buf = enc.AppendInt64(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendInt64(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Uint append append i as a uint to the array. // Uint appends i as a uint to the array.
func (a *Array) Uint(i uint) *Array { func (a *Array) Uint(i uint) *Array {
a.buf = enc.AppendUint(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendUint(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Uint8 append append i as a uint8 to the array. // Uint8 appends i as a uint8 to the array.
func (a *Array) Uint8(i uint8) *Array { func (a *Array) Uint8(i uint8) *Array {
a.buf = enc.AppendUint8(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendUint8(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Uint16 append append i as a uint16 to the array. // Uint16 appends i as a uint16 to the array.
func (a *Array) Uint16(i uint16) *Array { func (a *Array) Uint16(i uint16) *Array {
a.buf = enc.AppendUint16(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendUint16(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Uint32 append append i as a uint32 to the array. // Uint32 appends i as a uint32 to the array.
func (a *Array) Uint32(i uint32) *Array { func (a *Array) Uint32(i uint32) *Array {
a.buf = enc.AppendUint32(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendUint32(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Uint64 append append i as a uint64 to the array. // Uint64 appends i as a uint64 to the array.
func (a *Array) Uint64(i uint64) *Array { func (a *Array) Uint64(i uint64) *Array {
a.buf = enc.AppendUint64(enc.AppendArrayDelim(a.buf), i) a.buf = enc.AppendUint64(enc.AppendArrayDelim(a.buf), i)
return a return a
} }
// Float32 append append f as a float32 to the array. // Float32 appends f as a float32 to the array.
func (a *Array) Float32(f float32) *Array { func (a *Array) Float32(f float32) *Array {
a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f) a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f, FloatingPointPrecision)
return a return a
} }
// Float64 append append f as a float64 to the array. // Float64 appends f as a float64 to the array.
func (a *Array) Float64(f float64) *Array { func (a *Array) Float64(f float64) *Array {
a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f) a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f, FloatingPointPrecision)
return a return a
} }
// Time append append t formated as string using zerolog.TimeFieldFormat. // Time appends t formatted as string using zerolog.TimeFieldFormat.
func (a *Array) Time(t time.Time) *Array { func (a *Array) Time(t time.Time) *Array {
a.buf = enc.AppendTime(enc.AppendArrayDelim(a.buf), t, TimeFieldFormat) a.buf = enc.AppendTime(enc.AppendArrayDelim(a.buf), t, TimeFieldFormat)
return a return a
} }
// Dur append append d to the array. // Dur appends d to the array.
func (a *Array) Dur(d time.Duration) *Array { func (a *Array) Dur(d time.Duration) *Array {
a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger) a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
return a return a
} }
// Interface append append i marshaled using reflection. // Interface appends i marshaled using reflection.
func (a *Array) Interface(i interface{}) *Array { func (a *Array) Interface(i interface{}) *Array {
if obj, ok := i.(LogObjectMarshaler); ok { if obj, ok := i.(LogObjectMarshaler); ok {
return a.Object(obj) return a.Object(obj)
@ -231,3 +231,10 @@ func (a *Array) MACAddr(ha net.HardwareAddr) *Array {
a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha) a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha)
return a return a
} }
// Dict adds the dict Event to the array
func (a *Array) Dict(dict *Event) *Array {
dict.buf = enc.AppendEndMarker(dict.buf)
a.buf = append(enc.AppendArrayDelim(a.buf), dict.buf...)
return a
}

View file

@ -12,6 +12,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/mattn/go-colorable"
) )
const ( const (
@ -26,6 +28,8 @@ const (
colorBold = 1 colorBold = 1
colorDarkGray = 90 colorDarkGray = 90
unknownLevel = "???"
) )
var ( var (
@ -55,12 +59,24 @@ type ConsoleWriter struct {
// TimeFormat specifies the format for timestamp in output. // TimeFormat specifies the format for timestamp in output.
TimeFormat string TimeFormat string
// TimeLocation tells ConsoleWriters default FormatTimestamp
// how to localize the time.
TimeLocation *time.Location
// PartsOrder defines the order of parts in output. // PartsOrder defines the order of parts in output.
PartsOrder []string PartsOrder []string
// PartsExclude defines parts to not display in output. // PartsExclude defines parts to not display in output.
PartsExclude []string PartsExclude []string
// FieldsOrder defines the order of contextual fields in output.
FieldsOrder []string
fieldIsOrdered map[string]int
// FieldsExclude defines contextual fields to not display in output.
FieldsExclude []string
FormatTimestamp Formatter FormatTimestamp Formatter
FormatLevel Formatter FormatLevel Formatter
FormatCaller Formatter FormatCaller Formatter
@ -69,6 +85,10 @@ type ConsoleWriter struct {
FormatFieldValue Formatter FormatFieldValue Formatter
FormatErrFieldName Formatter FormatErrFieldName Formatter
FormatErrFieldValue Formatter FormatErrFieldValue Formatter
FormatExtra func(map[string]interface{}, *bytes.Buffer) error
FormatPrepare func(map[string]interface{}) error
} }
// NewConsoleWriter creates and initializes a new ConsoleWriter. // NewConsoleWriter creates and initializes a new ConsoleWriter.
@ -83,11 +103,21 @@ func NewConsoleWriter(options ...func(w *ConsoleWriter)) ConsoleWriter {
opt(&w) opt(&w)
} }
// Fix color on Windows
if w.Out == os.Stdout || w.Out == os.Stderr {
w.Out = colorable.NewColorable(w.Out.(*os.File))
}
return w return w
} }
// Write transforms the JSON input with formatters and appends to w.Out. // Write transforms the JSON input with formatters and appends to w.Out.
func (w ConsoleWriter) Write(p []byte) (n int, err error) { func (w ConsoleWriter) Write(p []byte) (n int, err error) {
// Fix color on Windows
if w.Out == os.Stdout || w.Out == os.Stderr {
w.Out = colorable.NewColorable(w.Out.(*os.File))
}
if w.PartsOrder == nil { if w.PartsOrder == nil {
w.PartsOrder = consoleDefaultPartsOrder() w.PartsOrder = consoleDefaultPartsOrder()
} }
@ -107,33 +137,74 @@ func (w ConsoleWriter) Write(p []byte) (n int, err error) {
return n, fmt.Errorf("cannot decode event: %s", err) return n, fmt.Errorf("cannot decode event: %s", err)
} }
if w.FormatPrepare != nil {
err = w.FormatPrepare(evt)
if err != nil {
return n, err
}
}
for _, p := range w.PartsOrder { for _, p := range w.PartsOrder {
w.writePart(buf, evt, p) w.writePart(buf, evt, p)
} }
w.writeFields(evt, buf) w.writeFields(evt, buf)
if w.FormatExtra != nil {
err = w.FormatExtra(evt, buf)
if err != nil {
return n, err
}
}
err = buf.WriteByte('\n') err = buf.WriteByte('\n')
if err != nil { if err != nil {
return n, err return n, err
} }
_, err = buf.WriteTo(w.Out) _, err = buf.WriteTo(w.Out)
return len(p), err return len(p), err
} }
// Call the underlying writer's Close method if it is an io.Closer. Otherwise
// does nothing.
func (w ConsoleWriter) Close() error {
if closer, ok := w.Out.(io.Closer); ok {
return closer.Close()
}
return nil
}
// writeFields appends formatted key-value pairs to buf. // writeFields appends formatted key-value pairs to buf.
func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer) { func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer) {
var fields = make([]string, 0, len(evt)) var fields = make([]string, 0, len(evt))
for field := range evt { for field := range evt {
var isExcluded bool
for _, excluded := range w.FieldsExclude {
if field == excluded {
isExcluded = true
break
}
}
if isExcluded {
continue
}
switch field { switch field {
case LevelFieldName, TimestampFieldName, MessageFieldName, CallerFieldName: case LevelFieldName, TimestampFieldName, MessageFieldName, CallerFieldName:
continue continue
} }
fields = append(fields, field) fields = append(fields, field)
} }
sort.Strings(fields)
if len(fields) > 0 { if len(w.FieldsOrder) > 0 {
w.orderFields(fields)
} else {
sort.Strings(fields)
}
// Write space only if something has already been written to the buffer, and if there are fields.
if buf.Len() > 0 && len(fields) > 0 {
buf.WriteByte(' ') buf.WriteByte(' ')
} }
@ -194,7 +265,7 @@ func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer
case json.Number: case json.Number:
buf.WriteString(fv(fValue)) buf.WriteString(fv(fValue))
default: default:
b, err := json.Marshal(fValue) b, err := InterfaceMarshalFunc(fValue)
if err != nil { if err != nil {
fmt.Fprintf(buf, colorize("[error: %v]", colorRed, w.NoColor), err) fmt.Fprintf(buf, colorize("[error: %v]", colorRed, w.NoColor), err)
} else { } else {
@ -229,13 +300,13 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
} }
case TimestampFieldName: case TimestampFieldName:
if w.FormatTimestamp == nil { if w.FormatTimestamp == nil {
f = consoleDefaultFormatTimestamp(w.TimeFormat, w.NoColor) f = consoleDefaultFormatTimestamp(w.TimeFormat, w.TimeLocation, w.NoColor)
} else { } else {
f = w.FormatTimestamp f = w.FormatTimestamp
} }
case MessageFieldName: case MessageFieldName:
if w.FormatMessage == nil { if w.FormatMessage == nil {
f = consoleDefaultFormatMessage f = consoleDefaultFormatMessage(w.NoColor, evt[LevelFieldName])
} else { } else {
f = w.FormatMessage f = w.FormatMessage
} }
@ -256,11 +327,37 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
var s = f(evt[p]) var s = f(evt[p])
if len(s) > 0 { if len(s) > 0 {
if buf.Len() > 0 {
buf.WriteByte(' ') // Write space only if not the first part
}
buf.WriteString(s) buf.WriteString(s)
if p != w.PartsOrder[len(w.PartsOrder)-1] { // Skip space for last part
buf.WriteByte(' ')
} }
} }
// orderFields takes an array of field names and an array representing field order
// and returns an array with any ordered fields at the beginning, in order,
// and the remaining fields after in their original order.
func (w ConsoleWriter) orderFields(fields []string) {
if w.fieldIsOrdered == nil {
w.fieldIsOrdered = make(map[string]int)
for i, fieldName := range w.FieldsOrder {
w.fieldIsOrdered[fieldName] = i
}
}
sort.Slice(fields, func(i, j int) bool {
ii, iOrdered := w.fieldIsOrdered[fields[i]]
jj, jOrdered := w.fieldIsOrdered[fields[j]]
if iOrdered && jOrdered {
return ii < jj
}
if iOrdered {
return true
}
if jOrdered {
return false
}
return fields[i] < fields[j]
})
} }
// needsQuote returns true when the string s should be quoted in output. // needsQuote returns true when the string s should be quoted in output.
@ -273,8 +370,13 @@ func needsQuote(s string) bool {
return false return false
} }
// colorize returns the string s wrapped in ANSI code c, unless disabled is true. // colorize returns the string s wrapped in ANSI code c, unless disabled is true or c is 0.
func colorize(s interface{}, c int, disabled bool) string { func colorize(s interface{}, c int, disabled bool) string {
e := os.Getenv("NO_COLOR")
if e != "" || c == 0 {
disabled = true
}
if disabled { if disabled {
return fmt.Sprintf("%s", s) return fmt.Sprintf("%s", s)
} }
@ -292,72 +394,74 @@ func consoleDefaultPartsOrder() []string {
} }
} }
func consoleDefaultFormatTimestamp(timeFormat string, noColor bool) Formatter { func consoleDefaultFormatTimestamp(timeFormat string, location *time.Location, noColor bool) Formatter {
if timeFormat == "" { if timeFormat == "" {
timeFormat = consoleDefaultTimeFormat timeFormat = consoleDefaultTimeFormat
} }
if location == nil {
location = time.Local
}
return func(i interface{}) string { return func(i interface{}) string {
t := "<nil>" t := "<nil>"
switch tt := i.(type) { switch tt := i.(type) {
case string: case string:
ts, err := time.Parse(TimeFieldFormat, tt) ts, err := time.ParseInLocation(TimeFieldFormat, tt, location)
if err != nil { if err != nil {
t = tt t = tt
} else { } else {
t = ts.Format(timeFormat) t = ts.In(location).Format(timeFormat)
} }
case json.Number: case json.Number:
i, err := tt.Int64() i, err := tt.Int64()
if err != nil { if err != nil {
t = tt.String() t = tt.String()
} else { } else {
var sec, nsec int64 = i, 0 var sec, nsec int64
switch TimeFieldFormat { switch TimeFieldFormat {
case TimeFormatUnixMs: case TimeFormatUnixNano:
nsec = int64(time.Duration(i) * time.Millisecond) sec, nsec = 0, i
sec = 0
case TimeFormatUnixMicro: case TimeFormatUnixMicro:
nsec = int64(time.Duration(i) * time.Microsecond) sec, nsec = 0, int64(time.Duration(i)*time.Microsecond)
sec = 0 case TimeFormatUnixMs:
sec, nsec = 0, int64(time.Duration(i)*time.Millisecond)
default:
sec, nsec = i, 0
} }
ts := time.Unix(sec, nsec).UTC()
t = ts.Format(timeFormat) ts := time.Unix(sec, nsec)
t = ts.In(location).Format(timeFormat)
} }
} }
return colorize(t, colorDarkGray, noColor) return colorize(t, colorDarkGray, noColor)
} }
} }
func stripLevel(ll string) string {
if len(ll) == 0 {
return unknownLevel
}
if len(ll) > 3 {
ll = ll[:3]
}
return strings.ToUpper(ll)
}
func consoleDefaultFormatLevel(noColor bool) Formatter { func consoleDefaultFormatLevel(noColor bool) Formatter {
return func(i interface{}) string { return func(i interface{}) string {
var l string
if ll, ok := i.(string); ok { if ll, ok := i.(string); ok {
switch ll { level, _ := ParseLevel(ll)
case LevelTraceValue: fl, ok := FormattedLevels[level]
l = colorize("TRC", colorMagenta, noColor) if ok {
case LevelDebugValue: return colorize(fl, LevelColors[level], noColor)
l = colorize("DBG", colorYellow, noColor) }
case LevelInfoValue: return stripLevel(ll)
l = colorize("INF", colorGreen, noColor)
case LevelWarnValue:
l = colorize("WRN", colorRed, noColor)
case LevelErrorValue:
l = colorize(colorize("ERR", colorRed, noColor), colorBold, noColor)
case LevelFatalValue:
l = colorize(colorize("FTL", colorRed, noColor), colorBold, noColor)
case LevelPanicValue:
l = colorize(colorize("PNC", colorRed, noColor), colorBold, noColor)
default:
l = colorize("???", colorBold, noColor)
} }
} else {
if i == nil { if i == nil {
l = colorize("???", colorBold, noColor) return unknownLevel
} else {
l = strings.ToUpper(fmt.Sprintf("%s", i))[0:3]
} }
} return stripLevel(fmt.Sprintf("%s", i))
return l
} }
} }
@ -379,12 +483,19 @@ func consoleDefaultFormatCaller(noColor bool) Formatter {
} }
} }
func consoleDefaultFormatMessage(i interface{}) string { func consoleDefaultFormatMessage(noColor bool, level interface{}) Formatter {
if i == nil { return func(i interface{}) string {
if i == nil || i == "" {
return "" return ""
} }
switch level {
case LevelInfoValue, LevelWarnValue, LevelErrorValue, LevelFatalValue, LevelPanicValue:
return colorize(fmt.Sprintf("%s", i), colorBold, noColor)
default:
return fmt.Sprintf("%s", i) return fmt.Sprintf("%s", i)
} }
}
}
func consoleDefaultFormatFieldName(noColor bool) Formatter { func consoleDefaultFormatFieldName(noColor bool) Formatter {
return func(i interface{}) string { return func(i interface{}) string {
@ -398,12 +509,12 @@ func consoleDefaultFormatFieldValue(i interface{}) string {
func consoleDefaultFormatErrFieldName(noColor bool) Formatter { func consoleDefaultFormatErrFieldName(noColor bool) Formatter {
return func(i interface{}) string { return func(i interface{}) string {
return colorize(fmt.Sprintf("%s=", i), colorRed, noColor) return colorize(fmt.Sprintf("%s=", i), colorCyan, noColor)
} }
} }
func consoleDefaultFormatErrFieldValue(noColor bool) Formatter { func consoleDefaultFormatErrFieldValue(noColor bool) Formatter {
return func(i interface{}) string { return func(i interface{}) string {
return colorize(fmt.Sprintf("%s", i), colorRed, noColor) return colorize(colorize(fmt.Sprintf("%s", i), colorBold, noColor), colorRed, noColor)
} }
} }

View file

@ -1,8 +1,9 @@
package zerolog package zerolog
import ( import (
"context"
"fmt" "fmt"
"io/ioutil" "io"
"math" "math"
"net" "net"
"time" "time"
@ -22,7 +23,7 @@ func (c Context) Logger() Logger {
// Only map[string]interface{} and []interface{} are accepted. []interface{} must // Only map[string]interface{} and []interface{} are accepted. []interface{} must
// alternate string keys and arbitrary values, and extraneous ones are ignored. // alternate string keys and arbitrary values, and extraneous ones are ignored.
func (c Context) Fields(fields interface{}) Context { func (c Context) Fields(fields interface{}) Context {
c.l.context = appendFields(c.l.context, fields) c.l.context = appendFields(c.l.context, fields, c.l.stack)
return c return c
} }
@ -56,7 +57,7 @@ func (c Context) Array(key string, arr LogArrayMarshaler) Context {
// Object marshals an object that implement the LogObjectMarshaler interface. // Object marshals an object that implement the LogObjectMarshaler interface.
func (c Context) Object(key string, obj LogObjectMarshaler) Context { func (c Context) Object(key string, obj LogObjectMarshaler) Context {
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0) e := newEvent(LevelWriterAdapter{io.Discard}, 0)
e.Object(key, obj) e.Object(key, obj)
c.l.context = enc.AppendObjectData(c.l.context, e.buf) c.l.context = enc.AppendObjectData(c.l.context, e.buf)
putEvent(e) putEvent(e)
@ -65,7 +66,7 @@ func (c Context) Object(key string, obj LogObjectMarshaler) Context {
// EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface. // EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface.
func (c Context) EmbedObject(obj LogObjectMarshaler) Context { func (c Context) EmbedObject(obj LogObjectMarshaler) Context {
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0) e := newEvent(LevelWriterAdapter{io.Discard}, 0)
e.EmbedObject(obj) e.EmbedObject(obj)
c.l.context = enc.AppendObjectData(c.l.context, e.buf) c.l.context = enc.AppendObjectData(c.l.context, e.buf)
putEvent(e) putEvent(e)
@ -162,9 +163,34 @@ func (c Context) Errs(key string, errs []error) Context {
// Err adds the field "error" with serialized err to the logger context. // Err adds the field "error" with serialized err to the logger context.
func (c Context) Err(err error) Context { func (c Context) Err(err error) Context {
if c.l.stack && ErrorStackMarshaler != nil {
switch m := ErrorStackMarshaler(err).(type) {
case nil:
case LogObjectMarshaler:
c = c.Object(ErrorStackFieldName, m)
case error:
if m != nil && !isNilValue(m) {
c = c.Str(ErrorStackFieldName, m.Error())
}
case string:
c = c.Str(ErrorStackFieldName, m)
default:
c = c.Interface(ErrorStackFieldName, m)
}
}
return c.AnErr(ErrorFieldName, err) return c.AnErr(ErrorFieldName, err)
} }
// Ctx adds the context.Context to the logger context. The context.Context is
// not rendered in the error message, but is made available for hooks to use.
// A typical use case is to extract tracing information from the
// context.Context.
func (c Context) Ctx(ctx context.Context) Context {
c.l.ctx = ctx
return c
}
// Bool adds the field key with val as a bool to the logger context. // Bool adds the field key with val as a bool to the logger context.
func (c Context) Bool(key string, b bool) Context { func (c Context) Bool(key string, b bool) Context {
c.l.context = enc.AppendBool(enc.AppendKey(c.l.context, key), b) c.l.context = enc.AppendBool(enc.AppendKey(c.l.context, key), b)
@ -299,25 +325,25 @@ func (c Context) Uints64(key string, i []uint64) Context {
// Float32 adds the field key with f as a float32 to the logger context. // Float32 adds the field key with f as a float32 to the logger context.
func (c Context) Float32(key string, f float32) Context { func (c Context) Float32(key string, f float32) Context {
c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f) c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
return c return c
} }
// Floats32 adds the field key with f as a []float32 to the logger context. // Floats32 adds the field key with f as a []float32 to the logger context.
func (c Context) Floats32(key string, f []float32) Context { func (c Context) Floats32(key string, f []float32) Context {
c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f) c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
return c return c
} }
// Float64 adds the field key with f as a float64 to the logger context. // Float64 adds the field key with f as a float64 to the logger context.
func (c Context) Float64(key string, f float64) Context { func (c Context) Float64(key string, f float64) Context {
c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f) c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
return c return c
} }
// Floats64 adds the field key with f as a []float64 to the logger context. // Floats64 adds the field key with f as a []float64 to the logger context.
func (c Context) Floats64(key string, f []float64) Context { func (c Context) Floats64(key string, f []float64) Context {
c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f) c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
return c return c
} }
@ -329,8 +355,9 @@ func (ts timestampHook) Run(e *Event, level Level, msg string) {
var th = timestampHook{} var th = timestampHook{}
// Timestamp adds the current local time as UNIX timestamp to the logger context with the "time" key. // Timestamp adds the current local time to the logger context with the "time" key, formatted using zerolog.TimeFieldFormat.
// To customize the key name, change zerolog.TimestampFieldName. // To customize the key name, change zerolog.TimestampFieldName.
// To customize the time format, change zerolog.TimeFieldFormat.
// //
// NOTE: It won't dedupe the "time" key if the *Context has one already. // NOTE: It won't dedupe the "time" key if the *Context has one already.
func (c Context) Timestamp() Context { func (c Context) Timestamp() Context {
@ -338,13 +365,13 @@ func (c Context) Timestamp() Context {
return c return c
} }
// Time adds the field key with t formated as string using zerolog.TimeFieldFormat. // Time adds the field key with t formatted as string using zerolog.TimeFieldFormat.
func (c Context) Time(key string, t time.Time) Context { func (c Context) Time(key string, t time.Time) Context {
c.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat) c.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
return c return c
} }
// Times adds the field key with t formated as string using zerolog.TimeFieldFormat. // Times adds the field key with t formatted as string using zerolog.TimeFieldFormat.
func (c Context) Times(key string, t []time.Time) Context { func (c Context) Times(key string, t []time.Time) Context {
c.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat) c.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
return c return c
@ -352,22 +379,42 @@ func (c Context) Times(key string, t []time.Time) Context {
// Dur adds the fields key with d divided by unit and stored as a float. // Dur adds the fields key with d divided by unit and stored as a float.
func (c Context) Dur(key string, d time.Duration) Context { func (c Context) Dur(key string, d time.Duration) Context {
c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger) c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
return c return c
} }
// Durs adds the fields key with d divided by unit and stored as a float. // Durs adds the fields key with d divided by unit and stored as a float.
func (c Context) Durs(key string, d []time.Duration) Context { func (c Context) Durs(key string, d []time.Duration) Context {
c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger) c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
return c return c
} }
// Interface adds the field key with obj marshaled using reflection. // Interface adds the field key with obj marshaled using reflection.
func (c Context) Interface(key string, i interface{}) Context { func (c Context) Interface(key string, i interface{}) Context {
if obj, ok := i.(LogObjectMarshaler); ok {
return c.Object(key, obj)
}
c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), i) c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), i)
return c return c
} }
// Type adds the field key with val's type using reflection.
func (c Context) Type(key string, val interface{}) Context {
c.l.context = enc.AppendType(enc.AppendKey(c.l.context, key), val)
return c
}
// Any is a wrapper around Context.Interface.
func (c Context) Any(key string, i interface{}) Context {
return c.Interface(key, i)
}
// Reset removes all the context fields.
func (c Context) Reset() Context {
c.l.context = enc.AppendBeginMarker(make([]byte, 0, 500))
return c
}
type callerHook struct { type callerHook struct {
callerSkipFrameCount int callerSkipFrameCount int
} }

23
vendor/github.com/rs/zerolog/ctx.go generated vendored
View file

@ -14,10 +14,15 @@ func init() {
type ctxKey struct{} type ctxKey struct{}
// WithContext returns a copy of ctx with l associated. If an instance of Logger // WithContext returns a copy of ctx with the receiver attached. The Logger
// is already in the context, the context is not updated. // attached to the provided Context (if any) will not be effected. If the
// receiver's log level is Disabled it will only be attached to the returned
// Context if the provided Context has a previously attached Logger. If the
// provided Context has no attached Logger, a Disabled Logger will not be
// attached.
// //
// For instance, to add a field to an existing logger in the context, use this // Note: to modify the existing Logger attached to a Context (instead of
// replacing it in a new Context), use UpdateContext with the following
// notation: // notation:
// //
// ctx := r.Context() // ctx := r.Context()
@ -25,17 +30,13 @@ type ctxKey struct{}
// l.UpdateContext(func(c Context) Context { // l.UpdateContext(func(c Context) Context {
// return c.Str("bar", "baz") // return c.Str("bar", "baz")
// }) // })
func (l *Logger) WithContext(ctx context.Context) context.Context { //
if lp, ok := ctx.Value(ctxKey{}).(*Logger); ok { func (l Logger) WithContext(ctx context.Context) context.Context {
if lp == l { if _, ok := ctx.Value(ctxKey{}).(*Logger); !ok && l.level == Disabled {
// Do not store same logger.
return ctx
}
} else if l.level == Disabled {
// Do not store disabled logger. // Do not store disabled logger.
return ctx return ctx
} }
return context.WithValue(ctx, ctxKey{}, l) return context.WithValue(ctx, ctxKey{}, &l)
} }
// Ctx returns the Logger associated with the ctx. If no logger // Ctx returns the Logger associated with the ctx. If no logger

View file

@ -13,13 +13,13 @@ type encoder interface {
AppendBool(dst []byte, val bool) []byte AppendBool(dst []byte, val bool) []byte
AppendBools(dst []byte, vals []bool) []byte AppendBools(dst []byte, vals []bool) []byte
AppendBytes(dst, s []byte) []byte AppendBytes(dst, s []byte) []byte
AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool, precision int) []byte
AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool, precision int) []byte
AppendEndMarker(dst []byte) []byte AppendEndMarker(dst []byte) []byte
AppendFloat32(dst []byte, val float32) []byte AppendFloat32(dst []byte, val float32, precision int) []byte
AppendFloat64(dst []byte, val float64) []byte AppendFloat64(dst []byte, val float64, precision int) []byte
AppendFloats32(dst []byte, vals []float32) []byte AppendFloats32(dst []byte, vals []float32, precision int) []byte
AppendFloats64(dst []byte, vals []float64) []byte AppendFloats64(dst []byte, vals []float64, precision int) []byte
AppendHex(dst, s []byte) []byte AppendHex(dst, s []byte) []byte
AppendIPAddr(dst []byte, ip net.IP) []byte AppendIPAddr(dst []byte, ip net.IP) []byte
AppendIPPrefix(dst []byte, pfx net.IPNet) []byte AppendIPPrefix(dst []byte, pfx net.IPNet) []byte

View file

@ -24,6 +24,9 @@ func init() {
func appendJSON(dst []byte, j []byte) []byte { func appendJSON(dst []byte, j []byte) []byte {
return cbor.AppendEmbeddedJSON(dst, j) return cbor.AppendEmbeddedJSON(dst, j)
} }
func appendCBOR(dst []byte, c []byte) []byte {
return cbor.AppendEmbeddedCBOR(dst, c)
}
// decodeIfBinaryToString - converts a binary formatted log msg to a // decodeIfBinaryToString - converts a binary formatted log msg to a
// JSON formatted String Log message. // JSON formatted String Log message.

View file

@ -6,6 +6,7 @@ package zerolog
// JSON encoded byte stream. // JSON encoded byte stream.
import ( import (
"encoding/base64"
"github.com/rs/zerolog/internal/json" "github.com/rs/zerolog/internal/json"
) )
@ -25,6 +26,17 @@ func init() {
func appendJSON(dst []byte, j []byte) []byte { func appendJSON(dst []byte, j []byte) []byte {
return append(dst, j...) return append(dst, j...)
} }
func appendCBOR(dst []byte, cbor []byte) []byte {
dst = append(dst, []byte("\"data:application/cbor;base64,")...)
l := len(dst)
enc := base64.StdEncoding
n := enc.EncodedLen(len(cbor))
for i := 0; i < n; i++ {
dst = append(dst, '.')
}
enc.Encode(dst[l:], cbor)
return append(dst, '"')
}
func decodeIfBinaryToString(in []byte) string { func decodeIfBinaryToString(in []byte) string {
return string(in) return string(in)

View file

@ -1,6 +1,7 @@
package zerolog package zerolog
import ( import (
"context"
"fmt" "fmt"
"net" "net"
"os" "os"
@ -27,6 +28,7 @@ type Event struct {
stack bool // enable error stack trace stack bool // enable error stack trace
ch []Hook // hooks from context ch []Hook // hooks from context
skipFrame int // The number of additional frames to skip when printing the caller. skipFrame int // The number of additional frames to skip when printing the caller.
ctx context.Context // Optional Go context for event
} }
func putEvent(e *Event) { func putEvent(e *Event) {
@ -129,6 +131,13 @@ func (e *Event) Msgf(format string, v ...interface{}) {
e.msg(fmt.Sprintf(format, v...)) e.msg(fmt.Sprintf(format, v...))
} }
func (e *Event) MsgFunc(createMsg func() string) {
if e == nil {
return
}
e.msg(createMsg())
}
func (e *Event) msg(msg string) { func (e *Event) msg(msg string) {
for _, hook := range e.ch { for _, hook := range e.ch {
hook.Run(e, e.level, msg) hook.Run(e, e.level, msg)
@ -155,7 +164,7 @@ func (e *Event) Fields(fields interface{}) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = appendFields(e.buf, fields) e.buf = appendFields(e.buf, fields, e.stack)
return e return e
} }
@ -257,18 +266,24 @@ func (e *Event) Strs(key string, vals []string) *Event {
return e return e
} }
// Stringer adds the field key with val.String() (or null if val is nil) to the *Event context. // Stringer adds the field key with val.String() (or null if val is nil)
// to the *Event context.
func (e *Event) Stringer(key string, val fmt.Stringer) *Event { func (e *Event) Stringer(key string, val fmt.Stringer) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = enc.AppendStringer(enc.AppendKey(e.buf, key), val)
if val != nil {
e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val.String())
return e return e
} }
e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), nil) // Stringers adds the field key with vals where each individual val
// is used as val.String() (or null if val is empty) to the *Event
// context.
func (e *Event) Stringers(key string, vals []fmt.Stringer) *Event {
if e == nil {
return e
}
e.buf = enc.AppendStringers(enc.AppendKey(e.buf, key), vals)
return e return e
} }
@ -305,6 +320,18 @@ func (e *Event) RawJSON(key string, b []byte) *Event {
return e return e
} }
// RawCBOR adds already encoded CBOR to the log line under key.
//
// No sanity check is performed on b
// Note: The full featureset of CBOR is supported as data will not be mapped to json but stored as data-url
func (e *Event) RawCBOR(key string, b []byte) *Event {
if e == nil {
return e
}
e.buf = appendCBOR(enc.AppendKey(e.buf, key), b)
return e
}
// AnErr adds the field key with serialized err to the *Event context. // AnErr adds the field key with serialized err to the *Event context.
// If err is nil, no field is added. // If err is nil, no field is added.
func (e *Event) AnErr(key string, err error) *Event { func (e *Event) AnErr(key string, err error) *Event {
@ -392,6 +419,28 @@ func (e *Event) Stack() *Event {
return e return e
} }
// Ctx adds the Go Context to the *Event context. The context is not rendered
// in the output message, but is available to hooks and to Func() calls via the
// GetCtx() accessor. A typical use case is to extract tracing information from
// the Go Ctx.
func (e *Event) Ctx(ctx context.Context) *Event {
if e != nil {
e.ctx = ctx
}
return e
}
// GetCtx retrieves the Go context.Context which is optionally stored in the
// Event. This allows Hooks and functions passed to Func() to retrieve values
// which are stored in the context.Context. This can be useful in tracing,
// where span information is commonly propagated in the context.Context.
func (e *Event) GetCtx() context.Context {
if e == nil || e.ctx == nil {
return context.Background()
}
return e.ctx
}
// Bool adds the field key with val as a bool to the *Event context. // Bool adds the field key with val as a bool to the *Event context.
func (e *Event) Bool(key string, b bool) *Event { func (e *Event) Bool(key string, b bool) *Event {
if e == nil { if e == nil {
@ -595,7 +644,7 @@ func (e *Event) Float32(key string, f float32) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f) e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
return e return e
} }
@ -604,7 +653,7 @@ func (e *Event) Floats32(key string, f []float32) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f) e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
return e return e
} }
@ -613,7 +662,7 @@ func (e *Event) Float64(key string, f float64) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f) e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
return e return e
} }
@ -622,7 +671,7 @@ func (e *Event) Floats64(key string, f []float64) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f) e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
return e return e
} }
@ -639,7 +688,7 @@ func (e *Event) Timestamp() *Event {
return e return e
} }
// Time adds the field key with t formated as string using zerolog.TimeFieldFormat. // Time adds the field key with t formatted as string using zerolog.TimeFieldFormat.
func (e *Event) Time(key string, t time.Time) *Event { func (e *Event) Time(key string, t time.Time) *Event {
if e == nil { if e == nil {
return e return e
@ -648,7 +697,7 @@ func (e *Event) Time(key string, t time.Time) *Event {
return e return e
} }
// Times adds the field key with t formated as string using zerolog.TimeFieldFormat. // Times adds the field key with t formatted as string using zerolog.TimeFieldFormat.
func (e *Event) Times(key string, t []time.Time) *Event { func (e *Event) Times(key string, t []time.Time) *Event {
if e == nil { if e == nil {
return e return e
@ -664,7 +713,7 @@ func (e *Event) Dur(key string, d time.Duration) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
return e return e
} }
@ -675,7 +724,7 @@ func (e *Event) Durs(key string, d []time.Duration) *Event {
if e == nil { if e == nil {
return e return e
} }
e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
return e return e
} }
@ -690,10 +739,15 @@ func (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event {
if t.After(start) { if t.After(start) {
d = t.Sub(start) d = t.Sub(start)
} }
e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
return e return e
} }
// Any is a wrapper around Event.Interface.
func (e *Event) Any(key string, i interface{}) *Event {
return e.Interface(key, i)
}
// Interface adds the field key with i marshaled using reflection. // Interface adds the field key with i marshaled using reflection.
func (e *Event) Interface(key string, i interface{}) *Event { func (e *Event) Interface(key string, i interface{}) *Event {
if e == nil { if e == nil {
@ -706,6 +760,15 @@ func (e *Event) Interface(key string, i interface{}) *Event {
return e return e
} }
// Type adds the field key with val's type using reflection.
func (e *Event) Type(key string, val interface{}) *Event {
if e == nil {
return e
}
e.buf = enc.AppendType(enc.AppendKey(e.buf, key), val)
return e
}
// CallerSkipFrame instructs any future Caller calls to skip the specified number of frames. // CallerSkipFrame instructs any future Caller calls to skip the specified number of frames.
// This includes those added via hooks from the context. // This includes those added via hooks from the context.
func (e *Event) CallerSkipFrame(skip int) *Event { func (e *Event) CallerSkipFrame(skip int) *Event {
@ -731,11 +794,11 @@ func (e *Event) caller(skip int) *Event {
if e == nil { if e == nil {
return e return e
} }
_, file, line, ok := runtime.Caller(skip + e.skipFrame) pc, file, line, ok := runtime.Caller(skip + e.skipFrame)
if !ok { if !ok {
return e return e
} }
e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), CallerMarshalFunc(file, line)) e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), CallerMarshalFunc(pc, file, line))
return e return e
} }

7
vendor/github.com/rs/zerolog/example.jsonl generated vendored Normal file
View file

@ -0,0 +1,7 @@
{"time":"5:41PM","level":"info","message":"Starting listener","listen":":8080","pid":37556}
{"time":"5:41PM","level":"debug","message":"Access","database":"myapp","host":"localhost:4962","pid":37556}
{"time":"5:41PM","level":"info","message":"Access","method":"GET","path":"/users","pid":37556,"resp_time":23}
{"time":"5:41PM","level":"info","message":"Access","method":"POST","path":"/posts","pid":37556,"resp_time":532}
{"time":"5:41PM","level":"warn","message":"Slow request","method":"POST","path":"/posts","pid":37556,"resp_time":532}
{"time":"5:41PM","level":"info","message":"Access","method":"GET","path":"/users","pid":37556,"resp_time":10}
{"time":"5:41PM","level":"error","message":"Database connection lost","database":"myapp","pid":37556,"error":"connection reset by peer"}

View file

@ -12,13 +12,13 @@ func isNilValue(i interface{}) bool {
return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0 return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0
} }
func appendFields(dst []byte, fields interface{}) []byte { func appendFields(dst []byte, fields interface{}, stack bool) []byte {
switch fields := fields.(type) { switch fields := fields.(type) {
case []interface{}: case []interface{}:
if n := len(fields); n&0x1 == 1 { // odd number if n := len(fields); n&0x1 == 1 { // odd number
fields = fields[:n-1] fields = fields[:n-1]
} }
dst = appendFieldList(dst, fields) dst = appendFieldList(dst, fields, stack)
case map[string]interface{}: case map[string]interface{}:
keys := make([]string, 0, len(fields)) keys := make([]string, 0, len(fields))
for key := range fields { for key := range fields {
@ -28,13 +28,13 @@ func appendFields(dst []byte, fields interface{}) []byte {
kv := make([]interface{}, 2) kv := make([]interface{}, 2)
for _, key := range keys { for _, key := range keys {
kv[0], kv[1] = key, fields[key] kv[0], kv[1] = key, fields[key]
dst = appendFieldList(dst, kv) dst = appendFieldList(dst, kv, stack)
} }
} }
return dst return dst
} }
func appendFieldList(dst []byte, kvList []interface{}) []byte { func appendFieldList(dst []byte, kvList []interface{}, stack bool) []byte {
for i, n := 0, len(kvList); i < n; i += 2 { for i, n := 0, len(kvList); i < n; i += 2 {
key, val := kvList[i], kvList[i+1] key, val := kvList[i], kvList[i+1]
if key, ok := key.(string); ok { if key, ok := key.(string); ok {
@ -74,6 +74,21 @@ func appendFieldList(dst []byte, kvList []interface{}) []byte {
default: default:
dst = enc.AppendInterface(dst, m) dst = enc.AppendInterface(dst, m)
} }
if stack && ErrorStackMarshaler != nil {
dst = enc.AppendKey(dst, ErrorStackFieldName)
switch m := ErrorStackMarshaler(val).(type) {
case nil:
case error:
if m != nil && !isNilValue(m) {
dst = enc.AppendString(dst, m.Error())
}
case string:
dst = enc.AppendString(dst, m)
default:
dst = enc.AppendInterface(dst, m)
}
}
case []error: case []error:
dst = enc.AppendArrayStart(dst) dst = enc.AppendArrayStart(dst)
for i, err := range val { for i, err := range val {
@ -124,13 +139,13 @@ func appendFieldList(dst []byte, kvList []interface{}) []byte {
case uint64: case uint64:
dst = enc.AppendUint64(dst, val) dst = enc.AppendUint64(dst, val)
case float32: case float32:
dst = enc.AppendFloat32(dst, val) dst = enc.AppendFloat32(dst, val, FloatingPointPrecision)
case float64: case float64:
dst = enc.AppendFloat64(dst, val) dst = enc.AppendFloat64(dst, val, FloatingPointPrecision)
case time.Time: case time.Time:
dst = enc.AppendTime(dst, val, TimeFieldFormat) dst = enc.AppendTime(dst, val, TimeFieldFormat)
case time.Duration: case time.Duration:
dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger) dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
case *string: case *string:
if val != nil { if val != nil {
dst = enc.AppendString(dst, *val) dst = enc.AppendString(dst, *val)
@ -205,13 +220,13 @@ func appendFieldList(dst []byte, kvList []interface{}) []byte {
} }
case *float32: case *float32:
if val != nil { if val != nil {
dst = enc.AppendFloat32(dst, *val) dst = enc.AppendFloat32(dst, *val, FloatingPointPrecision)
} else { } else {
dst = enc.AppendNil(dst) dst = enc.AppendNil(dst)
} }
case *float64: case *float64:
if val != nil { if val != nil {
dst = enc.AppendFloat64(dst, *val) dst = enc.AppendFloat64(dst, *val, FloatingPointPrecision)
} else { } else {
dst = enc.AppendNil(dst) dst = enc.AppendNil(dst)
} }
@ -223,7 +238,7 @@ func appendFieldList(dst []byte, kvList []interface{}) []byte {
} }
case *time.Duration: case *time.Duration:
if val != nil { if val != nil {
dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger) dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
} else { } else {
dst = enc.AppendNil(dst) dst = enc.AppendNil(dst)
} }
@ -252,13 +267,13 @@ func appendFieldList(dst []byte, kvList []interface{}) []byte {
case []uint64: case []uint64:
dst = enc.AppendUints64(dst, val) dst = enc.AppendUints64(dst, val)
case []float32: case []float32:
dst = enc.AppendFloats32(dst, val) dst = enc.AppendFloats32(dst, val, FloatingPointPrecision)
case []float64: case []float64:
dst = enc.AppendFloats64(dst, val) dst = enc.AppendFloats64(dst, val, FloatingPointPrecision)
case []time.Time: case []time.Time:
dst = enc.AppendTimes(dst, val, TimeFieldFormat) dst = enc.AppendTimes(dst, val, TimeFieldFormat)
case []time.Duration: case []time.Duration:
dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger) dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
case nil: case nil:
dst = enc.AppendNil(dst) dst = enc.AppendNil(dst)
case net.IP: case net.IP:

View file

@ -1,6 +1,7 @@
package zerolog package zerolog
import ( import (
"bytes"
"encoding/json" "encoding/json"
"strconv" "strconv"
"sync/atomic" "sync/atomic"
@ -19,6 +20,10 @@ const (
// TimeFormatUnixMicro defines a time format that makes time fields to be // TimeFormatUnixMicro defines a time format that makes time fields to be
// serialized as Unix timestamp integers in microseconds. // serialized as Unix timestamp integers in microseconds.
TimeFormatUnixMicro = "UNIXMICRO" TimeFormatUnixMicro = "UNIXMICRO"
// TimeFormatUnixNano defines a time format that makes time fields to be
// serialized as Unix timestamp integers in nanoseconds.
TimeFormatUnixNano = "UNIXNANO"
) )
var ( var (
@ -61,7 +66,7 @@ var (
CallerSkipFrameCount = 2 CallerSkipFrameCount = 2
// CallerMarshalFunc allows customization of global caller marshaling // CallerMarshalFunc allows customization of global caller marshaling
CallerMarshalFunc = func(file string, line int) string { CallerMarshalFunc = func(pc uintptr, file string, line int) string {
return file + ":" + strconv.Itoa(line) return file + ":" + strconv.Itoa(line)
} }
@ -77,11 +82,25 @@ var (
} }
// InterfaceMarshalFunc allows customization of interface marshaling. // InterfaceMarshalFunc allows customization of interface marshaling.
// Default: "encoding/json.Marshal" // Default: "encoding/json.Marshal" with disabled HTML escaping
InterfaceMarshalFunc = json.Marshal InterfaceMarshalFunc = func(v interface{}) ([]byte, error) {
var buf bytes.Buffer
encoder := json.NewEncoder(&buf)
encoder.SetEscapeHTML(false)
err := encoder.Encode(v)
if err != nil {
return nil, err
}
b := buf.Bytes()
if len(b) > 0 {
// Remove trailing \n which is added by Encode.
return b[:len(b)-1], nil
}
return b, nil
}
// TimeFieldFormat defines the time format of the Time field type. If set to // TimeFieldFormat defines the time format of the Time field type. If set to
// TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX // TimeFormatUnix, TimeFormatUnixMs, TimeFormatUnixMicro or TimeFormatUnixNano, the time is formatted as a UNIX
// timestamp as integer. // timestamp as integer.
TimeFieldFormat = time.RFC3339 TimeFieldFormat = time.RFC3339
@ -104,6 +123,39 @@ var (
// DefaultContextLogger is returned from Ctx() if there is no logger associated // DefaultContextLogger is returned from Ctx() if there is no logger associated
// with the context. // with the context.
DefaultContextLogger *Logger DefaultContextLogger *Logger
// LevelColors are used by ConsoleWriter's consoleDefaultFormatLevel to color
// log levels.
LevelColors = map[Level]int{
TraceLevel: colorBlue,
DebugLevel: 0,
InfoLevel: colorGreen,
WarnLevel: colorYellow,
ErrorLevel: colorRed,
FatalLevel: colorRed,
PanicLevel: colorRed,
}
// FormattedLevels are used by ConsoleWriter's consoleDefaultFormatLevel
// for a short level name.
FormattedLevels = map[Level]string{
TraceLevel: "TRC",
DebugLevel: "DBG",
InfoLevel: "INF",
WarnLevel: "WRN",
ErrorLevel: "ERR",
FatalLevel: "FTL",
PanicLevel: "PNC",
}
// TriggerLevelWriterBufferReuseLimit is a limit in bytes that a buffer is dropped
// from the TriggerLevelWriter buffer pool if the buffer grows above the limit.
TriggerLevelWriterBufferReuseLimit = 64 * 1024
// FloatingPointPrecision, if set to a value other than -1, controls the number
// of digits when formatting float numbers in JSON. See strconv.FormatFloat for
// more details.
FloatingPointPrecision = -1
) )
var ( var (

View file

@ -27,6 +27,7 @@ const (
// Tag Sub-types. // Tag Sub-types.
additionalTypeTimestamp byte = 01 additionalTypeTimestamp byte = 01
additionalTypeEmbeddedCBOR byte = 63
// Extended Tags - from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml // Extended Tags - from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
additionalTypeTagNetworkAddr uint16 = 260 additionalTypeTagNetworkAddr uint16 = 260
@ -91,7 +92,8 @@ func appendCborTypePrefix(dst []byte, major byte, number uint64) []byte {
minor = additionalTypeIntUint64 minor = additionalTypeIntUint64
} }
dst = append(dst, byte(major|minor))
dst = append(dst, major|minor)
byteCount-- byteCount--
for ; byteCount >= 0; byteCount-- { for ; byteCount >= 0; byteCount-- {
dst = append(dst, byte(number>>(uint(byteCount)*8))) dst = append(dst, byte(number>>(uint(byteCount)*8)))

View file

@ -5,6 +5,7 @@ package cbor
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"encoding/base64"
"fmt" "fmt"
"io" "io"
"math" "math"
@ -43,7 +44,7 @@ func readByte(src *bufio.Reader) byte {
return b return b
} }
func decodeIntAdditonalType(src *bufio.Reader, minor byte) int64 { func decodeIntAdditionalType(src *bufio.Reader, minor byte) int64 {
val := int64(0) val := int64(0)
if minor <= 23 { if minor <= 23 {
val = int64(minor) val = int64(minor)
@ -77,7 +78,7 @@ func decodeInteger(src *bufio.Reader) int64 {
if major != majorTypeUnsignedInt && major != majorTypeNegativeInt { if major != majorTypeUnsignedInt && major != majorTypeNegativeInt {
panic(fmt.Errorf("Major type is: %d in decodeInteger!! (expected 0 or 1)", major)) panic(fmt.Errorf("Major type is: %d in decodeInteger!! (expected 0 or 1)", major))
} }
val := decodeIntAdditonalType(src, minor) val := decodeIntAdditionalType(src, minor)
if major == 0 { if major == 0 {
return val return val
} }
@ -94,7 +95,7 @@ func decodeFloat(src *bufio.Reader) (float64, int) {
switch minor { switch minor {
case additionalTypeFloat16: case additionalTypeFloat16:
panic(fmt.Errorf("float16 is not suppported in decodeFloat")) panic(fmt.Errorf("float16 is not supported in decodeFloat"))
case additionalTypeFloat32: case additionalTypeFloat32:
pb := readNBytes(src, 4) pb := readNBytes(src, 4)
@ -204,7 +205,7 @@ func decodeString(src *bufio.Reader, noQuotes bool) []byte {
if !noQuotes { if !noQuotes {
result = append(result, '"') result = append(result, '"')
} }
length := decodeIntAdditonalType(src, minor) length := decodeIntAdditionalType(src, minor)
len := int(length) len := int(length)
pbs := readNBytes(src, len) pbs := readNBytes(src, len)
result = append(result, pbs...) result = append(result, pbs...)
@ -213,6 +214,31 @@ func decodeString(src *bufio.Reader, noQuotes bool) []byte {
} }
return append(result, '"') return append(result, '"')
} }
func decodeStringToDataUrl(src *bufio.Reader, mimeType string) []byte {
pb := readByte(src)
major := pb & maskOutAdditionalType
minor := pb & maskOutMajorType
if major != majorTypeByteString {
panic(fmt.Errorf("Major type is: %d in decodeString", major))
}
length := decodeIntAdditionalType(src, minor)
l := int(length)
enc := base64.StdEncoding
lEnc := enc.EncodedLen(l)
result := make([]byte, len("\"data:;base64,\"")+len(mimeType)+lEnc)
dest := result
u := copy(dest, "\"data:")
dest = dest[u:]
u = copy(dest, mimeType)
dest = dest[u:]
u = copy(dest, ";base64,")
dest = dest[u:]
pbs := readNBytes(src, l)
enc.Encode(dest, pbs)
dest = dest[lEnc:]
dest[0] = '"'
return result
}
func decodeUTF8String(src *bufio.Reader) []byte { func decodeUTF8String(src *bufio.Reader) []byte {
pb := readByte(src) pb := readByte(src)
@ -222,7 +248,7 @@ func decodeUTF8String(src *bufio.Reader) []byte {
panic(fmt.Errorf("Major type is: %d in decodeUTF8String", major)) panic(fmt.Errorf("Major type is: %d in decodeUTF8String", major))
} }
result := []byte{'"'} result := []byte{'"'}
length := decodeIntAdditonalType(src, minor) length := decodeIntAdditionalType(src, minor)
len := int(length) len := int(length)
pbs := readNBytes(src, len) pbs := readNBytes(src, len)
@ -238,7 +264,7 @@ func decodeUTF8String(src *bufio.Reader) []byte {
return append(dst, '"') return append(dst, '"')
} }
} }
// The string has no need for encoding an therefore is directly // The string has no need for encoding and therefore is directly
// appended to the byte slice. // appended to the byte slice.
result = append(result, pbs...) result = append(result, pbs...)
return append(result, '"') return append(result, '"')
@ -257,7 +283,7 @@ func array2Json(src *bufio.Reader, dst io.Writer) {
if minor == additionalTypeInfiniteCount { if minor == additionalTypeInfiniteCount {
unSpecifiedCount = true unSpecifiedCount = true
} else { } else {
length := decodeIntAdditonalType(src, minor) length := decodeIntAdditionalType(src, minor)
len = int(length) len = int(length)
} }
for i := 0; unSpecifiedCount || i < len; i++ { for i := 0; unSpecifiedCount || i < len; i++ {
@ -266,7 +292,7 @@ func array2Json(src *bufio.Reader, dst io.Writer) {
if e != nil { if e != nil {
panic(e) panic(e)
} }
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) { if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak {
readByte(src) readByte(src)
break break
} }
@ -277,7 +303,7 @@ func array2Json(src *bufio.Reader, dst io.Writer) {
if e != nil { if e != nil {
panic(e) panic(e)
} }
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) { if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak {
readByte(src) readByte(src)
break break
} }
@ -301,7 +327,7 @@ func map2Json(src *bufio.Reader, dst io.Writer) {
if minor == additionalTypeInfiniteCount { if minor == additionalTypeInfiniteCount {
unSpecifiedCount = true unSpecifiedCount = true
} else { } else {
length := decodeIntAdditonalType(src, minor) length := decodeIntAdditionalType(src, minor)
len = int(length) len = int(length)
} }
dst.Write([]byte{'{'}) dst.Write([]byte{'{'})
@ -311,7 +337,7 @@ func map2Json(src *bufio.Reader, dst io.Writer) {
if e != nil { if e != nil {
panic(e) panic(e)
} }
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) { if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak {
readByte(src) readByte(src)
break break
} }
@ -326,7 +352,7 @@ func map2Json(src *bufio.Reader, dst io.Writer) {
if e != nil { if e != nil {
panic(e) panic(e)
} }
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) { if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak {
readByte(src) readByte(src)
break break
} }
@ -349,10 +375,24 @@ func decodeTagData(src *bufio.Reader) []byte {
switch minor { switch minor {
case additionalTypeTimestamp: case additionalTypeTimestamp:
return decodeTimeStamp(src) return decodeTimeStamp(src)
case additionalTypeIntUint8:
val := decodeIntAdditionalType(src, minor)
switch byte(val) {
case additionalTypeEmbeddedCBOR:
pb := readByte(src)
dataMajor := pb & maskOutAdditionalType
if dataMajor != majorTypeByteString {
panic(fmt.Errorf("Unsupported embedded Type: %d in decodeEmbeddedCBOR", dataMajor))
}
src.UnreadByte()
return decodeStringToDataUrl(src, "application/cbor")
default:
panic(fmt.Errorf("Unsupported Additional Tag Type: %d in decodeTagData", val))
}
// Tag value is larger than 256 (so uint16). // Tag value is larger than 256 (so uint16).
case additionalTypeIntUint16: case additionalTypeIntUint16:
val := decodeIntAdditonalType(src, minor) val := decodeIntAdditionalType(src, minor)
switch uint16(val) { switch uint16(val) {
case additionalTypeEmbeddedJSON: case additionalTypeEmbeddedJSON:
@ -383,7 +423,7 @@ func decodeTagData(src *bufio.Reader) []byte {
case additionalTypeTagNetworkPrefix: case additionalTypeTagNetworkPrefix:
pb := readByte(src) pb := readByte(src)
if pb != byte(majorTypeMap|0x1) { if pb != majorTypeMap|0x1 {
panic(fmt.Errorf("IP Prefix is NOT of MAP of 1 elements as expected")) panic(fmt.Errorf("IP Prefix is NOT of MAP of 1 elements as expected"))
} }
octets := decodeString(src, true) octets := decodeString(src, true)

View file

@ -1,12 +1,14 @@
package cbor package cbor
import "fmt"
// AppendStrings encodes and adds an array of strings to the dst byte array. // AppendStrings encodes and adds an array of strings to the dst byte array.
func (e Encoder) AppendStrings(dst []byte, vals []string) []byte { func (e Encoder) AppendStrings(dst []byte, vals []string) []byte {
major := majorTypeArray major := majorTypeArray
l := len(vals) l := len(vals)
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -23,13 +25,38 @@ func (Encoder) AppendString(dst []byte, s string) []byte {
l := len(s) l := len(s)
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, majorTypeUtf8String, uint64(l)) dst = appendCborTypePrefix(dst, majorTypeUtf8String, uint64(l))
} }
return append(dst, s...) return append(dst, s...)
} }
// AppendStringers encodes and adds an array of Stringer values
// to the dst byte array.
func (e Encoder) AppendStringers(dst []byte, vals []fmt.Stringer) []byte {
if len(vals) == 0 {
return e.AppendArrayEnd(e.AppendArrayStart(dst))
}
dst = e.AppendArrayStart(dst)
dst = e.AppendStringer(dst, vals[0])
if len(vals) > 1 {
for _, val := range vals[1:] {
dst = e.AppendStringer(dst, val)
}
}
return e.AppendArrayEnd(dst)
}
// AppendStringer encodes and adds the Stringer value to the dst
// byte array.
func (e Encoder) AppendStringer(dst []byte, val fmt.Stringer) []byte {
if val == nil {
return e.AppendNil(dst)
}
return e.AppendString(dst, val.String())
}
// AppendBytes encodes and adds an array of bytes to the dst byte array. // AppendBytes encodes and adds an array of bytes to the dst byte array.
func (Encoder) AppendBytes(dst, s []byte) []byte { func (Encoder) AppendBytes(dst, s []byte) []byte {
major := majorTypeByteString major := majorTypeByteString
@ -37,7 +64,7 @@ func (Encoder) AppendBytes(dst, s []byte) []byte {
l := len(s) l := len(s)
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -50,7 +77,7 @@ func AppendEmbeddedJSON(dst, s []byte) []byte {
minor := additionalTypeEmbeddedJSON minor := additionalTypeEmbeddedJSON
// Append the TAG to indicate this is Embedded JSON. // Append the TAG to indicate this is Embedded JSON.
dst = append(dst, byte(major|additionalTypeIntUint16)) dst = append(dst, major|additionalTypeIntUint16)
dst = append(dst, byte(minor>>8)) dst = append(dst, byte(minor>>8))
dst = append(dst, byte(minor&0xff)) dst = append(dst, byte(minor&0xff))
@ -60,7 +87,29 @@ func AppendEmbeddedJSON(dst, s []byte) []byte {
l := len(s) l := len(s)
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else {
dst = appendCborTypePrefix(dst, major, uint64(l))
}
return append(dst, s...)
}
// AppendEmbeddedCBOR adds a tag and embeds input CBOR as such.
func AppendEmbeddedCBOR(dst, s []byte) []byte {
major := majorTypeTags
minor := additionalTypeEmbeddedCBOR
// Append the TAG to indicate this is Embedded JSON.
dst = append(dst, major|additionalTypeIntUint8)
dst = append(dst, minor)
// Append the CBOR Object as Byte String.
major = majorTypeByteString
l := len(s)
if l <= additionalMax {
lb := byte(l)
dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }

View file

@ -7,7 +7,7 @@ import (
func appendIntegerTimestamp(dst []byte, t time.Time) []byte { func appendIntegerTimestamp(dst []byte, t time.Time) []byte {
major := majorTypeTags major := majorTypeTags
minor := additionalTypeTimestamp minor := additionalTypeTimestamp
dst = append(dst, byte(major|minor)) dst = append(dst, major|minor)
secs := t.Unix() secs := t.Unix()
var val uint64 var val uint64
if secs < 0 { if secs < 0 {
@ -17,19 +17,19 @@ func appendIntegerTimestamp(dst []byte, t time.Time) []byte {
major = majorTypeUnsignedInt major = majorTypeUnsignedInt
val = uint64(secs) val = uint64(secs)
} }
dst = appendCborTypePrefix(dst, major, uint64(val)) dst = appendCborTypePrefix(dst, major, val)
return dst return dst
} }
func (e Encoder) appendFloatTimestamp(dst []byte, t time.Time) []byte { func (e Encoder) appendFloatTimestamp(dst []byte, t time.Time) []byte {
major := majorTypeTags major := majorTypeTags
minor := additionalTypeTimestamp minor := additionalTypeTimestamp
dst = append(dst, byte(major|minor)) dst = append(dst, major|minor)
secs := t.Unix() secs := t.Unix()
nanos := t.Nanosecond() nanos := t.Nanosecond()
var val float64 var val float64
val = float64(secs)*1.0 + float64(nanos)*1E-9 val = float64(secs)*1.0 + float64(nanos)*1e-9
return e.AppendFloat64(dst, val) return e.AppendFloat64(dst, val, -1)
} }
// AppendTime encodes and adds a timestamp to the dst byte array. // AppendTime encodes and adds a timestamp to the dst byte array.
@ -50,7 +50,7 @@ func (e Encoder) AppendTimes(dst []byte, vals []time.Time, unused string) []byte
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -64,17 +64,17 @@ func (e Encoder) AppendTimes(dst []byte, vals []time.Time, unused string) []byte
// AppendDuration encodes and adds a duration to the dst byte array. // AppendDuration encodes and adds a duration to the dst byte array.
// useInt field indicates whether to store the duration as seconds (integer) or // useInt field indicates whether to store the duration as seconds (integer) or
// as seconds+nanoseconds (float). // as seconds+nanoseconds (float).
func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte { func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool, unused int) []byte {
if useInt { if useInt {
return e.AppendInt64(dst, int64(d/unit)) return e.AppendInt64(dst, int64(d/unit))
} }
return e.AppendFloat64(dst, float64(d)/float64(unit)) return e.AppendFloat64(dst, float64(d)/float64(unit), unused)
} }
// AppendDurations encodes and adds an array of durations to the dst byte array. // AppendDurations encodes and adds an array of durations to the dst byte array.
// useInt field indicates whether to store the duration as seconds (integer) or // useInt field indicates whether to store the duration as seconds (integer) or
// as seconds+nanoseconds (float). // as seconds+nanoseconds (float).
func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte { func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool, unused int) []byte {
major := majorTypeArray major := majorTypeArray
l := len(vals) l := len(vals)
if l == 0 { if l == 0 {
@ -82,12 +82,12 @@ func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Dur
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
for _, d := range vals { for _, d := range vals {
dst = e.AppendDuration(dst, d, unit, useInt) dst = e.AppendDuration(dst, d, unit, useInt, unused)
} }
return dst return dst
} }

View file

@ -4,21 +4,22 @@ import (
"fmt" "fmt"
"math" "math"
"net" "net"
"reflect"
) )
// AppendNil inserts a 'Nil' object into the dst byte array. // AppendNil inserts a 'Nil' object into the dst byte array.
func (Encoder) AppendNil(dst []byte) []byte { func (Encoder) AppendNil(dst []byte) []byte {
return append(dst, byte(majorTypeSimpleAndFloat|additionalTypeNull)) return append(dst, majorTypeSimpleAndFloat|additionalTypeNull)
} }
// AppendBeginMarker inserts a map start into the dst byte array. // AppendBeginMarker inserts a map start into the dst byte array.
func (Encoder) AppendBeginMarker(dst []byte) []byte { func (Encoder) AppendBeginMarker(dst []byte) []byte {
return append(dst, byte(majorTypeMap|additionalTypeInfiniteCount)) return append(dst, majorTypeMap|additionalTypeInfiniteCount)
} }
// AppendEndMarker inserts a map end into the dst byte array. // AppendEndMarker inserts a map end into the dst byte array.
func (Encoder) AppendEndMarker(dst []byte) []byte { func (Encoder) AppendEndMarker(dst []byte) []byte {
return append(dst, byte(majorTypeSimpleAndFloat|additionalTypeBreak)) return append(dst, majorTypeSimpleAndFloat|additionalTypeBreak)
} }
// AppendObjectData takes an object in form of a byte array and appends to dst. // AppendObjectData takes an object in form of a byte array and appends to dst.
@ -30,12 +31,12 @@ func (Encoder) AppendObjectData(dst []byte, o []byte) []byte {
// AppendArrayStart adds markers to indicate the start of an array. // AppendArrayStart adds markers to indicate the start of an array.
func (Encoder) AppendArrayStart(dst []byte) []byte { func (Encoder) AppendArrayStart(dst []byte) []byte {
return append(dst, byte(majorTypeArray|additionalTypeInfiniteCount)) return append(dst, majorTypeArray|additionalTypeInfiniteCount)
} }
// AppendArrayEnd adds markers to indicate the end of an array. // AppendArrayEnd adds markers to indicate the end of an array.
func (Encoder) AppendArrayEnd(dst []byte) []byte { func (Encoder) AppendArrayEnd(dst []byte) []byte {
return append(dst, byte(majorTypeSimpleAndFloat|additionalTypeBreak)) return append(dst, majorTypeSimpleAndFloat|additionalTypeBreak)
} }
// AppendArrayDelim adds markers to indicate end of a particular array element. // AppendArrayDelim adds markers to indicate end of a particular array element.
@ -56,7 +57,7 @@ func (Encoder) AppendBool(dst []byte, val bool) []byte {
if val { if val {
b = additionalTypeBoolTrue b = additionalTypeBoolTrue
} }
return append(dst, byte(majorTypeSimpleAndFloat|b)) return append(dst, majorTypeSimpleAndFloat|b)
} }
// AppendBools encodes and inserts an array of boolean values into the dst byte array. // AppendBools encodes and inserts an array of boolean values into the dst byte array.
@ -68,7 +69,7 @@ func (e Encoder) AppendBools(dst []byte, vals []bool) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -88,7 +89,7 @@ func (Encoder) AppendInt(dst []byte, val int) []byte {
} }
if contentVal <= additionalMax { if contentVal <= additionalMax {
lb := byte(contentVal) lb := byte(contentVal)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(contentVal)) dst = appendCborTypePrefix(dst, major, uint64(contentVal))
} }
@ -104,7 +105,7 @@ func (e Encoder) AppendInts(dst []byte, vals []int) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -128,7 +129,7 @@ func (e Encoder) AppendInts8(dst []byte, vals []int8) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -152,7 +153,7 @@ func (e Encoder) AppendInts16(dst []byte, vals []int16) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -176,7 +177,7 @@ func (e Encoder) AppendInts32(dst []byte, vals []int32) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -196,7 +197,7 @@ func (Encoder) AppendInt64(dst []byte, val int64) []byte {
} }
if contentVal <= additionalMax { if contentVal <= additionalMax {
lb := byte(contentVal) lb := byte(contentVal)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(contentVal)) dst = appendCborTypePrefix(dst, major, uint64(contentVal))
} }
@ -212,7 +213,7 @@ func (e Encoder) AppendInts64(dst []byte, vals []int64) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -236,7 +237,7 @@ func (e Encoder) AppendUints(dst []byte, vals []uint) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -260,7 +261,7 @@ func (e Encoder) AppendUints8(dst []byte, vals []uint8) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -284,7 +285,7 @@ func (e Encoder) AppendUints16(dst []byte, vals []uint16) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -308,7 +309,7 @@ func (e Encoder) AppendUints32(dst []byte, vals []uint32) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -324,9 +325,9 @@ func (Encoder) AppendUint64(dst []byte, val uint64) []byte {
contentVal := val contentVal := val
if contentVal <= additionalMax { if contentVal <= additionalMax {
lb := byte(contentVal) lb := byte(contentVal)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(contentVal)) dst = appendCborTypePrefix(dst, major, contentVal)
} }
return dst return dst
} }
@ -340,7 +341,7 @@ func (e Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
@ -351,7 +352,7 @@ func (e Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
} }
// AppendFloat32 encodes and inserts a single precision float value into the dst byte array. // AppendFloat32 encodes and inserts a single precision float value into the dst byte array.
func (Encoder) AppendFloat32(dst []byte, val float32) []byte { func (Encoder) AppendFloat32(dst []byte, val float32, unused int) []byte {
switch { switch {
case math.IsNaN(float64(val)): case math.IsNaN(float64(val)):
return append(dst, "\xfa\x7f\xc0\x00\x00"...) return append(dst, "\xfa\x7f\xc0\x00\x00"...)
@ -367,11 +368,11 @@ func (Encoder) AppendFloat32(dst []byte, val float32) []byte {
for i := uint(0); i < 4; i++ { for i := uint(0); i < 4; i++ {
buf[i] = byte(n >> ((3 - i) * 8)) buf[i] = byte(n >> ((3 - i) * 8))
} }
return append(append(dst, byte(major|subType)), buf[0], buf[1], buf[2], buf[3]) return append(append(dst, major|subType), buf[0], buf[1], buf[2], buf[3])
} }
// AppendFloats32 encodes and inserts an array of single precision float value into the dst byte array. // AppendFloats32 encodes and inserts an array of single precision float value into the dst byte array.
func (e Encoder) AppendFloats32(dst []byte, vals []float32) []byte { func (e Encoder) AppendFloats32(dst []byte, vals []float32, unused int) []byte {
major := majorTypeArray major := majorTypeArray
l := len(vals) l := len(vals)
if l == 0 { if l == 0 {
@ -379,18 +380,18 @@ func (e Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
for _, v := range vals { for _, v := range vals {
dst = e.AppendFloat32(dst, v) dst = e.AppendFloat32(dst, v, unused)
} }
return dst return dst
} }
// AppendFloat64 encodes and inserts a double precision float value into the dst byte array. // AppendFloat64 encodes and inserts a double precision float value into the dst byte array.
func (Encoder) AppendFloat64(dst []byte, val float64) []byte { func (Encoder) AppendFloat64(dst []byte, val float64, unused int) []byte {
switch { switch {
case math.IsNaN(val): case math.IsNaN(val):
return append(dst, "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00"...) return append(dst, "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00"...)
@ -402,7 +403,7 @@ func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
major := majorTypeSimpleAndFloat major := majorTypeSimpleAndFloat
subType := additionalTypeFloat64 subType := additionalTypeFloat64
n := math.Float64bits(val) n := math.Float64bits(val)
dst = append(dst, byte(major|subType)) dst = append(dst, major|subType)
for i := uint(1); i <= 8; i++ { for i := uint(1); i <= 8; i++ {
b := byte(n >> ((8 - i) * 8)) b := byte(n >> ((8 - i) * 8))
dst = append(dst, b) dst = append(dst, b)
@ -411,7 +412,7 @@ func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
} }
// AppendFloats64 encodes and inserts an array of double precision float values into the dst byte array. // AppendFloats64 encodes and inserts an array of double precision float values into the dst byte array.
func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte { func (e Encoder) AppendFloats64(dst []byte, vals []float64, unused int) []byte {
major := majorTypeArray major := majorTypeArray
l := len(vals) l := len(vals)
if l == 0 { if l == 0 {
@ -419,12 +420,12 @@ func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
} }
if l <= additionalMax { if l <= additionalMax {
lb := byte(l) lb := byte(l)
dst = append(dst, byte(major|lb)) dst = append(dst, major|lb)
} else { } else {
dst = appendCborTypePrefix(dst, major, uint64(l)) dst = appendCborTypePrefix(dst, major, uint64(l))
} }
for _, v := range vals { for _, v := range vals {
dst = e.AppendFloat64(dst, v) dst = e.AppendFloat64(dst, v, unused)
} }
return dst return dst
} }
@ -438,9 +439,17 @@ func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
return AppendEmbeddedJSON(dst, marshaled) return AppendEmbeddedJSON(dst, marshaled)
} }
// AppendType appends the parameter type (as a string) to the input byte slice.
func (e Encoder) AppendType(dst []byte, i interface{}) []byte {
if i == nil {
return e.AppendString(dst, "<nil>")
}
return e.AppendString(dst, reflect.TypeOf(i).String())
}
// AppendIPAddr encodes and inserts an IP Address (IPv4 or IPv6). // AppendIPAddr encodes and inserts an IP Address (IPv4 or IPv6).
func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte { func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte {
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16)) dst = append(dst, majorTypeTags|additionalTypeIntUint16)
dst = append(dst, byte(additionalTypeTagNetworkAddr>>8)) dst = append(dst, byte(additionalTypeTagNetworkAddr>>8))
dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff)) dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff))
return e.AppendBytes(dst, ip) return e.AppendBytes(dst, ip)
@ -448,21 +457,21 @@ func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte {
// AppendIPPrefix encodes and inserts an IP Address Prefix (Address + Mask Length). // AppendIPPrefix encodes and inserts an IP Address Prefix (Address + Mask Length).
func (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte { func (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte {
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16)) dst = append(dst, majorTypeTags|additionalTypeIntUint16)
dst = append(dst, byte(additionalTypeTagNetworkPrefix>>8)) dst = append(dst, byte(additionalTypeTagNetworkPrefix>>8))
dst = append(dst, byte(additionalTypeTagNetworkPrefix&0xff)) dst = append(dst, byte(additionalTypeTagNetworkPrefix&0xff))
// Prefix is a tuple (aka MAP of 1 pair of elements) - // Prefix is a tuple (aka MAP of 1 pair of elements) -
// first element is prefix, second is mask length. // first element is prefix, second is mask length.
dst = append(dst, byte(majorTypeMap|0x1)) dst = append(dst, majorTypeMap|0x1)
dst = e.AppendBytes(dst, pfx.IP) dst = e.AppendBytes(dst, pfx.IP)
maskLen, _ := pfx.Mask.Size() maskLen, _ := pfx.Mask.Size()
return e.AppendUint8(dst, uint8(maskLen)) return e.AppendUint8(dst, uint8(maskLen))
} }
// AppendMACAddr encodes and inserts an Hardware (MAC) address. // AppendMACAddr encodes and inserts a Hardware (MAC) address.
func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte { func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte {
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16)) dst = append(dst, majorTypeTags|additionalTypeIntUint16)
dst = append(dst, byte(additionalTypeTagNetworkAddr>>8)) dst = append(dst, byte(additionalTypeTagNetworkAddr>>8))
dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff)) dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff))
return e.AppendBytes(dst, ha) return e.AppendBytes(dst, ha)
@ -470,7 +479,7 @@ func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte {
// AppendHex adds a TAG and inserts a hex bytes as a string. // AppendHex adds a TAG and inserts a hex bytes as a string.
func (e Encoder) AppendHex(dst []byte, val []byte) []byte { func (e Encoder) AppendHex(dst []byte, val []byte) []byte {
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16)) dst = append(dst, majorTypeTags|additionalTypeIntUint16)
dst = append(dst, byte(additionalTypeTagHexString>>8)) dst = append(dst, byte(additionalTypeTagHexString>>8))
dst = append(dst, byte(additionalTypeTagHexString&0xff)) dst = append(dst, byte(additionalTypeTagHexString&0xff))
return e.AppendBytes(dst, val) return e.AppendBytes(dst, val)

View file

@ -1,6 +1,9 @@
package json package json
import "unicode/utf8" import (
"fmt"
"unicode/utf8"
)
const hex = "0123456789abcdef" const hex = "0123456789abcdef"
@ -34,7 +37,7 @@ func (e Encoder) AppendStrings(dst []byte, vals []string) []byte {
// //
// The operation loops though each byte in the string looking // The operation loops though each byte in the string looking
// for characters that need json or utf8 encoding. If the string // for characters that need json or utf8 encoding. If the string
// does not need encoding, then the string is appended in it's // does not need encoding, then the string is appended in its
// entirety to the byte slice. // entirety to the byte slice.
// If we encounter a byte that does need encoding, switch up // If we encounter a byte that does need encoding, switch up
// the operation and perform a byte-by-byte read-encode-append. // the operation and perform a byte-by-byte read-encode-append.
@ -53,14 +56,39 @@ func (Encoder) AppendString(dst []byte, s string) []byte {
return append(dst, '"') return append(dst, '"')
} }
} }
// The string has no need for encoding an therefore is directly // The string has no need for encoding and therefore is directly
// appended to the byte slice. // appended to the byte slice.
dst = append(dst, s...) dst = append(dst, s...)
// End with a double quote // End with a double quote
return append(dst, '"') return append(dst, '"')
} }
// appendStringComplex is used by appendString to take over an in // AppendStringers encodes the provided Stringer list to json and
// appends the encoded Stringer list to the input byte slice.
func (e Encoder) AppendStringers(dst []byte, vals []fmt.Stringer) []byte {
if len(vals) == 0 {
return append(dst, '[', ']')
}
dst = append(dst, '[')
dst = e.AppendStringer(dst, vals[0])
if len(vals) > 1 {
for _, val := range vals[1:] {
dst = e.AppendStringer(append(dst, ','), val)
}
}
return append(dst, ']')
}
// AppendStringer encodes the input Stringer to json and appends the
// encoded Stringer value to the input byte slice.
func (e Encoder) AppendStringer(dst []byte, val fmt.Stringer) []byte {
if val == nil {
return e.AppendInterface(dst, nil)
}
return e.AppendString(dst, val.String())
}
//// appendStringComplex is used by appendString to take over an in
// progress JSON string encoding that encountered a character that needs // progress JSON string encoding that encountered a character that needs
// to be encoded. // to be encoded.
func appendStringComplex(dst []byte, s string, i int) []byte { func appendStringComplex(dst []byte, s string, i int) []byte {
@ -71,7 +99,7 @@ func appendStringComplex(dst []byte, s string, i int) []byte {
r, size := utf8.DecodeRuneInString(s[i:]) r, size := utf8.DecodeRuneInString(s[i:])
if r == utf8.RuneError && size == 1 { if r == utf8.RuneError && size == 1 {
// In case of error, first append previous simple characters to // In case of error, first append previous simple characters to
// the byte slice if any and append a remplacement character code // the byte slice if any and append a replacement character code
// in place of the invalid sequence. // in place of the invalid sequence.
if start < i { if start < i {
dst = append(dst, s[start:i]...) dst = append(dst, s[start:i]...)

View file

@ -10,6 +10,7 @@ const (
timeFormatUnix = "" timeFormatUnix = ""
timeFormatUnixMs = "UNIXMS" timeFormatUnixMs = "UNIXMS"
timeFormatUnixMicro = "UNIXMICRO" timeFormatUnixMicro = "UNIXMICRO"
timeFormatUnixNano = "UNIXNANO"
) )
// AppendTime formats the input time with the given format // AppendTime formats the input time with the given format
@ -22,6 +23,8 @@ func (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte {
return e.AppendInt64(dst, t.UnixNano()/1000000) return e.AppendInt64(dst, t.UnixNano()/1000000)
case timeFormatUnixMicro: case timeFormatUnixMicro:
return e.AppendInt64(dst, t.UnixNano()/1000) return e.AppendInt64(dst, t.UnixNano()/1000)
case timeFormatUnixNano:
return e.AppendInt64(dst, t.UnixNano())
} }
return append(t.AppendFormat(append(dst, '"'), format), '"') return append(t.AppendFormat(append(dst, '"'), format), '"')
} }
@ -33,7 +36,11 @@ func (Encoder) AppendTimes(dst []byte, vals []time.Time, format string) []byte {
case timeFormatUnix: case timeFormatUnix:
return appendUnixTimes(dst, vals) return appendUnixTimes(dst, vals)
case timeFormatUnixMs: case timeFormatUnixMs:
return appendUnixMsTimes(dst, vals) return appendUnixNanoTimes(dst, vals, 1000000)
case timeFormatUnixMicro:
return appendUnixNanoTimes(dst, vals, 1000)
case timeFormatUnixNano:
return appendUnixNanoTimes(dst, vals, 1)
} }
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -64,15 +71,15 @@ func appendUnixTimes(dst []byte, vals []time.Time) []byte {
return dst return dst
} }
func appendUnixMsTimes(dst []byte, vals []time.Time) []byte { func appendUnixNanoTimes(dst []byte, vals []time.Time, div int64) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
} }
dst = append(dst, '[') dst = append(dst, '[')
dst = strconv.AppendInt(dst, vals[0].UnixNano()/1000000, 10) dst = strconv.AppendInt(dst, vals[0].UnixNano()/div, 10)
if len(vals) > 1 { if len(vals) > 1 {
for _, t := range vals[1:] { for _, t := range vals[1:] {
dst = strconv.AppendInt(append(dst, ','), t.UnixNano()/1000000, 10) dst = strconv.AppendInt(append(dst, ','), t.UnixNano()/div, 10)
} }
} }
dst = append(dst, ']') dst = append(dst, ']')
@ -81,24 +88,24 @@ func appendUnixMsTimes(dst []byte, vals []time.Time) []byte {
// AppendDuration formats the input duration with the given unit & format // AppendDuration formats the input duration with the given unit & format
// and appends the encoded string to the input byte slice. // and appends the encoded string to the input byte slice.
func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte { func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool, precision int) []byte {
if useInt { if useInt {
return strconv.AppendInt(dst, int64(d/unit), 10) return strconv.AppendInt(dst, int64(d/unit), 10)
} }
return e.AppendFloat64(dst, float64(d)/float64(unit)) return e.AppendFloat64(dst, float64(d)/float64(unit), precision)
} }
// AppendDurations formats the input durations with the given unit & format // AppendDurations formats the input durations with the given unit & format
// and appends the encoded string list to the input byte slice. // and appends the encoded string list to the input byte slice.
func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte { func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool, precision int) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
} }
dst = append(dst, '[') dst = append(dst, '[')
dst = e.AppendDuration(dst, vals[0], unit, useInt) dst = e.AppendDuration(dst, vals[0], unit, useInt, precision)
if len(vals) > 1 { if len(vals) > 1 {
for _, d := range vals[1:] { for _, d := range vals[1:] {
dst = e.AppendDuration(append(dst, ','), d, unit, useInt) dst = e.AppendDuration(append(dst, ','), d, unit, useInt, precision)
} }
} }
dst = append(dst, ']') dst = append(dst, ']')

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"math" "math"
"net" "net"
"reflect"
"strconv" "strconv"
) )
@ -278,7 +279,7 @@ func (Encoder) AppendUints32(dst []byte, vals []uint32) []byte {
// AppendUint64 converts the input uint64 to a string and // AppendUint64 converts the input uint64 to a string and
// appends the encoded string to the input byte slice. // appends the encoded string to the input byte slice.
func (Encoder) AppendUint64(dst []byte, val uint64) []byte { func (Encoder) AppendUint64(dst []byte, val uint64) []byte {
return strconv.AppendUint(dst, uint64(val), 10) return strconv.AppendUint(dst, val, 10)
} }
// AppendUints64 encodes the input uint64s to json and // AppendUints64 encodes the input uint64s to json and
@ -298,9 +299,9 @@ func (Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
return dst return dst
} }
func appendFloat(dst []byte, val float64, bitSize int) []byte { func appendFloat(dst []byte, val float64, bitSize, precision int) []byte {
// JSON does not permit NaN or Infinity. A typical JSON encoder would fail // JSON does not permit NaN or Infinity. A typical JSON encoder would fail
// with an error, but a logging library wants the data to get thru so we // with an error, but a logging library wants the data to get through so we
// make a tradeoff and store those types as string. // make a tradeoff and store those types as string.
switch { switch {
case math.IsNaN(val): case math.IsNaN(val):
@ -310,26 +311,47 @@ func appendFloat(dst []byte, val float64, bitSize int) []byte {
case math.IsInf(val, -1): case math.IsInf(val, -1):
return append(dst, `"-Inf"`...) return append(dst, `"-Inf"`...)
} }
return strconv.AppendFloat(dst, val, 'f', -1, bitSize) // convert as if by es6 number to string conversion
// see also https://cs.opensource.google/go/go/+/refs/tags/go1.20.3:src/encoding/json/encode.go;l=573
strFmt := byte('f')
// If precision is set to a value other than -1, we always just format the float using that precision.
if precision == -1 {
// Use float32 comparisons for underlying float32 value to get precise cutoffs right.
if abs := math.Abs(val); abs != 0 {
if bitSize == 64 && (abs < 1e-6 || abs >= 1e21) || bitSize == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
strFmt = 'e'
}
}
}
dst = strconv.AppendFloat(dst, val, strFmt, precision, bitSize)
if strFmt == 'e' {
// Clean up e-09 to e-9
n := len(dst)
if n >= 4 && dst[n-4] == 'e' && dst[n-3] == '-' && dst[n-2] == '0' {
dst[n-2] = dst[n-1]
dst = dst[:n-1]
}
}
return dst
} }
// AppendFloat32 converts the input float32 to a string and // AppendFloat32 converts the input float32 to a string and
// appends the encoded string to the input byte slice. // appends the encoded string to the input byte slice.
func (Encoder) AppendFloat32(dst []byte, val float32) []byte { func (Encoder) AppendFloat32(dst []byte, val float32, precision int) []byte {
return appendFloat(dst, float64(val), 32) return appendFloat(dst, float64(val), 32, precision)
} }
// AppendFloats32 encodes the input float32s to json and // AppendFloats32 encodes the input float32s to json and
// appends the encoded string list to the input byte slice. // appends the encoded string list to the input byte slice.
func (Encoder) AppendFloats32(dst []byte, vals []float32) []byte { func (Encoder) AppendFloats32(dst []byte, vals []float32, precision int) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
} }
dst = append(dst, '[') dst = append(dst, '[')
dst = appendFloat(dst, float64(vals[0]), 32) dst = appendFloat(dst, float64(vals[0]), 32, precision)
if len(vals) > 1 { if len(vals) > 1 {
for _, val := range vals[1:] { for _, val := range vals[1:] {
dst = appendFloat(append(dst, ','), float64(val), 32) dst = appendFloat(append(dst, ','), float64(val), 32, precision)
} }
} }
dst = append(dst, ']') dst = append(dst, ']')
@ -338,21 +360,21 @@ func (Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
// AppendFloat64 converts the input float64 to a string and // AppendFloat64 converts the input float64 to a string and
// appends the encoded string to the input byte slice. // appends the encoded string to the input byte slice.
func (Encoder) AppendFloat64(dst []byte, val float64) []byte { func (Encoder) AppendFloat64(dst []byte, val float64, precision int) []byte {
return appendFloat(dst, val, 64) return appendFloat(dst, val, 64, precision)
} }
// AppendFloats64 encodes the input float64s to json and // AppendFloats64 encodes the input float64s to json and
// appends the encoded string list to the input byte slice. // appends the encoded string list to the input byte slice.
func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte { func (Encoder) AppendFloats64(dst []byte, vals []float64, precision int) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
} }
dst = append(dst, '[') dst = append(dst, '[')
dst = appendFloat(dst, vals[0], 64) dst = appendFloat(dst, vals[0], 64, precision)
if len(vals) > 1 { if len(vals) > 1 {
for _, val := range vals[1:] { for _, val := range vals[1:] {
dst = appendFloat(append(dst, ','), val, 64) dst = appendFloat(append(dst, ','), val, 64, precision)
} }
} }
dst = append(dst, ']') dst = append(dst, ']')
@ -369,6 +391,14 @@ func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
return append(dst, marshaled...) return append(dst, marshaled...)
} }
// AppendType appends the parameter type (as a string) to the input byte slice.
func (e Encoder) AppendType(dst []byte, i interface{}) []byte {
if i == nil {
return e.AppendString(dst, "<nil>")
}
return e.AppendString(dst, reflect.TypeOf(i).String())
}
// AppendObjectData takes in an object that is already in a byte array // AppendObjectData takes in an object that is already in a byte array
// and adds it to the dst. // and adds it to the dst.
func (Encoder) AppendObjectData(dst []byte, o []byte) []byte { func (Encoder) AppendObjectData(dst []byte, o []byte) []byte {

101
vendor/github.com/rs/zerolog/log.go generated vendored
View file

@ -24,7 +24,7 @@
// //
// Sub-loggers let you chain loggers with additional context: // Sub-loggers let you chain loggers with additional context:
// //
// sublogger := log.With().Str("component": "foo").Logger() // sublogger := log.With().Str("component", "foo").Logger()
// sublogger.Info().Msg("hello world") // sublogger.Info().Msg("hello world")
// // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"} // // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"}
// //
@ -82,8 +82,9 @@
// log.Warn().Msg("") // log.Warn().Msg("")
// // Output: {"level":"warn","severity":"warn"} // // Output: {"level":"warn","severity":"warn"}
// //
// # Caveats
// //
// Caveats // Field duplication:
// //
// There is no fields deduplication out-of-the-box. // There is no fields deduplication out-of-the-box.
// Using the same key multiple times creates new key in final JSON each time. // Using the same key multiple times creates new key in final JSON each time.
@ -96,14 +97,30 @@
// //
// In this case, many consumers will take the last value, // In this case, many consumers will take the last value,
// but this is not guaranteed; check yours if in doubt. // but this is not guaranteed; check yours if in doubt.
//
// Concurrency safety:
//
// Be careful when calling UpdateContext. It is not concurrency safe. Use the With method to create a child logger:
//
// func handler(w http.ResponseWriter, r *http.Request) {
// // Create a child logger for concurrency safety
// logger := log.Logger.With().Logger()
//
// // Add context fields, for example User-Agent from HTTP headers
// logger.UpdateContext(func(c zerolog.Context) zerolog.Context {
// ...
// })
// }
package zerolog package zerolog
import ( import (
"context"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"strconv" "strconv"
"strings"
) )
// Level defines log levels. // Level defines log levels.
@ -159,24 +176,24 @@ func (l Level) String() string {
// ParseLevel converts a level string into a zerolog Level value. // ParseLevel converts a level string into a zerolog Level value.
// returns an error if the input string does not match known values. // returns an error if the input string does not match known values.
func ParseLevel(levelStr string) (Level, error) { func ParseLevel(levelStr string) (Level, error) {
switch levelStr { switch {
case LevelFieldMarshalFunc(TraceLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(TraceLevel)):
return TraceLevel, nil return TraceLevel, nil
case LevelFieldMarshalFunc(DebugLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(DebugLevel)):
return DebugLevel, nil return DebugLevel, nil
case LevelFieldMarshalFunc(InfoLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(InfoLevel)):
return InfoLevel, nil return InfoLevel, nil
case LevelFieldMarshalFunc(WarnLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(WarnLevel)):
return WarnLevel, nil return WarnLevel, nil
case LevelFieldMarshalFunc(ErrorLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(ErrorLevel)):
return ErrorLevel, nil return ErrorLevel, nil
case LevelFieldMarshalFunc(FatalLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(FatalLevel)):
return FatalLevel, nil return FatalLevel, nil
case LevelFieldMarshalFunc(PanicLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(PanicLevel)):
return PanicLevel, nil return PanicLevel, nil
case LevelFieldMarshalFunc(Disabled): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(Disabled)):
return Disabled, nil return Disabled, nil
case LevelFieldMarshalFunc(NoLevel): case strings.EqualFold(levelStr, LevelFieldMarshalFunc(NoLevel)):
return NoLevel, nil return NoLevel, nil
} }
i, err := strconv.Atoi(levelStr) i, err := strconv.Atoi(levelStr)
@ -189,6 +206,21 @@ func ParseLevel(levelStr string) (Level, error) {
return Level(i), nil return Level(i), nil
} }
// UnmarshalText implements encoding.TextUnmarshaler to allow for easy reading from toml/yaml/json formats
func (l *Level) UnmarshalText(text []byte) error {
if l == nil {
return errors.New("can't unmarshal a nil *Level")
}
var err error
*l, err = ParseLevel(string(text))
return err
}
// MarshalText implements encoding.TextMarshaler to allow for easy writing into toml/yaml/json formats
func (l Level) MarshalText() ([]byte, error) {
return []byte(LevelFieldMarshalFunc(l)), nil
}
// A Logger represents an active logging object that generates lines // A Logger represents an active logging object that generates lines
// of JSON output to an io.Writer. Each logging operation makes a single // of JSON output to an io.Writer. Each logging operation makes a single
// call to the Writer's Write method. There is no guarantee on access // call to the Writer's Write method. There is no guarantee on access
@ -201,6 +233,7 @@ type Logger struct {
context []byte context []byte
hooks []Hook hooks []Hook
stack bool stack bool
ctx context.Context
} }
// New creates a root logger with given output writer. If the output writer implements // New creates a root logger with given output writer. If the output writer implements
@ -212,11 +245,11 @@ type Logger struct {
// you may consider using sync wrapper. // you may consider using sync wrapper.
func New(w io.Writer) Logger { func New(w io.Writer) Logger {
if w == nil { if w == nil {
w = ioutil.Discard w = io.Discard
} }
lw, ok := w.(LevelWriter) lw, ok := w.(LevelWriter)
if !ok { if !ok {
lw = levelWriterAdapter{w} lw = LevelWriterAdapter{w}
} }
return Logger{w: lw, level: TraceLevel} return Logger{w: lw, level: TraceLevel}
} }
@ -258,7 +291,8 @@ func (l Logger) With() Context {
// UpdateContext updates the internal logger's context. // UpdateContext updates the internal logger's context.
// //
// Use this method with caution. If unsure, prefer the With method. // Caution: This method is not concurrency safe.
// Use the With method to create a child logger before modifying the context from concurrent goroutines.
func (l *Logger) UpdateContext(update func(c Context) Context) { func (l *Logger) UpdateContext(update func(c Context) Context) {
if l == disabledLogger { if l == disabledLogger {
return return
@ -291,8 +325,13 @@ func (l Logger) Sample(s Sampler) Logger {
} }
// Hook returns a logger with the h Hook. // Hook returns a logger with the h Hook.
func (l Logger) Hook(h Hook) Logger { func (l Logger) Hook(hooks ...Hook) Logger {
l.hooks = append(l.hooks, h) if len(hooks) == 0 {
return l
}
newHooks := make([]Hook, len(l.hooks), len(l.hooks)+len(hooks))
copy(newHooks, l.hooks)
l.hooks = append(newHooks, hooks...)
return l return l
} }
@ -348,7 +387,14 @@ func (l *Logger) Err(err error) *Event {
// //
// You must call Msg on the returned event in order to send the event. // You must call Msg on the returned event in order to send the event.
func (l *Logger) Fatal() *Event { func (l *Logger) Fatal() *Event {
return l.newEvent(FatalLevel, func(msg string) { os.Exit(1) }) return l.newEvent(FatalLevel, func(msg string) {
if closer, ok := l.w.(io.Closer); ok {
// Close the writer to flush any buffered message. Otherwise the message
// will be lost as os.Exit() terminates the program immediately.
closer.Close()
}
os.Exit(1)
})
} }
// Panic starts a new message with panic level. The panic() function // Panic starts a new message with panic level. The panic() function
@ -361,7 +407,7 @@ func (l *Logger) Panic() *Event {
// WithLevel starts a new message with level. Unlike Fatal and Panic // WithLevel starts a new message with level. Unlike Fatal and Panic
// methods, WithLevel does not terminate the program or stop the ordinary // methods, WithLevel does not terminate the program or stop the ordinary
// flow of a gourotine when used with their respective levels. // flow of a goroutine when used with their respective levels.
// //
// You must call Msg on the returned event in order to send the event. // You must call Msg on the returned event in order to send the event.
func (l *Logger) WithLevel(level Level) *Event { func (l *Logger) WithLevel(level Level) *Event {
@ -413,6 +459,14 @@ func (l *Logger) Printf(format string, v ...interface{}) {
} }
} }
// Println sends a log event using debug level and no extra field.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Println(v ...interface{}) {
if e := l.Debug(); e.Enabled() {
e.CallerSkipFrame(1).Msg(fmt.Sprintln(v...))
}
}
// Write implements the io.Writer interface. This is useful to set as a writer // Write implements the io.Writer interface. This is useful to set as a writer
// for the standard library log. // for the standard library log.
func (l Logger) Write(p []byte) (n int, err error) { func (l Logger) Write(p []byte) (n int, err error) {
@ -428,11 +482,15 @@ func (l Logger) Write(p []byte) (n int, err error) {
func (l *Logger) newEvent(level Level, done func(string)) *Event { func (l *Logger) newEvent(level Level, done func(string)) *Event {
enabled := l.should(level) enabled := l.should(level)
if !enabled { if !enabled {
if done != nil {
done("")
}
return nil return nil
} }
e := newEvent(l.w, level) e := newEvent(l.w, level)
e.done = done e.done = done
e.ch = l.hooks e.ch = l.hooks
e.ctx = l.ctx
if level != NoLevel && LevelFieldName != "" { if level != NoLevel && LevelFieldName != "" {
e.Str(LevelFieldName, LevelFieldMarshalFunc(level)) e.Str(LevelFieldName, LevelFieldMarshalFunc(level))
} }
@ -447,6 +505,9 @@ func (l *Logger) newEvent(level Level, done func(string)) *Event {
// should returns true if the log event should be logged. // should returns true if the log event should be logged.
func (l *Logger) should(lvl Level) bool { func (l *Logger) should(lvl Level) bool {
if l.w == nil {
return false
}
if lvl < l.level || lvl < GlobalLevel() { if lvl < l.level || lvl < GlobalLevel() {
return false return false
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View file

@ -84,7 +84,7 @@ func (s *BurstSampler) Sample(lvl Level) bool {
} }
func (s *BurstSampler) inc() uint32 { func (s *BurstSampler) inc() uint32 {
now := time.Now().UnixNano() now := TimestampFunc().UnixNano()
resetAt := atomic.LoadInt64(&s.resetAt) resetAt := atomic.LoadInt64(&s.resetAt)
var c uint32 var c uint32
if now > resetAt { if now > resetAt {

View file

@ -78,3 +78,12 @@ func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {
n = len(p) n = len(p)
return return
} }
// Call the underlying writer's Close method if it is an io.Closer. Otherwise
// does nothing.
func (sw syslogWriter) Close() error {
if c, ok := sw.w.(io.Closer); ok {
return c.Close()
}
return nil
}

View file

@ -1,7 +1,12 @@
package zerolog package zerolog
import ( import (
"bytes"
"io" "io"
"path"
"runtime"
"strconv"
"strings"
"sync" "sync"
) )
@ -12,14 +17,25 @@ type LevelWriter interface {
WriteLevel(level Level, p []byte) (n int, err error) WriteLevel(level Level, p []byte) (n int, err error)
} }
type levelWriterAdapter struct { // LevelWriterAdapter adapts an io.Writer to support the LevelWriter interface.
type LevelWriterAdapter struct {
io.Writer io.Writer
} }
func (lw levelWriterAdapter) WriteLevel(l Level, p []byte) (n int, err error) { // WriteLevel simply writes everything to the adapted writer, ignoring the level.
func (lw LevelWriterAdapter) WriteLevel(l Level, p []byte) (n int, err error) {
return lw.Write(p) return lw.Write(p)
} }
// Call the underlying writer's Close method if it is an io.Closer. Otherwise
// does nothing.
func (lw LevelWriterAdapter) Close() error {
if closer, ok := lw.Writer.(io.Closer); ok {
return closer.Close()
}
return nil
}
type syncWriter struct { type syncWriter struct {
mu sync.Mutex mu sync.Mutex
lw LevelWriter lw LevelWriter
@ -33,7 +49,7 @@ func SyncWriter(w io.Writer) io.Writer {
if lw, ok := w.(LevelWriter); ok { if lw, ok := w.(LevelWriter); ok {
return &syncWriter{lw: lw} return &syncWriter{lw: lw}
} }
return &syncWriter{lw: levelWriterAdapter{w}} return &syncWriter{lw: LevelWriterAdapter{w}}
} }
// Write implements the io.Writer interface. // Write implements the io.Writer interface.
@ -50,6 +66,15 @@ func (s *syncWriter) WriteLevel(l Level, p []byte) (n int, err error) {
return s.lw.WriteLevel(l, p) return s.lw.WriteLevel(l, p)
} }
func (s *syncWriter) Close() error {
s.mu.Lock()
defer s.mu.Unlock()
if closer, ok := s.lw.(io.Closer); ok {
return closer.Close()
}
return nil
}
type multiLevelWriter struct { type multiLevelWriter struct {
writers []LevelWriter writers []LevelWriter
} }
@ -82,6 +107,20 @@ func (t multiLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) {
return n, err return n, err
} }
// Calls close on all the underlying writers that are io.Closers. If any of the
// Close methods return an error, the remainder of the closers are not closed
// and the error is returned.
func (t multiLevelWriter) Close() error {
for _, w := range t.writers {
if closer, ok := w.(io.Closer); ok {
if err := closer.Close(); err != nil {
return err
}
}
}
return nil
}
// MultiLevelWriter creates a writer that duplicates its writes to all the // MultiLevelWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command. If some writers // provided writers, similar to the Unix tee(1) command. If some writers
// implement LevelWriter, their WriteLevel method will be used instead of Write. // implement LevelWriter, their WriteLevel method will be used instead of Write.
@ -91,8 +130,217 @@ func MultiLevelWriter(writers ...io.Writer) LevelWriter {
if lw, ok := w.(LevelWriter); ok { if lw, ok := w.(LevelWriter); ok {
lwriters = append(lwriters, lw) lwriters = append(lwriters, lw)
} else { } else {
lwriters = append(lwriters, levelWriterAdapter{w}) lwriters = append(lwriters, LevelWriterAdapter{w})
} }
} }
return multiLevelWriter{lwriters} return multiLevelWriter{lwriters}
} }
// TestingLog is the logging interface of testing.TB.
type TestingLog interface {
Log(args ...interface{})
Logf(format string, args ...interface{})
Helper()
}
// TestWriter is a writer that writes to testing.TB.
type TestWriter struct {
T TestingLog
// Frame skips caller frames to capture the original file and line numbers.
Frame int
}
// NewTestWriter creates a writer that logs to the testing.TB.
func NewTestWriter(t TestingLog) TestWriter {
return TestWriter{T: t}
}
// Write to testing.TB.
func (t TestWriter) Write(p []byte) (n int, err error) {
t.T.Helper()
n = len(p)
// Strip trailing newline because t.Log always adds one.
p = bytes.TrimRight(p, "\n")
// Try to correct the log file and line number to the caller.
if t.Frame > 0 {
_, origFile, origLine, _ := runtime.Caller(1)
_, frameFile, frameLine, ok := runtime.Caller(1 + t.Frame)
if ok {
erase := strings.Repeat("\b", len(path.Base(origFile))+len(strconv.Itoa(origLine))+3)
t.T.Logf("%s%s:%d: %s", erase, path.Base(frameFile), frameLine, p)
return n, err
}
}
t.T.Log(string(p))
return n, err
}
// ConsoleTestWriter creates an option that correctly sets the file frame depth for testing.TB log.
func ConsoleTestWriter(t TestingLog) func(w *ConsoleWriter) {
return func(w *ConsoleWriter) {
w.Out = TestWriter{T: t, Frame: 6}
}
}
// FilteredLevelWriter writes only logs at Level or above to Writer.
//
// It should be used only in combination with MultiLevelWriter when you
// want to write to multiple destinations at different levels. Otherwise
// you should just set the level on the logger and filter events early.
// When using MultiLevelWriter then you set the level on the logger to
// the lowest of the levels you use for writers.
type FilteredLevelWriter struct {
Writer LevelWriter
Level Level
}
// Write writes to the underlying Writer.
func (w *FilteredLevelWriter) Write(p []byte) (int, error) {
return w.Writer.Write(p)
}
// WriteLevel calls WriteLevel of the underlying Writer only if the level is equal
// or above the Level.
func (w *FilteredLevelWriter) WriteLevel(level Level, p []byte) (int, error) {
if level >= w.Level {
return w.Writer.WriteLevel(level, p)
}
return len(p), nil
}
var triggerWriterPool = &sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(make([]byte, 0, 1024))
},
}
// TriggerLevelWriter buffers log lines at the ConditionalLevel or below
// until a trigger level (or higher) line is emitted. Log lines with level
// higher than ConditionalLevel are always written out to the destination
// writer. If trigger never happens, buffered log lines are never written out.
//
// It can be used to configure "log level per request".
type TriggerLevelWriter struct {
// Destination writer. If LevelWriter is provided (usually), its WriteLevel is used
// instead of Write.
io.Writer
// ConditionalLevel is the level (and below) at which lines are buffered until
// a trigger level (or higher) line is emitted. Usually this is set to DebugLevel.
ConditionalLevel Level
// TriggerLevel is the lowest level that triggers the sending of the conditional
// level lines. Usually this is set to ErrorLevel.
TriggerLevel Level
buf *bytes.Buffer
triggered bool
mu sync.Mutex
}
func (w *TriggerLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) {
w.mu.Lock()
defer w.mu.Unlock()
// At first trigger level or above log line, we flush the buffer and change the
// trigger state to triggered.
if !w.triggered && l >= w.TriggerLevel {
err := w.trigger()
if err != nil {
return 0, err
}
}
// Unless triggered, we buffer everything at and below ConditionalLevel.
if !w.triggered && l <= w.ConditionalLevel {
if w.buf == nil {
w.buf = triggerWriterPool.Get().(*bytes.Buffer)
}
// We prefix each log line with a byte with the level.
// Hopefully we will never have a level value which equals a newline
// (which could interfere with reconstruction of log lines in the trigger method).
w.buf.WriteByte(byte(l))
w.buf.Write(p)
return len(p), nil
}
// Anything above ConditionalLevel is always passed through.
// Once triggered, everything is passed through.
if lw, ok := w.Writer.(LevelWriter); ok {
return lw.WriteLevel(l, p)
}
return w.Write(p)
}
// trigger expects lock to be held.
func (w *TriggerLevelWriter) trigger() error {
if w.triggered {
return nil
}
w.triggered = true
if w.buf == nil {
return nil
}
p := w.buf.Bytes()
for len(p) > 0 {
// We do not use bufio.Scanner here because we already have full buffer
// in the memory and we do not want extra copying from the buffer to
// scanner's token slice, nor we want to hit scanner's token size limit,
// and we also want to preserve newlines.
i := bytes.IndexByte(p, '\n')
line := p[0 : i+1]
p = p[i+1:]
// We prefixed each log line with a byte with the level.
level := Level(line[0])
line = line[1:]
var err error
if lw, ok := w.Writer.(LevelWriter); ok {
_, err = lw.WriteLevel(level, line)
} else {
_, err = w.Write(line)
}
if err != nil {
return err
}
}
return nil
}
// Trigger forces flushing the buffer and change the trigger state to
// triggered, if the writer has not already been triggered before.
func (w *TriggerLevelWriter) Trigger() error {
w.mu.Lock()
defer w.mu.Unlock()
return w.trigger()
}
// Close closes the writer and returns the buffer to the pool.
func (w *TriggerLevelWriter) Close() error {
w.mu.Lock()
defer w.mu.Unlock()
if w.buf == nil {
return nil
}
// We return the buffer only if it has not grown above the limit.
// This prevents accumulation of large buffers in the pool just
// because occasionally a large buffer might be needed.
if w.buf.Cap() <= TriggerLevelWriterBufferReuseLimit {
w.buf.Reset()
triggerWriterPool.Put(w.buf)
}
w.buf = nil
return nil
}

3
vendor/golang.org/x/sys/AUTHORS generated vendored
View file

@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.

View file

@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.

View file

@ -149,7 +149,7 @@ 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 Then, edit the regex (if necessary) to match the desired constant. Avoid making
the regex too broad to avoid matching unintended constants. the regex too broad to avoid matching unintended constants.
### mkmerge.go ### internal/mkmerge
This program is used to extract duplicate const, func, and type declarations This program is used to extract duplicate const, func, and type declarations
from the generated architecture-specific files listed below, and merge these from the generated architecture-specific files listed below, and merge these

31
vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s generated vendored Normal file
View file

@ -0,0 +1,31 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (darwin || freebsd || netbsd || openbsd) && gc
// +build darwin freebsd netbsd openbsd
// +build gc
#include "textflag.h"
//
// System call support for ppc64, BSD
//
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-104
JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB)

29
vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s generated vendored Normal file
View file

@ -0,0 +1,29 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (darwin || freebsd || netbsd || openbsd) && gc
// +build darwin freebsd netbsd openbsd
// +build gc
#include "textflag.h"
// System call support for RISCV64 BSD
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-104
JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB)

54
vendor/golang.org/x/sys/unix/asm_linux_loong64.s generated vendored Normal file
View file

@ -0,0 +1,54 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build linux && loong64 && gc
// +build linux
// +build loong64
// +build gc
#include "textflag.h"
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
JAL runtime·entersyscall(SB)
MOVV a1+8(FP), R4
MOVV a2+16(FP), R5
MOVV a3+24(FP), R6
MOVV R0, R7
MOVV R0, R8
MOVV R0, R9
MOVV trap+0(FP), R11 // syscall entry
SYSCALL
MOVV R4, r1+32(FP)
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
JAL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVV a1+8(FP), R4
MOVV a2+16(FP), R5
MOVV a3+24(FP), R6
MOVV R0, R7
MOVV R0, R8
MOVV R0, R9
MOVV trap+0(FP), R11 // syscall entry
SYSCALL
MOVV R4, r1+32(FP)
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
RET

View file

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package unix package unix

View file

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// //
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh //go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh
// +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh // +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh
package unix package unix

View file

@ -1,233 +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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
DLT_HHDLC = 0x79
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_FAITH = 0x16
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)

View file

@ -1,233 +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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
DLT_HHDLC = 0x79
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_FAITH = 0x16
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
SIOCADDRT = 0x8040720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8040720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)

View file

@ -1,226 +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.
package unix
const (
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
IFF_SMART = 0x20
IFT_FAITH = 0xf2
IFT_IPXIP = 0xf9
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)

View file

@ -1,17 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
DLT_HHDLC = 0x79
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
)

View file

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gccgo && !aix //go:build gccgo && !aix && !hurd
// +build gccgo,!aix // +build gccgo,!aix,!hurd
package unix package unix

View file

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build gccgo //go:build gccgo && !aix && !hurd
// +build !aix // +build gccgo,!aix,!hurd
#include <errno.h> #include <errno.h>
#include <stdint.h> #include <stdint.h>

View file

@ -8,7 +8,6 @@
package unix package unix
import ( import (
"bytes"
"unsafe" "unsafe"
) )
@ -45,13 +44,7 @@ func NewIfreq(name string) (*Ifreq, error) {
// Name returns the interface name associated with the Ifreq. // Name returns the interface name associated with the Ifreq.
func (ifr *Ifreq) Name() string { func (ifr *Ifreq) Name() string {
// BytePtrToString requires a NULL terminator or the program may crash. If return ByteSliceToString(ifr.raw.Ifrn[:])
// one is not present, just return the empty string.
if !bytes.Contains(ifr.raw.Ifrn[:], []byte{0x00}) {
return ""
}
return BytePtrToString(&ifr.raw.Ifrn[0])
} }
// According to netdevice(7), only AF_INET addresses are returned for numerous // According to netdevice(7), only AF_INET addresses are returned for numerous

View file

@ -4,9 +4,7 @@
package unix package unix
import ( import "unsafe"
"unsafe"
)
// IoctlRetInt performs an ioctl operation specified by req on a device // IoctlRetInt performs an ioctl operation specified by req on a device
// associated with opened file descriptor fd, and returns a non-negative // associated with opened file descriptor fd, and returns a non-negative
@ -194,3 +192,42 @@ func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
// identical so pass *IfreqData directly. // identical so pass *IfreqData directly.
return ioctlPtr(fd, req, unsafe.Pointer(value)) return ioctlPtr(fd, req, unsafe.Pointer(value))
} }
// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
// existing KCM socket, returning a structure containing the file descriptor of
// the new socket.
func IoctlKCMClone(fd int) (*KCMClone, error) {
var info KCMClone
if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
return nil, err
}
return &info, nil
}
// IoctlKCMAttach attaches a TCP socket and associated BPF program file
// descriptor to a multiplexor.
func IoctlKCMAttach(fd int, info KCMAttach) error {
return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
}
// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
}
// IoctlLoopGetStatus64 gets the status of the loop device associated with the
// file descriptor fd using the LOOP_GET_STATUS64 operation.
func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
var value LoopInfo64
if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {
return nil, err
}
return &value, nil
}
// IoctlLoopSetStatus64 sets the status of the loop device associated with the
// file descriptor fd using the LOOP_SET_STATUS64 operation.
func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
}

70
vendor/golang.org/x/sys/unix/ioctl_signed.go generated vendored Normal file
View file

@ -0,0 +1,70 @@
// 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.
//go:build aix || solaris
// +build aix solaris
package unix
import (
"unsafe"
)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req int, value int) error {
return ioctl(fd, req, uintptr(value))
}
// IoctlSetPointerInt performs an ioctl operation which sets an
// integer value on fd, using the specified request number. The ioctl
// argument is called with a pointer to the integer value, rather than
// passing the integer value directly.
func IoctlSetPointerInt(fd int, req int, value int) error {
v := int32(value)
return ioctlPtr(fd, req, unsafe.Pointer(&v))
}
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
//
// To change fd's window size, the req argument should be TIOCSWINSZ.
func IoctlSetWinsize(fd int, req int, value *Winsize) error {
// TODO: if we get the chance, remove the req parameter and
// hardcode TIOCSWINSZ.
return ioctlPtr(fd, req, unsafe.Pointer(value))
}
// IoctlSetTermios performs an ioctl on fd with a *Termios.
//
// The req value will usually be TCSETA or TIOCSETA.
func IoctlSetTermios(fd int, req int, value *Termios) error {
// TODO: if we get the chance, remove the req parameter.
return ioctlPtr(fd, req, unsafe.Pointer(value))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
//
// A few ioctl requests use the return value as an output parameter;
// for those, IoctlRetInt should be used instead of this function.
func IoctlGetInt(fd int, req int) (int, error) {
var value int
err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return value, err
}
func IoctlGetWinsize(fd int, req int) (*Winsize, error) {
var value Winsize
err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return &value, err
}
func IoctlGetTermios(fd int, req int) (*Termios, error) {
var value Termios
err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return &value, err
}

View file

@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris //go:build darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris // +build darwin dragonfly freebsd hurd linux netbsd openbsd
package unix package unix
import ( import (
"runtime"
"unsafe" "unsafe"
) )
@ -27,7 +26,7 @@ func IoctlSetInt(fd int, req uint, value int) error {
// passing the integer value directly. // passing the integer value directly.
func IoctlSetPointerInt(fd int, req uint, value int) error { func IoctlSetPointerInt(fd int, req uint, value int) error {
v := int32(value) v := int32(value)
return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) return ioctlPtr(fd, req, unsafe.Pointer(&v))
} }
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. // IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
@ -36,9 +35,7 @@ func IoctlSetPointerInt(fd int, req uint, value int) error {
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// TODO: if we get the chance, remove the req parameter and // TODO: if we get the chance, remove the req parameter and
// hardcode TIOCSWINSZ. // hardcode TIOCSWINSZ.
err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctlPtr(fd, req, unsafe.Pointer(value))
runtime.KeepAlive(value)
return err
} }
// IoctlSetTermios performs an ioctl on fd with a *Termios. // IoctlSetTermios performs an ioctl on fd with a *Termios.
@ -46,9 +43,7 @@ func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// The req value will usually be TCSETA or TIOCSETA. // The req value will usually be TCSETA or TIOCSETA.
func IoctlSetTermios(fd int, req uint, value *Termios) error { func IoctlSetTermios(fd int, req uint, value *Termios) error {
// TODO: if we get the chance, remove the req parameter. // TODO: if we get the chance, remove the req parameter.
err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctlPtr(fd, req, unsafe.Pointer(value))
runtime.KeepAlive(value)
return err
} }
// IoctlGetInt performs an ioctl operation which gets an integer value // IoctlGetInt performs an ioctl operation which gets an integer value
@ -58,18 +53,18 @@ func IoctlSetTermios(fd int, req uint, value *Termios) error {
// for those, IoctlRetInt should be used instead of this function. // for those, IoctlRetInt should be used instead of this function.
func IoctlGetInt(fd int, req uint) (int, error) { func IoctlGetInt(fd int, req uint) (int, error) {
var value int var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return value, err return value, err
} }
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return &value, err return &value, err
} }
func IoctlGetTermios(fd int, req uint) (*Termios, error) { func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return &value, err return &value, err
} }

View file

@ -17,25 +17,23 @@ import (
// IoctlSetInt performs an ioctl operation which sets an integer value // IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number. // on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error { func IoctlSetInt(fd int, req int, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. // IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
// //
// To change fd's window size, the req argument should be TIOCSWINSZ. // To change fd's window size, the req argument should be TIOCSWINSZ.
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func IoctlSetWinsize(fd int, req int, value *Winsize) error {
// TODO: if we get the chance, remove the req parameter and // TODO: if we get the chance, remove the req parameter and
// hardcode TIOCSWINSZ. // hardcode TIOCSWINSZ.
err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctlPtr(fd, req, unsafe.Pointer(value))
runtime.KeepAlive(value)
return err
} }
// IoctlSetTermios performs an ioctl on fd with a *Termios. // IoctlSetTermios performs an ioctl on fd with a *Termios.
// //
// The req value is expected to be TCSETS, TCSETSW, or TCSETSF // The req value is expected to be TCSETS, TCSETSW, or TCSETSF
func IoctlSetTermios(fd int, req uint, value *Termios) error { func IoctlSetTermios(fd int, req int, value *Termios) error {
if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) { if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) {
return ENOSYS return ENOSYS
} }
@ -49,22 +47,22 @@ func IoctlSetTermios(fd int, req uint, value *Termios) error {
// //
// A few ioctl requests use the return value as an output parameter; // A few ioctl requests use the return value as an output parameter;
// for those, IoctlRetInt should be used instead of this function. // for those, IoctlRetInt should be used instead of this function.
func IoctlGetInt(fd int, req uint) (int, error) { func IoctlGetInt(fd int, req int) (int, error) {
var value int var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return value, err return value, err
} }
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { func IoctlGetWinsize(fd int, req int) (*Winsize, error) {
var value Winsize var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return &value, err return &value, err
} }
// IoctlGetTermios performs an ioctl on fd with a *Termios. // IoctlGetTermios performs an ioctl on fd with a *Termios.
// //
// The req value is expected to be TCGETS // The req value is expected to be TCGETS
func IoctlGetTermios(fd int, req uint) (*Termios, error) { func IoctlGetTermios(fd int, req int) (*Termios, error) {
var value Termios var value Termios
if req != TCGETS { if req != TCGETS {
return &value, ENOSYS return &value, ENOSYS

View file

@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then
# Use the Docker-based build system # Use the Docker-based build system
# Files generated through docker (use $cmd so you can Ctl-C the build or run) # Files generated through docker (use $cmd so you can Ctl-C the build or run)
$cmd docker build --tag generate:$GOOS $GOOS $cmd docker build --tag generate:$GOOS $GOOS
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS
exit exit
fi fi
@ -73,12 +73,12 @@ aix_ppc64)
darwin_amd64) darwin_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go" mkasm="go run mkasm.go"
;; ;;
darwin_arm64) darwin_arm64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go" mkasm="go run mkasm.go"
;; ;;
dragonfly_amd64) dragonfly_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
@ -89,25 +89,30 @@ dragonfly_amd64)
freebsd_386) freebsd_386)
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32" mksyscall="go run mksyscall.go -l32"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
freebsd_amd64) freebsd_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
freebsd_arm) freebsd_arm)
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -arm" mksyscall="go run mksyscall.go -l32 -arm"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
# Let the type of C char be signed for making the bare syscall # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;; ;;
freebsd_arm64) freebsd_arm64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
freebsd_riscv64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;; ;;
netbsd_386) netbsd_386)
@ -137,42 +142,60 @@ netbsd_arm64)
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_386) openbsd_386)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32 -openbsd" mksyscall="go run mksyscall.go -l32 -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
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" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_amd64) openbsd_amd64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd" mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
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" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_arm) openbsd_arm)
mkasm="go run mkasm.go"
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -openbsd -arm" mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
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 # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;; ;;
openbsd_arm64) openbsd_arm64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd" mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
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 # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;; ;;
openbsd_mips64) openbsd_mips64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd" mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
# 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_ppc64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
# 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_riscv64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
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 # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
@ -209,11 +232,6 @@ esac
if [ "$GOOSARCH" == "aix_ppc64" ]; then if [ "$GOOSARCH" == "aix_ppc64" ]; then
# aix/ppc64 script generates files instead of writing to stdin. # 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 " ; 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
# 1.12 and later, syscalls via libSystem
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
# 1.13 and later, syscalls via libSystem (including syscallPtr)
echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
elif [ "$GOOS" == "illumos" ]; then elif [ "$GOOS" == "illumos" ]; then
# illumos code generation requires a --illumos switch # illumos code generation requires a --illumos switch
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go"; echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
@ -227,5 +245,5 @@ esac
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; 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"; fi if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi
if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
) | $run ) | $run

View file

@ -54,7 +54,7 @@ includes_AIX='
includes_Darwin=' includes_Darwin='
#define _DARWIN_C_SOURCE #define _DARWIN_C_SOURCE
#define KERNEL #define KERNEL 1
#define _DARWIN_USE_64_BIT_INODE #define _DARWIN_USE_64_BIT_INODE
#define __APPLE_USE_RFC_3542 #define __APPLE_USE_RFC_3542
#include <stdint.h> #include <stdint.h>
@ -66,6 +66,7 @@ includes_Darwin='
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/sockio.h> #include <sys/sockio.h>
#include <sys/sys_domain.h> #include <sys/sys_domain.h>
@ -75,6 +76,7 @@ includes_Darwin='
#include <sys/utsname.h> #include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/xattr.h> #include <sys/xattr.h>
#include <sys/vsock.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
#include <net/if_types.h> #include <net/if_types.h>
@ -82,6 +84,9 @@ includes_Darwin='
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <termios.h> #include <termios.h>
// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk.
#define TIOCREMOTE 0x80047469
' '
includes_DragonFly=' includes_DragonFly='
@ -124,6 +129,7 @@ includes_FreeBSD='
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/ptrace.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
#include <net/if_types.h> #include <net/if_types.h>
@ -198,9 +204,12 @@ struct ltchars {
#include <sys/timerfd.h> #include <sys/timerfd.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/xattr.h> #include <sys/xattr.h>
#include <netinet/udp.h>
#include <linux/audit.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/can.h> #include <linux/can.h>
#include <linux/can/error.h> #include <linux/can/error.h>
#include <linux/can/netlink.h>
#include <linux/can/raw.h> #include <linux/can/raw.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/cryptouser.h> #include <linux/cryptouser.h>
@ -210,6 +219,7 @@ struct ltchars {
#include <linux/ethtool_netlink.h> #include <linux/ethtool_netlink.h>
#include <linux/falloc.h> #include <linux/falloc.h>
#include <linux/fanotify.h> #include <linux/fanotify.h>
#include <linux/fib_rules.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/fscrypt.h> #include <linux/fscrypt.h>
@ -227,6 +237,7 @@ struct ltchars {
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <linux/if_xdp.h> #include <linux/if_xdp.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/kcm.h>
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/keyctl.h> #include <linux/keyctl.h>
#include <linux/landlock.h> #include <linux/landlock.h>
@ -235,6 +246,7 @@ struct ltchars {
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/memfd.h> #include <linux/memfd.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mount.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/net_namespace.h> #include <linux/net_namespace.h>
@ -256,6 +268,7 @@ struct ltchars {
#include <linux/vm_sockets.h> #include <linux/vm_sockets.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
#include <linux/wireguard.h>
#include <mtd/ubi-user.h> #include <mtd/ubi-user.h>
#include <mtd/mtd-user.h> #include <mtd/mtd-user.h>
@ -286,6 +299,10 @@ struct ltchars {
#define SOL_NETLINK 270 #define SOL_NETLINK 270
#endif #endif
#ifndef SOL_SMC
#define SOL_SMC 286
#endif
#ifdef SOL_BLUETOOTH #ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go // but it is already in bluetooth_linux.go
@ -466,7 +483,6 @@ ccflags="$@"
$2 !~ /^EQUIV_/ && $2 !~ /^EQUIV_/ &&
$2 !~ /^EXPR_/ && $2 !~ /^EXPR_/ &&
$2 !~ /^EVIOC/ && $2 !~ /^EVIOC/ &&
$2 !~ /^EV_/ &&
$2 ~ /^E[A-Z0-9_]+$/ || $2 ~ /^E[A-Z0-9_]+$/ ||
$2 ~ /^B[0-9_]+$/ || $2 ~ /^B[0-9_]+$/ ||
$2 ~ /^(OLD|NEW)DEV$/ || $2 ~ /^(OLD|NEW)DEV$/ ||
@ -498,14 +514,16 @@ ccflags="$@"
$2 ~ /^O?XTABS$/ || $2 ~ /^O?XTABS$/ ||
$2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ || $2 ~ /^IN_/ ||
$2 ~ /^KCM/ ||
$2 ~ /^LANDLOCK_/ || $2 ~ /^LANDLOCK_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT)_/ || $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
$2 ~ /^RAW_PAYLOAD_/ || $2 ~ /^RAW_PAYLOAD_/ ||
$2 ~ /^[US]F_/ ||
$2 ~ /^TP_STATUS_/ || $2 ~ /^TP_STATUS_/ ||
$2 ~ /^FALLOC_/ || $2 ~ /^FALLOC_/ ||
$2 ~ /^ICMPV?6?_(FILTER|SEC)/ || $2 ~ /^ICMPV?6?_(FILTER|SEC)/ ||
@ -517,10 +535,10 @@ ccflags="$@"
$2 ~ /^HW_MACHINE$/ || $2 ~ /^HW_MACHINE$/ ||
$2 ~ /^SYSCTL_VERS/ || $2 ~ /^SYSCTL_VERS/ ||
$2 !~ "MNT_BITS" && $2 !~ "MNT_BITS" &&
$2 ~ /^(MS|MNT|UMOUNT)_/ || $2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ ||
$2 ~ /^NS_GET_/ || $2 ~ /^NS_GET_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ || $2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|PIOD|TFD)_/ ||
$2 ~ /^KEXEC_/ || $2 ~ /^KEXEC_/ ||
$2 ~ /^LINUX_REBOOT_CMD_/ || $2 ~ /^LINUX_REBOOT_CMD_/ ||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
@ -544,6 +562,7 @@ ccflags="$@"
$2 ~ /^CLONE_[A-Z_]+/ || $2 ~ /^CLONE_[A-Z_]+/ ||
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ && $2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
$2 ~ /^(BPF|DLT)_/ || $2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^AUDIT_/ ||
$2 ~ /^(CLOCK|TIMER)_/ || $2 ~ /^(CLOCK|TIMER)_/ ||
$2 ~ /^CAN_/ || $2 ~ /^CAN_/ ||
$2 ~ /^CAP_/ || $2 ~ /^CAP_/ ||
@ -564,9 +583,9 @@ ccflags="$@"
$2 ~ /^PERF_/ || $2 ~ /^PERF_/ ||
$2 ~ /^SECCOMP_MODE_/ || $2 ~ /^SECCOMP_MODE_/ ||
$2 ~ /^SEEK_/ || $2 ~ /^SEEK_/ ||
$2 ~ /^SCHED_/ ||
$2 ~ /^SPLICE_/ || $2 ~ /^SPLICE_/ ||
$2 ~ /^SYNC_FILE_RANGE_/ || $2 ~ /^SYNC_FILE_RANGE_/ ||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
$2 !~ /IOC_MAGIC/ && $2 !~ /IOC_MAGIC/ &&
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || $2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
$2 ~ /^(VM|VMADDR)_/ || $2 ~ /^(VM|VMADDR)_/ ||
@ -592,8 +611,10 @@ ccflags="$@"
$2 ~ /^DEVLINK_/ || $2 ~ /^DEVLINK_/ ||
$2 ~ /^ETHTOOL_/ || $2 ~ /^ETHTOOL_/ ||
$2 ~ /^LWTUNNEL_IP/ || $2 ~ /^LWTUNNEL_IP/ ||
$2 ~ /^ITIMER_/ ||
$2 !~ "WMESGLEN" && $2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ || $2 ~ /^W[A-Z0-9]+$/ ||
$2 ~ /^P_/ ||
$2 ~/^PPPIOC/ || $2 ~/^PPPIOC/ ||
$2 ~ /^FAN_|FANOTIFY_/ || $2 ~ /^FAN_|FANOTIFY_/ ||
$2 == "HID_MAX_DESCRIPTOR_SIZE" || $2 == "HID_MAX_DESCRIPTOR_SIZE" ||
@ -602,7 +623,9 @@ ccflags="$@"
$2 ~ /^MTD/ || $2 ~ /^MTD/ ||
$2 ~ /^OTP/ || $2 ~ /^OTP/ ||
$2 ~ /^MEM/ || $2 ~ /^MEM/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^WG/ ||
$2 ~ /^FIB_RULE_/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE|IOMIN$|IOOPT$|ALIGNOFF$|DISCARD|ROTATIONAL$|ZEROOUT$|GETDISKSEQ$)/ {printf("\t%s = C.%s\n", $2, $2)}
$2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__WCOREFLAG$/ {next}
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
@ -623,7 +646,7 @@ errors=$(
signals=$( signals=$(
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
sort sort
) )
@ -633,7 +656,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
sort >_error.grep sort >_error.grep
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
sort >_signal.grep sort >_signal.grep
echo '// mkerrors.sh' "$@" echo '// mkerrors.sh' "$@"
@ -719,7 +742,8 @@ main(void)
e = errors[i].num; e = errors[i].num;
if(i > 0 && errors[i-1].num == e) if(i > 0 && errors[i-1].num == e)
continue; continue;
strcpy(buf, strerror(e)); strncpy(buf, strerror(e), sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
// lowercase first letter: Bad -> bad, but STREAM -> STREAM. // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
buf[0] += a - A; buf[0] += a - A;
@ -738,7 +762,8 @@ main(void)
e = signals[i].num; e = signals[i].num;
if(i > 0 && signals[i-1].num == e) if(i > 0 && signals[i-1].num == e)
continue; continue;
strcpy(buf, strsignal(e)); strncpy(buf, strsignal(e), sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
// lowercase first letter: Bad -> bad, but STREAM -> STREAM. // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
buf[0] += a - A; buf[0] += a - A;

14
vendor/golang.org/x/sys/unix/mmap_nomremap.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
// +build aix darwin dragonfly freebsd openbsd solaris
package unix
var mapper = &mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
}

53
vendor/golang.org/x/sys/unix/mremap.go generated vendored Normal file
View file

@ -0,0 +1,53 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build linux || netbsd
// +build linux netbsd
package unix
import "unsafe"
type mremapMmapper struct {
mmapper
mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
}
var mapper = &mremapMmapper{
mmapper: mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
},
mremap: mremap,
}
func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 {
return nil, EINVAL
}
pOld := &oldData[cap(oldData)-1]
m.Lock()
defer m.Unlock()
bOld := m.active[pOld]
if bOld == nil || &bOld[0] != &oldData[0] {
return nil, EINVAL
}
newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0)
if errno != nil {
return nil, errno
}
bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)
pNew := &bNew[cap(bNew)-1]
if flags&mremapDontunmap == 0 {
delete(m.active, pOld)
}
m.active[pNew] = bNew
return bNew, nil
}
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
return mapper.Mremap(oldData, newLength, flags)
}

View file

@ -7,6 +7,12 @@
package unix package unix
import "unsafe"
func ptrace(request int, pid int, addr uintptr, data uintptr) error { func ptrace(request int, pid int, addr uintptr, data uintptr) error {
return ptrace1(request, pid, addr, data) return ptrace1(request, pid, addr, data)
} }
func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) error {
return ptrace1Ptr(request, pid, addr, data)
}

View file

@ -7,6 +7,12 @@
package unix package unix
import "unsafe"
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
return ENOTSUP return ENOTSUP
} }
func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) {
return ENOTSUP
}

View file

@ -34,3 +34,52 @@ func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0])) ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
return &ucred, nil return &ucred, nil
} }
// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
func PktInfo4(info *Inet4Pktinfo) []byte {
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_IP
h.Type = IP_PKTINFO
h.SetLen(CmsgLen(SizeofInet4Pktinfo))
*(*Inet4Pktinfo)(h.data(0)) = *info
return b
}
// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
func PktInfo6(info *Inet6Pktinfo) []byte {
b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_IPV6
h.Type = IPV6_PKTINFO
h.SetLen(CmsgLen(SizeofInet6Pktinfo))
*(*Inet6Pktinfo)(h.data(0)) = *info
return b
}
// ParseOrigDstAddr decodes a socket control message containing the original
// destination address. To receive such a message the IP_RECVORIGDSTADDR or
// IPV6_RECVORIGDSTADDR option must be enabled on the socket.
func ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) {
switch {
case m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR:
pp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0]))
sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
sa.Addr = pp.Addr
return sa, nil
case m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR:
pp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0]))
sa := new(SockaddrInet6)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id
sa.Addr = pp.Addr
return sa, nil
default:
return nil, EINVAL
}
}

View file

@ -52,6 +52,20 @@ func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
return msgs, nil return msgs, nil
} }
// ParseOneSocketControlMessage parses a single socket control message from b, returning the message header,
// message data (a slice of b), and the remainder of b after that single message.
// When there are no remaining messages, len(remainder) == 0.
func ParseOneSocketControlMessage(b []byte) (hdr Cmsghdr, data []byte, remainder []byte, err error) {
h, dbuf, err := socketControlMessageHeaderAndData(b)
if err != nil {
return Cmsghdr{}, nil, nil, err
}
if i := cmsgAlignOf(int(h.Len)); i < len(b) {
remainder = b[i:]
}
return *h, dbuf, remainder, nil
}
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) { func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
h := (*Cmsghdr)(unsafe.Pointer(&b[0])) h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) { if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {

27
vendor/golang.org/x/sys/unix/str.go generated vendored
View file

@ -1,27 +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.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
if val < 0 {
return "-" + uitoa(uint(-val))
}
return uitoa(uint(val))
}
func uitoa(val uint) string {
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:])
}

View file

@ -29,8 +29,6 @@ import (
"bytes" "bytes"
"strings" "strings"
"unsafe" "unsafe"
"golang.org/x/sys/internal/unsafeheader"
) )
// ByteSliceFromString returns a NUL-terminated slice of bytes // ByteSliceFromString returns a NUL-terminated slice of bytes
@ -82,13 +80,7 @@ func BytePtrToString(p *byte) string {
ptr = unsafe.Pointer(uintptr(ptr) + 1) ptr = unsafe.Pointer(uintptr(ptr) + 1)
} }
var s []byte return string(unsafe.Slice(p, n))
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
h.Data = unsafe.Pointer(p)
h.Len = n
h.Cap = n
return string(s)
} }
// Single-word zero for use when we need a valid pointer to 0 bytes. // Single-word zero for use when we need a valid pointer to 0 bytes.

View file

@ -37,6 +37,7 @@ func Creat(path string, mode uint32) (fd int, err error) {
} }
//sys utimes(path string, times *[2]Timeval) (err error) //sys utimes(path string, times *[2]Timeval) (err error)
func Utimes(path string, tv []Timeval) error { func Utimes(path string, tv []Timeval) error {
if len(tv) != 2 { if len(tv) != 2 {
return EINVAL return EINVAL
@ -45,6 +46,7 @@ func Utimes(path string, tv []Timeval) error {
} }
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
func UtimesNano(path string, ts []Timespec) error { func UtimesNano(path string, ts []Timespec) error {
if len(ts) != 2 { if len(ts) != 2 {
return EINVAL return EINVAL
@ -70,9 +72,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
} }
@ -85,9 +85,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
} }
@ -219,20 +217,63 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
return return
} }
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
// Recvmsg not implemented on AIX var msg Msghdr
sa := new(SockaddrUnix) msg.Name = (*byte)(unsafe.Pointer(rsa))
return -1, -1, -1, sa, ENOSYS msg.Namelen = uint32(SizeofSockaddrAny)
var dummy byte
if len(oob) > 0 {
// receive at least one normal byte
if emptyIovecs(iov) {
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { msg.SetControllen(len(oob))
_, err = SendmsgN(fd, p, oob, to, flags) }
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); n == -1 {
return
}
oobn = int(msg.Controllen)
recvflags = int(msg.Flags)
return return
} }
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
// SendmsgN not implemented on AIX var msg Msghdr
return -1, ENOSYS msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen)
var dummy byte
var empty bool
if len(oob) > 0 {
// send at least one normal byte
empty = emptyIovecs(iov)
if empty {
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
}
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.SetControllen(len(oob))
}
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err
}
if len(oob) > 0 && empty {
n = 0
}
return n, nil
} }
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
@ -251,9 +292,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
break break
} }
} }
sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
sa.Name = string(bytes)
return sa, nil return sa, nil
case AF_INET: case AF_INET:
@ -261,9 +300,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_INET6: case AF_INET6:
@ -272,9 +309,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT
@ -314,11 +349,13 @@ func direntNamlen(buf []byte) (uint64, bool) {
} }
//sys getdirent(fd int, buf []byte) (n int, err error) //sys getdirent(fd int, buf []byte) (n int, err error)
func Getdents(fd int, buf []byte) (n int, err error) { func Getdents(fd int, buf []byte) (n int, err error) {
return getdirent(fd, buf) return getdirent(fd, buf)
} }
//sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error) //sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error)
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
var status _C_int var status _C_int
var r Pid_t var r Pid_t
@ -371,7 +408,8 @@ func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 }
func (w WaitStatus) TrapCause() int { return -1 } func (w WaitStatus) TrapCause() int { return -1 }
//sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctl(fd int, req int, arg uintptr) (err error)
//sys ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = ioctl
// fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX // fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX
// There is no way to create a custom fcntl and to keep //sys fcntl easily, // There is no way to create a custom fcntl and to keep //sys fcntl easily,
@ -385,6 +423,12 @@ func (w WaitStatus) TrapCause() int { return -1 }
//sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range
func Fsync(fd int) error {
return fsyncRange(fd, O_SYNC, 0, 0)
}
/* /*
* Direct access * Direct access
*/ */
@ -401,7 +445,6 @@ func (w WaitStatus) TrapCause() int { return -1 }
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Fdatasync(fd int) (err error) //sys Fdatasync(fd int) (err error)
//sys Fsync(fd int) (err error)
// readdir_r // readdir_r
//sysnb Getpgid(pid int) (pgid int, err error) //sysnb Getpgid(pid int) (pgid int, err error)
@ -462,8 +505,8 @@ func (w WaitStatus) TrapCause() int { return -1 }
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys lstat(path string, stat *Stat_t) (err error) //sys lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error) //sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64 //sys pread(fd int, p []byte, offset int64) (n int, err error) = pread64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 //sys pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
@ -492,21 +535,6 @@ func (w WaitStatus) TrapCause() int { return -1 }
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg
//sys munmap(addr uintptr, length uintptr) (err error) //sys munmap(addr uintptr, length uintptr) (err error)
var mapper = &mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
}
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
return mapper.Mmap(fd, offset, length, prot, flags)
}
func Munmap(b []byte) (err error) {
return mapper.Munmap(b)
}
//sys Madvise(b []byte, advice int) (err error) //sys Madvise(b []byte, advice int) (err error)
//sys Mprotect(b []byte, prot int) (err error) //sys Mprotect(b []byte, prot int) (err error)
//sys Mlock(b []byte) (err error) //sys Mlock(b []byte) (err error)
@ -523,8 +551,10 @@ func Pipe(p []int) (err error) {
} }
var pp [2]_C_int var pp [2]_C_int
err = pipe(&pp) err = pipe(&pp)
if err == nil {
p[0] = int(pp[0]) p[0] = int(pp[0])
p[1] = int(pp[1]) p[1] = int(pp[1])
}
return return
} }
@ -544,6 +574,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
//sys Getsystemcfg(label int) (n uint64) //sys Getsystemcfg(label int) (n uint64)
//sys umount(target string) (err error) //sys umount(target string) (err error)
func Unmount(target string, flags int) (err error) { func Unmount(target string, flags int) (err error) {
if flags != 0 { if flags != 0 {
// AIX doesn't have any flags for umount. // AIX doesn't have any flags for umount.

View file

@ -8,7 +8,6 @@
package unix package unix
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = getrlimit64 //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = getrlimit64
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) = setrlimit64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek64 //sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek64
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)

View file

@ -8,7 +8,6 @@
package unix package unix
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) //sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek //sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) = mmap64 //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) = mmap64

View file

@ -163,9 +163,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
} }
@ -179,9 +177,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
} }
@ -210,9 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Nlen = sa.Nlen sa.raw.Nlen = sa.Nlen
sa.raw.Alen = sa.Alen sa.raw.Alen = sa.Alen
sa.raw.Slen = sa.Slen sa.raw.Slen = sa.Slen
for i := 0; i < len(sa.raw.Data); i++ { sa.raw.Data = sa.Data
sa.raw.Data[i] = sa.Data[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
} }
@ -228,9 +222,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Nlen = pp.Nlen sa.Nlen = pp.Nlen
sa.Alen = pp.Alen sa.Alen = pp.Alen
sa.Slen = pp.Slen sa.Slen = pp.Slen
for i := 0; i < len(sa.Data); i++ { sa.Data = pp.Data
sa.Data[i] = pp.Data[i]
}
return sa, nil return sa, nil
case AF_UNIX: case AF_UNIX:
@ -253,8 +245,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
break break
} }
} }
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
sa.Name = string(bytes)
return sa, nil return sa, nil
case AF_INET: case AF_INET:
@ -262,9 +253,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_INET6: case AF_INET6:
@ -273,9 +262,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
return anyToSockaddrGOOS(fd, rsa) return anyToSockaddrGOOS(fd, rsa)
@ -337,80 +324,62 @@ func GetsockoptString(fd, level, opt int) (string, error) {
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr var msg Msghdr
var rsa RawSockaddrAny msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Namelen = uint32(SizeofSockaddrAny) msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
iov.SetLen(len(p))
}
var dummy byte var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
// receive at least one normal byte // receive at least one normal byte
if len(p) == 0 { if emptyIovecs(iov) {
iov.Base = &dummy var iova [1]Iovec
iov.SetLen(1) iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); err != nil { if n, err = recvmsg(fd, &msg, flags); err != nil {
return return
} }
oobn = int(msg.Controllen) oobn = int(msg.Controllen)
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return return
} }
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
var msg Msghdr var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr)) msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen) msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
iov.SetLen(len(p))
}
var dummy byte var dummy byte
var empty bool
if len(oob) > 0 { if len(oob) > 0 {
// send at least one normal byte // send at least one normal byte
if len(p) == 0 { empty = emptyIovecs(iov)
iov.Base = &dummy if empty {
iov.SetLen(1) var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil { if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err return 0, err
} }
if len(oob) > 0 && len(p) == 0 { if len(oob) > 0 && empty {
n = 0 n = 0
} }
return n, nil return n, nil
@ -583,12 +552,7 @@ func UtimesNano(path string, ts []Timespec) error {
if len(ts) != 2 { if len(ts) != 2 {
return EINVAL return EINVAL
} }
// Darwin setattrlist can set nanosecond timestamps err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
err := setattrlistTimes(path, ts, 0)
if err != ENOSYS {
return err
}
err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -608,10 +572,6 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
if len(ts) != 2 { if len(ts) != 2 {
return EINVAL return EINVAL
} }
err := setattrlistTimes(path, ts, flags)
if err != ENOSYS {
return err
}
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
} }
@ -641,20 +601,6 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
// Gethostuuid(uuid *byte, timeout *Timespec) (err error) // Gethostuuid(uuid *byte, timeout *Timespec) (err error)
// Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
var mapper = &mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
}
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
return mapper.Mmap(fd, offset, length, prot, flags)
}
func Munmap(b []byte) (err error) {
return mapper.Munmap(b)
}
//sys Madvise(b []byte, behav int) (err error) //sys Madvise(b []byte, behav int) (err error)
//sys Mlock(b []byte) (err error) //sys Mlock(b []byte) (err error)
//sys Mlockall(flags int) (err error) //sys Mlockall(flags int) (err error)

View file

@ -1,32 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && go1.12 && !go1.13
// +build darwin,go1.12,!go1.13
package unix
import (
"unsafe"
)
const _SYS_GETDIRENTRIES64 = 344
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// To implement this using libSystem we'd need syscall_syscallPtr for
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
// back to raw syscalls for this func on Go 1.12.
var p unsafe.Pointer
if len(buf) > 0 {
p = unsafe.Pointer(&buf[0])
} else {
p = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
return n, errnoErr(e1)
}
return n, nil
}

View file

@ -1,108 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && go1.13
// +build darwin,go1.13
package unix
import (
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
//sys closedir(dir uintptr) (err error)
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
func fdopendir(fd int) (dir uintptr, err error) {
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
dir = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fdopendir_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
// We store the number of entries to skip in the seek
// offset of fd. See issue #31368.
// It's not the full required semantics, but should handle the case
// of calling Getdirentries or ReadDirent repeatedly.
// It won't handle assigning the results of lseek to *basep, or handle
// the directory being edited underfoot.
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
if err != nil {
return 0, err
}
// We need to duplicate the incoming file descriptor
// because the caller expects to retain control of it, but
// fdopendir expects to take control of its argument.
// Just Dup'ing the file descriptor is not enough, as the
// result shares underlying state. Use Openat to make a really
// new file descriptor referring to the same directory.
fd2, err := Openat(fd, ".", O_RDONLY, 0)
if err != nil {
return 0, err
}
d, err := fdopendir(fd2)
if err != nil {
Close(fd2)
return 0, err
}
defer closedir(d)
var cnt int64
for {
var entry Dirent
var entryp *Dirent
e := readdir_r(d, &entry, &entryp)
if e != 0 {
return n, errnoErr(e)
}
if entryp == nil {
break
}
if skip > 0 {
skip--
cnt++
continue
}
reclen := int(entry.Reclen)
if reclen > len(buf) {
// Not enough room. Return for now.
// The counter will let us know where we should start up again.
// Note: this strategy for suspending in the middle and
// restarting is O(n^2) in the length of the directory. Oh well.
break
}
// Copy entry into return buffer.
var s []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
hdr.Data = unsafe.Pointer(&entry)
hdr.Cap = reclen
hdr.Len = reclen
copy(buf, s)
buf = buf[reclen:]
n += reclen
cnt++
}
// Set the seek offset of the input fd to record
// how many files we've already returned.
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
if err != nil {
return n, err
}
return n, nil
}

View file

@ -14,11 +14,100 @@ package unix
import ( import (
"fmt" "fmt"
"runtime"
"syscall" "syscall"
"unsafe" "unsafe"
) )
//sys closedir(dir uintptr) (err error)
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
func fdopendir(fd int) (dir uintptr, err error) {
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
dir = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fdopendir_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
// We store the number of entries to skip in the seek
// offset of fd. See issue #31368.
// It's not the full required semantics, but should handle the case
// of calling Getdirentries or ReadDirent repeatedly.
// It won't handle assigning the results of lseek to *basep, or handle
// the directory being edited underfoot.
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
if err != nil {
return 0, err
}
// We need to duplicate the incoming file descriptor
// because the caller expects to retain control of it, but
// fdopendir expects to take control of its argument.
// Just Dup'ing the file descriptor is not enough, as the
// result shares underlying state. Use Openat to make a really
// new file descriptor referring to the same directory.
fd2, err := Openat(fd, ".", O_RDONLY, 0)
if err != nil {
return 0, err
}
d, err := fdopendir(fd2)
if err != nil {
Close(fd2)
return 0, err
}
defer closedir(d)
var cnt int64
for {
var entry Dirent
var entryp *Dirent
e := readdir_r(d, &entry, &entryp)
if e != 0 {
return n, errnoErr(e)
}
if entryp == nil {
break
}
if skip > 0 {
skip--
cnt++
continue
}
reclen := int(entry.Reclen)
if reclen > len(buf) {
// Not enough room. Return for now.
// The counter will let us know where we should start up again.
// Note: this strategy for suspending in the middle and
// restarting is O(n^2) in the length of the directory. Oh well.
break
}
// Copy entry into return buffer.
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
copy(buf, s)
buf = buf[reclen:]
n += reclen
cnt++
}
// Set the seek offset of the input fd to record
// how many files we've already returned.
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
if err != nil {
return n, err
}
return n, nil
}
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
@ -48,6 +137,30 @@ func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
} }
// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables
// bidirectional communication between a hypervisor and its guest virtual
// machines.
type SockaddrVM struct {
// CID and Port specify a context ID and port address for a VM socket.
// Guests have a unique CID, and hosts may have a well-known CID of:
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
// - VMADDR_CID_LOCAL: refers to local communication (loopback).
// - VMADDR_CID_HOST: refers to other processes on the host.
CID uint32
Port uint32
raw RawSockaddrVM
}
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Len = SizeofSockaddrVM
sa.raw.Family = AF_VSOCK
sa.raw.Port = sa.Port
sa.raw.Cid = sa.CID
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
}
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_SYSTEM: case AF_SYSTEM:
@ -58,6 +171,13 @@ func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Unit = pp.Sc_unit sa.Unit = pp.Sc_unit
return sa, nil return sa, nil
} }
case AF_VSOCK:
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
sa := &SockaddrVM{
CID: pp.Cid,
Port: pp.Port,
}
return sa, nil
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT
} }
@ -109,16 +229,7 @@ func direntNamlen(buf []byte) (uint64, bool) {
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
func PtraceDenyAttach() (err error) { return ptrace(PT_DENY_ATTACH, 0, 0, 0) }
type attrList struct {
bitmapCount uint16
_ uint16
CommonAttr uint32
VolAttr uint32
DirAttr uint32
FileAttr uint32
Forkattr uint32
}
//sysnb pipe(p *[2]int32) (err error) //sysnb pipe(p *[2]int32) (err error)
@ -128,8 +239,10 @@ func Pipe(p []int) (err error) {
} }
var x [2]int32 var x [2]int32
err = pipe(&x) err = pipe(&x)
if err == nil {
p[0] = int(x[0]) p[0] = int(x[0])
p[1] = int(x[1]) p[1] = int(x[1])
}
return return
} }
@ -249,36 +362,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) {
return flistxattr(fd, xattrPointer(dest), len(dest), 0) return flistxattr(fd, xattrPointer(dest), len(dest), 0)
} }
func setattrlistTimes(path string, times []Timespec, flags int) error { //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
_p0, err := BytePtrFromString(path)
if err != nil {
return err
}
var attrList attrList
attrList.bitmapCount = ATTR_BIT_MAP_COUNT
attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME
// order is mtime, atime: the opposite of Chtimes
attributes := [2]Timespec{times[1], times[0]}
options := 0
if flags&AT_SYMLINK_NOFOLLOW != 0 {
options |= FSOPT_NOFOLLOW
}
return setattrlist(
_p0,
unsafe.Pointer(&attrList),
unsafe.Pointer(&attributes),
unsafe.Sizeof(attributes),
options)
}
//sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
// Darwin doesn't support SYS_UTIMENSAT
return ENOSYS
}
/* /*
* Wrapped * Wrapped
@ -291,11 +375,10 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) } func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
//sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctl(fd int, req uint, arg uintptr) (err error)
//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL
func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error { func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error {
err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo))) return ioctlPtr(fd, CTLIOCGINFO, unsafe.Pointer(ctlInfo))
runtime.KeepAlive(ctlInfo)
return err
} }
// IfreqMTU is struct ifreq used to get or set a network device's MTU. // IfreqMTU is struct ifreq used to get or set a network device's MTU.
@ -309,16 +392,14 @@ type IfreqMTU struct {
func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) { func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) {
var ifreq IfreqMTU var ifreq IfreqMTU
copy(ifreq.Name[:], ifname) copy(ifreq.Name[:], ifname)
err := ioctl(fd, SIOCGIFMTU, uintptr(unsafe.Pointer(&ifreq))) err := ioctlPtr(fd, SIOCGIFMTU, unsafe.Pointer(&ifreq))
return &ifreq, err return &ifreq, err
} }
// IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU // IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU
// of the network device specified by ifreq.Name. // of the network device specified by ifreq.Name.
func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error { func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error {
err := ioctl(fd, SIOCSIFMTU, uintptr(unsafe.Pointer(ifreq))) return ioctlPtr(fd, SIOCSIFMTU, unsafe.Pointer(ifreq))
runtime.KeepAlive(ifreq)
return err
} }
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
@ -399,12 +480,37 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
return x, err return x, err
} }
func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) { func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) {
mib, err := sysctlmib(name) var value TCPConnectionInfo
vallen := _Socklen(SizeofTCPConnectionInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
mib, err := sysctlmib(name, args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var kinfo KinfoProc
n := uintptr(SizeofKinfoProc)
if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {
return nil, err
}
if n != SizeofKinfoProc {
return nil, EIO
}
return &kinfo, nil
}
func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
mib, err := sysctlmib(name, args...)
if err != nil {
return nil, err
}
for {
// Find size. // Find size.
n := uintptr(0) n := uintptr(0)
if err := sysctl(mib, nil, &n, nil, 0); err != nil { if err := sysctl(mib, nil, &n, nil, 0); err != nil {
@ -420,6 +526,10 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
// Read into buffer of that size. // Read into buffer of that size.
buf := make([]KinfoProc, n/SizeofKinfoProc) buf := make([]KinfoProc, n/SizeofKinfoProc)
if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
if err == ENOMEM {
// Process table grew. Try again.
continue
}
return nil, err return nil, err
} }
if n%SizeofKinfoProc != 0 { if n%SizeofKinfoProc != 0 {
@ -430,9 +540,15 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
// size so ensure we deal with that. // size so ensure we deal with that.
return buf[:n/SizeofKinfoProc], nil return buf[:n/SizeofKinfoProc], nil
} }
}
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
//sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error)
/* /*
* Exposed directly * Exposed directly
*/ */
@ -488,11 +604,12 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
//sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error) //sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error) //sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n 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 pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
@ -502,6 +619,7 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys Setattrlist(path string, attrlist *Attrlist, attrBuf []byte, options int) (err error)
//sys Setegid(egid int) (err error) //sys Setegid(egid int) (err error)
//sysnb Seteuid(euid int) (err error) //sysnb Seteuid(euid int) (err error)
//sysnb Setgid(gid int) (err error) //sysnb Setgid(gid int) (err error)
@ -511,7 +629,6 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
//sys Setprivexec(flag int) (err error) //sys Setprivexec(flag int) (err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error)
//sysnb Setrlimit(which int, lim *Rlimit) (err error)
//sysnb Setsid() (pid int, err error) //sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tp *Timeval) (err error) //sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error) //sysnb Setuid(uid int) (err error)
@ -556,7 +673,6 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
// Nfssvc // Nfssvc
// Getfh // Getfh
// Quotactl // Quotactl
// Mount
// Csops // Csops
// Waitid // Waitid
// Add_profil // Add_profil
@ -566,7 +682,6 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
// Kqueue_from_portset_np // Kqueue_from_portset_np
// Kqueue_portset // Kqueue_portset
// Getattrlist // Getattrlist
// Setattrlist
// Getdirentriesattr // Getdirentriesattr
// Searchfs // Searchfs
// Delete // Delete
@ -590,10 +705,6 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
// Msgget // Msgget
// Msgsnd // Msgsnd
// Msgrcv // Msgrcv
// Shmat
// Shmctl
// Shmdt
// Shmget
// Shm_open // Shm_open
// Shm_unlink // Shm_unlink
// Sem_open // Sem_open

View file

@ -47,5 +47,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace //sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
//sys ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) = SYS_ptrace
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64

View file

@ -47,5 +47,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace //sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
//sys ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) = SYS_ptrace
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error)

View file

@ -101,7 +101,10 @@ func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
} }
p[0], p[1], err = pipe() r, w, err := pipe()
if err == nil {
p[0], p[1] = r, w
}
return return
} }
@ -114,17 +117,22 @@ func Pipe2(p []int, flags int) (err error) {
var pp [2]_C_int var pp [2]_C_int
// pipe2 on dragonfly takes an fds array as an argument, but still // pipe2 on dragonfly takes an fds array as an argument, but still
// returns the file descriptors. // returns the file descriptors.
p[0], p[1], err = pipe2(&pp, flags) r, w, err := pipe2(&pp, flags)
if err == nil {
p[0], p[1] = r, w
}
return err return err
} }
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error) //sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
return extpread(fd, p, 0, offset) return extpread(fd, p, 0, offset)
} }
//sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) //sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error)
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
return extpwrite(fd, p, 0, offset) return extpwrite(fd, p, 0, offset)
} }
@ -163,12 +171,8 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
return return
} }
func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
//sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctl(fd int, req uint, arg uintptr) (err error)
//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
@ -252,6 +256,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Chmod(path string, mode uint32) (err error) //sys Chmod(path string, mode uint32) (err error)
//sys Chown(path string, uid int, gid int) (err error) //sys Chown(path string, uid int, gid int) (err error)
//sys Chroot(path string) (err error) //sys Chroot(path string) (err error)
//sys ClockGettime(clockid int32, time *Timespec) (err error)
//sys Close(fd int) (err error) //sys Close(fd int) (err error)
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
@ -321,7 +326,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(which int, lim *Rlimit) (err error)
//sysnb Setsid() (pid int, err error) //sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tp *Timeval) (err error) //sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error) //sysnb Setuid(uid int) (err error)

View file

@ -17,25 +17,12 @@ import (
"unsafe" "unsafe"
) )
const (
SYS_FSTAT_FREEBSD12 = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
SYS_FSTATAT_FREEBSD12 = 552 // { int fstatat(int fd, _In_z_ char *path, \
SYS_GETDIRENTRIES_FREEBSD12 = 554 // { ssize_t getdirentries(int fd, \
SYS_STATFS_FREEBSD12 = 555 // { int statfs(_In_z_ char *path, \
SYS_FSTATFS_FREEBSD12 = 556 // { int fstatfs(int fd, \
SYS_GETFSSTAT_FREEBSD12 = 557 // { int getfsstat( \
SYS_MKNODAT_FREEBSD12 = 559 // { int mknodat(int fd, _In_z_ char *path, \
)
// See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html. // See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html.
var ( var (
osreldateOnce sync.Once osreldateOnce sync.Once
osreldate uint32 osreldate uint32
) )
// INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h
const _ino64First = 1200031
func supportsABI(ver uint32) bool { func supportsABI(ver uint32) bool {
osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") }) osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
return osreldate >= ver return osreldate >= ver
@ -110,8 +97,10 @@ func Pipe2(p []int, flags int) error {
} }
var pp [2]_C_int var pp [2]_C_int
err := pipe2(&pp, flags) err := pipe2(&pp, flags)
if err == nil {
p[0] = int(pp[0]) p[0] = int(pp[0])
p[1] = int(pp[1]) p[1] = int(pp[1])
}
return err return err
} }
@ -159,45 +148,21 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
var ( var (
_p0 unsafe.Pointer _p0 unsafe.Pointer
bufsize uintptr bufsize uintptr
oldBuf []statfs_freebsd11_t
needsConvert bool
) )
if len(buf) > 0 { if len(buf) > 0 {
if supportsABI(_ino64First) {
_p0 = unsafe.Pointer(&buf[0]) _p0 = unsafe.Pointer(&buf[0])
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
} else {
n := len(buf)
oldBuf = make([]statfs_freebsd11_t, n)
_p0 = unsafe.Pointer(&oldBuf[0])
bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n)
needsConvert = true
} }
} r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
var sysno uintptr = SYS_GETFSSTAT
if supportsABI(_ino64First) {
sysno = SYS_GETFSSTAT_FREEBSD12
}
r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags))
n = int(r0) n = int(r0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }
if e1 == 0 && needsConvert {
for i := range oldBuf {
buf[i].convertFrom(&oldBuf[i])
}
}
return return
} }
func setattrlistTimes(path string, times []Timespec, flags int) error { //sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL
// used on Darwin for UtimesNano //sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL
return ENOSYS
}
//sys ioctl(fd int, req uint, arg uintptr) (err error)
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
@ -248,87 +213,11 @@ func Uname(uname *Utsname) error {
} }
func Stat(path string, st *Stat_t) (err error) { func Stat(path string, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t return Fstatat(AT_FDCWD, path, st, 0)
if supportsABI(_ino64First) {
return fstatat_freebsd12(AT_FDCWD, path, st, 0)
}
err = stat(path, &oldStat)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
} }
func Lstat(path string, st *Stat_t) (err error) { func Lstat(path string, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t return Fstatat(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
if supportsABI(_ino64First) {
return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
}
err = lstat(path, &oldStat)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
}
func Fstat(fd int, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t
if supportsABI(_ino64First) {
return fstat_freebsd12(fd, st)
}
err = fstat(fd, &oldStat)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
}
func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) {
var oldStat stat_freebsd11_t
if supportsABI(_ino64First) {
return fstatat_freebsd12(fd, path, st, flags)
}
err = fstatat(fd, path, &oldStat, flags)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
}
func Statfs(path string, st *Statfs_t) (err error) {
var oldStatfs statfs_freebsd11_t
if supportsABI(_ino64First) {
return statfs_freebsd12(path, st)
}
err = statfs(path, &oldStatfs)
if err != nil {
return err
}
st.convertFrom(&oldStatfs)
return nil
}
func Fstatfs(fd int, st *Statfs_t) (err error) {
var oldStatfs statfs_freebsd11_t
if supportsABI(_ino64First) {
return fstatfs_freebsd12(fd, st)
}
err = fstatfs(fd, &oldStatfs)
if err != nil {
return err
}
st.convertFrom(&oldStatfs)
return nil
} }
func Getdents(fd int, buf []byte) (n int, err error) { func Getdents(fd int, buf []byte) (n int, err error) {
@ -336,14 +225,13 @@ func Getdents(fd int, buf []byte) (n int, err error) {
} }
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
if supportsABI(_ino64First) {
if basep == nil || unsafe.Sizeof(*basep) == 8 { if basep == nil || unsafe.Sizeof(*basep) == 8 {
return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep))) return getdirentries(fd, buf, (*uint64)(unsafe.Pointer(basep)))
} }
// The freebsd12 syscall needs a 64-bit base. On 32-bit machines // The syscall needs a 64-bit base. On 32-bit machines
// we can't just use the basep passed in. See #32498. // we can't just use the basep passed in. See #32498.
var base uint64 = uint64(*basep) var base uint64 = uint64(*basep)
n, err = getdirentries_freebsd12(fd, buf, &base) n, err = getdirentries(fd, buf, &base)
*basep = uintptr(base) *basep = uintptr(base)
if base>>32 != 0 { if base>>32 != 0 {
// We can't stuff the base back into a uintptr, so any // We can't stuff the base back into a uintptr, so any
@ -354,144 +242,8 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
return return
} }
// The old syscall entries are smaller than the new. Use 1/4 of the original
// buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c).
oldBufLen := roundup(len(buf)/4, _dirblksiz)
oldBuf := make([]byte, oldBufLen)
n, err = getdirentries(fd, oldBuf, basep)
if err == nil && n > 0 {
n = convertFromDirents11(buf, oldBuf[:n])
}
return
}
func Mknod(path string, mode uint32, dev uint64) (err error) { func Mknod(path string, mode uint32, dev uint64) (err error) {
var oldDev int return Mknodat(AT_FDCWD, path, mode, dev)
if supportsABI(_ino64First) {
return mknodat_freebsd12(AT_FDCWD, path, mode, dev)
}
oldDev = int(dev)
return mknod(path, mode, oldDev)
}
func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
var oldDev int
if supportsABI(_ino64First) {
return mknodat_freebsd12(fd, path, mode, dev)
}
oldDev = int(dev)
return mknodat(fd, path, mode, oldDev)
}
// round x to the nearest multiple of y, larger or equal to x.
//
// from /usr/include/sys/param.h Macros for counting and rounding.
// #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
func roundup(x, y int) int {
return ((x + y - 1) / y) * y
}
func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
*s = Stat_t{
Dev: uint64(old.Dev),
Ino: uint64(old.Ino),
Nlink: uint64(old.Nlink),
Mode: old.Mode,
Uid: old.Uid,
Gid: old.Gid,
Rdev: uint64(old.Rdev),
Atim: old.Atim,
Mtim: old.Mtim,
Ctim: old.Ctim,
Btim: old.Btim,
Size: old.Size,
Blocks: old.Blocks,
Blksize: old.Blksize,
Flags: old.Flags,
Gen: uint64(old.Gen),
}
}
func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) {
*s = Statfs_t{
Version: _statfsVersion,
Type: old.Type,
Flags: old.Flags,
Bsize: old.Bsize,
Iosize: old.Iosize,
Blocks: old.Blocks,
Bfree: old.Bfree,
Bavail: old.Bavail,
Files: old.Files,
Ffree: old.Ffree,
Syncwrites: old.Syncwrites,
Asyncwrites: old.Asyncwrites,
Syncreads: old.Syncreads,
Asyncreads: old.Asyncreads,
// Spare
Namemax: old.Namemax,
Owner: old.Owner,
Fsid: old.Fsid,
// Charspare
// Fstypename
// Mntfromname
// Mntonname
}
sl := old.Fstypename[:]
n := clen(*(*[]byte)(unsafe.Pointer(&sl)))
copy(s.Fstypename[:], old.Fstypename[:n])
sl = old.Mntfromname[:]
n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
copy(s.Mntfromname[:], old.Mntfromname[:n])
sl = old.Mntonname[:]
n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
copy(s.Mntonname[:], old.Mntonname[:n])
}
func convertFromDirents11(buf []byte, old []byte) int {
const (
fixedSize = int(unsafe.Offsetof(Dirent{}.Name))
oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name))
)
dstPos := 0
srcPos := 0
for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) {
var dstDirent Dirent
var srcDirent dirent_freebsd11
// If multiple direntries are written, sometimes when we reach the final one,
// we may have cap of old less than size of dirent_freebsd11.
copy((*[unsafe.Sizeof(srcDirent)]byte)(unsafe.Pointer(&srcDirent))[:], old[srcPos:])
reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8)
if dstPos+reclen > len(buf) {
break
}
dstDirent.Fileno = uint64(srcDirent.Fileno)
dstDirent.Off = 0
dstDirent.Reclen = uint16(reclen)
dstDirent.Type = srcDirent.Type
dstDirent.Pad0 = 0
dstDirent.Namlen = uint16(srcDirent.Namlen)
dstDirent.Pad1 = 0
copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen])
copy(buf[dstPos:], (*[unsafe.Sizeof(dstDirent)]byte)(unsafe.Pointer(&dstDirent))[:])
padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen]
for i := range padding {
padding[i] = 0
}
dstPos += int(dstDirent.Reclen)
srcPos += int(srcDirent.Reclen)
}
return dstPos
} }
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
@ -502,33 +254,51 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
} }
//sys ptrace(request int, pid int, addr uintptr, data int) (err error) //sys ptrace(request int, pid int, addr uintptr, data int) (err error)
//sys ptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) = SYS_PTRACE
func PtraceAttach(pid int) (err error) { func PtraceAttach(pid int) (err error) {
return ptrace(PTRACE_ATTACH, pid, 0, 0) return ptrace(PT_ATTACH, pid, 0, 0)
} }
func PtraceCont(pid int, signal int) (err error) { func PtraceCont(pid int, signal int) (err error) {
return ptrace(PTRACE_CONT, pid, 1, signal) return ptrace(PT_CONTINUE, pid, 1, signal)
} }
func PtraceDetach(pid int) (err error) { func PtraceDetach(pid int) (err error) {
return ptrace(PTRACE_DETACH, pid, 1, 0) return ptrace(PT_DETACH, pid, 1, 0)
} }
func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) { func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) {
return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0) return ptracePtr(PT_GETFPREGS, pid, unsafe.Pointer(fpregsout), 0)
} }
func PtraceGetRegs(pid int, regsout *Reg) (err error) { func PtraceGetRegs(pid int, regsout *Reg) (err error) {
return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0) return ptracePtr(PT_GETREGS, pid, unsafe.Pointer(regsout), 0)
}
func PtraceIO(req int, pid int, offs uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{
Op: int32(req),
Offs: offs,
}
if countin > 0 {
_ = out[:countin] // check bounds
ioDesc.Addr = &out[0]
} else if out != nil {
ioDesc.Addr = (*byte)(unsafe.Pointer(&_zero))
}
ioDesc.SetLen(countin)
err = ptracePtr(PT_IO, pid, unsafe.Pointer(&ioDesc), 0)
return int(ioDesc.Len), err
} }
func PtraceLwpEvents(pid int, enable int) (err error) { func PtraceLwpEvents(pid int, enable int) (err error) {
return ptrace(PTRACE_LWPEVENTS, pid, 0, enable) return ptrace(PT_LWP_EVENTS, pid, 0, enable)
} }
func PtraceLwpInfo(pid int, info uintptr) (err error) { func PtraceLwpInfo(pid int, info *PtraceLwpInfoStruct) (err error) {
return ptrace(PTRACE_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{}))) return ptracePtr(PT_LWPINFO, pid, unsafe.Pointer(info), int(unsafe.Sizeof(*info)))
} }
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
@ -548,11 +318,23 @@ func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
} }
func PtraceSetRegs(pid int, regs *Reg) (err error) { func PtraceSetRegs(pid int, regs *Reg) (err error) {
return ptrace(PTRACE_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0) return ptracePtr(PT_SETREGS, pid, unsafe.Pointer(regs), 0)
} }
func PtraceSingleStep(pid int) (err error) { func PtraceSingleStep(pid int) (err error) {
return ptrace(PTRACE_SINGLESTEP, pid, 1, 0) return ptrace(PT_STEP, pid, 1, 0)
}
func Dup3(oldfd, newfd, flags int) error {
if oldfd == newfd || flags&^O_CLOEXEC != 0 {
return EINVAL
}
how := F_DUP2FD
if flags&O_CLOEXEC != 0 {
how = F_DUP2FD_CLOEXEC
}
_, err := fcntl(oldfd, how, newfd)
return err
} }
/* /*
@ -568,6 +350,7 @@ func PtraceSingleStep(pid int) (err error) {
//sys Chmod(path string, mode uint32) (err error) //sys Chmod(path string, mode uint32) (err error)
//sys Chown(path string, uid int, gid int) (err error) //sys Chown(path string, uid int, gid int) (err error)
//sys Chroot(path string) (err error) //sys Chroot(path string) (err error)
//sys ClockGettime(clockid int32, time *Timespec) (err error)
//sys Close(fd int) (err error) //sys Close(fd int) (err error)
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
@ -594,16 +377,12 @@ func PtraceSingleStep(pid int) (err error) {
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys fstat(fd int, stat *stat_freebsd11_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys fstat_freebsd12(fd int, stat *Stat_t) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error)
//sys fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error)
//sys fstatfs(fd int, stat *statfs_freebsd11_t) (err error)
//sys fstatfs_freebsd12(fd int, stat *Statfs_t) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) //sys getdirentries(fd int, buf []byte, basep *uint64) (n int, err error)
//sys getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error)
//sys Getdtablesize() (size int) //sys Getdtablesize() (size int)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
//sysnb Geteuid() (uid int) //sysnb Geteuid() (uid int)
@ -625,19 +404,16 @@ func PtraceSingleStep(pid int) (err error) {
//sys Link(path string, link string) (err error) //sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) //sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error) //sys Listen(s int, backlog int) (err error)
//sys lstat(path string, stat *stat_freebsd11_t) (err error)
//sys Mkdir(path string, mode uint32) (err error) //sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error)
//sys mknod(path string, mode uint32, dev int) (err error) //sys Mknodat(fd int, path string, mode uint32, dev uint64) (err error)
//sys mknodat(fd int, path string, mode uint32, dev int) (err error)
//sys mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) //sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error) //sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n 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 pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
@ -657,13 +433,10 @@ func PtraceSingleStep(pid int) (err error) {
//sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(which int, lim *Rlimit) (err error)
//sysnb Setsid() (pid int, err error) //sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tp *Timeval) (err error) //sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error) //sysnb Setuid(uid int) (err error)
//sys stat(path string, stat *stat_freebsd11_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error)
//sys statfs(path string, stat *statfs_freebsd11_t) (err error)
//sys statfs_freebsd12(path string, stat *Statfs_t) (err error)
//sys Symlink(path string, link string) (err error) //sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error) //sys Sync() (err error)

View file

@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func (d *PtraceIoDesc) SetLen(length int) {
d.Len = uint32(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0 var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0) _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)
@ -57,11 +61,5 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceGetFsBase(pid int, fsbase *int64) (err error) { func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0) return ptracePtr(PT_GETFSBASE, pid, unsafe.Pointer(fsbase), 0)
}
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
} }

View file

@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func (d *PtraceIoDesc) SetLen(length int) {
d.Len = uint64(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0 var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
@ -57,11 +61,5 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceGetFsBase(pid int, fsbase *int64) (err error) { func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0) return ptracePtr(PT_GETFSBASE, pid, unsafe.Pointer(fsbase), 0)
}
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
} }

View file

@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func (d *PtraceIoDesc) SetLen(length int) {
d.Len = uint32(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0 var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0) _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)
@ -55,9 +59,3 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
} }
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View file

@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func (d *PtraceIoDesc) SetLen(length int) {
d.Len = uint64(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0 var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
@ -55,9 +59,3 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
} }
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View file

@ -0,0 +1,61 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build riscv64 && freebsd
// +build riscv64,freebsd
package unix
import (
"syscall"
"unsafe"
)
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint64(fd)
k.Filter = int16(mode)
k.Flags = uint16(flags)
}
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
func (d *PtraceIoDesc) SetLen(length int) {
d.Len = uint64(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
written = int(writtenOut)
if e1 != 0 {
err = e1
}
return
}
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)

30
vendor/golang.org/x/sys/unix/syscall_hurd.go generated vendored Normal file
View file

@ -0,0 +1,30 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build hurd
// +build hurd
package unix
/*
#include <stdint.h>
int ioctl(int, unsigned long int, uintptr_t);
*/
import "C"
func ioctl(fd int, req uint, arg uintptr) (err error) {
r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(arg))
if r0 == -1 && er != nil {
err = er
}
return
}
func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) {
r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(uintptr(arg)))
if r0 == -1 && er != nil {
err = er
}
return
}

29
vendor/golang.org/x/sys/unix/syscall_hurd_386.go generated vendored Normal file
View file

@ -0,0 +1,29 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build 386 && hurd
// +build 386,hurd
package unix
const (
TIOCGETA = 0x62251713
)
type Winsize struct {
Row uint16
Col uint16
Xpixel uint16
Ypixel uint16
}
type Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed int32
Ospeed int32
}

View file

@ -10,8 +10,6 @@
package unix package unix
import ( import (
"fmt"
"runtime"
"unsafe" "unsafe"
) )
@ -20,10 +18,9 @@ func bytes2iovec(bs [][]byte) []Iovec {
for i, b := range bs { for i, b := range bs {
iovecs[i].SetLen(len(b)) iovecs[i].SetLen(len(b))
if len(b) > 0 { if len(b) > 0 {
// somehow Iovec.Base on illumos is (*int8), not (*byte) iovecs[i].Base = &b[0]
iovecs[i].Base = (*int8)(unsafe.Pointer(&b[0]))
} else { } else {
iovecs[i].Base = (*int8)(unsafe.Pointer(&_zero)) iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
} }
} }
return iovecs return iovecs
@ -80,107 +77,3 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
} }
return return
} }
//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
var clp, datap *strbuf
if len(cl) > 0 {
clp = &strbuf{
Len: int32(len(cl)),
Buf: (*int8)(unsafe.Pointer(&cl[0])),
}
}
if len(data) > 0 {
datap = &strbuf{
Len: int32(len(data)),
Buf: (*int8)(unsafe.Pointer(&data[0])),
}
}
return putmsg(fd, clp, datap, flags)
}
//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
var clp, datap *strbuf
if len(cl) > 0 {
clp = &strbuf{
Maxlen: int32(len(cl)),
Buf: (*int8)(unsafe.Pointer(&cl[0])),
}
}
if len(data) > 0 {
datap = &strbuf{
Maxlen: int32(len(data)),
Buf: (*int8)(unsafe.Pointer(&data[0])),
}
}
if err = getmsg(fd, clp, datap, &flags); err != nil {
return nil, nil, 0, err
}
if len(cl) > 0 {
retCl = cl[:clp.Len]
}
if len(data) > 0 {
retData = data[:datap.Len]
}
return retCl, retData, flags, nil
}
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
return ioctlRet(fd, req, uintptr(arg))
}
func IoctlSetString(fd int, req uint, val string) error {
bs := make([]byte, len(val)+1)
copy(bs[:len(bs)-1], val)
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
runtime.KeepAlive(&bs[0])
return err
}
// Lifreq Helpers
func (l *Lifreq) SetName(name string) error {
if len(name) >= len(l.Name) {
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
}
for i := range name {
l.Name[i] = int8(name[i])
}
return nil
}
func (l *Lifreq) SetLifruInt(d int) {
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
}
func (l *Lifreq) GetLifruInt() int {
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
}
func (l *Lifreq) SetLifruUint(d uint) {
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
}
func (l *Lifreq) GetLifruUint() uint {
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
}
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
}
// Strioctl Helpers
func (s *Strioctl) SetInt(i int) {
s.Len = int32(unsafe.Sizeof(i))
s.Dp = (*int8)(unsafe.Pointer(&i))
}
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
}

View file

@ -13,8 +13,9 @@ package unix
import ( import (
"encoding/binary" "encoding/binary"
"runtime" "strconv"
"syscall" "syscall"
"time"
"unsafe" "unsafe"
) )
@ -120,6 +121,25 @@ func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
return openat2(dirfd, path, how, SizeofOpenHow) return openat2(dirfd, path, how, SizeofOpenHow)
} }
func Pipe(p []int) error {
return Pipe2(p, 0)
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) error {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err := pipe2(&pp, flags)
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return err
}
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
@ -129,6 +149,15 @@ func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error
return ppoll(&fds[0], len(fds), timeout, sigmask) return ppoll(&fds[0], len(fds), timeout, sigmask)
} }
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
return Ppoll(fds, ts, nil)
}
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
func Readlink(path string, buf []byte) (n int, err error) { func Readlink(path string, buf []byte) (n int, err error) {
@ -205,7 +234,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) error {
func Futimes(fd int, tv []Timeval) (err error) { func Futimes(fd int, tv []Timeval) (err error) {
// Believe it or not, this is the best we can do on Linux // Believe it or not, this is the best we can do on Linux
// (and is what glibc does). // (and is what glibc does).
return Utimes("/proc/self/fd/"+itoa(fd), tv) return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv)
} }
const ImplementsGetwd = true const ImplementsGetwd = true
@ -222,6 +251,13 @@ func Getwd() (wd string, err error) {
if n < 1 || n > len(buf) || buf[n-1] != 0 { if n < 1 || n > len(buf) || buf[n-1] != 0 {
return "", EINVAL return "", EINVAL
} }
// In some cases, Linux can return a path that starts with the
// "(unreachable)" prefix, which can potentially be a valid relative
// path. To work around that, return ENOENT if path is not absolute.
if buf[0] != '/' {
return "", ENOENT
}
return string(buf[0 : n-1]), nil return string(buf[0 : n-1]), nil
} }
@ -331,6 +367,8 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int,
return return
} }
//sys Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error)
func Mkfifo(path string, mode uint32) error { func Mkfifo(path string, mode uint32) error {
return Mknod(path, mode|S_IFIFO, 0) return Mknod(path, mode|S_IFIFO, 0)
} }
@ -347,9 +385,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
} }
@ -362,9 +398,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
} }
@ -413,9 +447,7 @@ func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Hatype = sa.Hatype sa.raw.Hatype = sa.Hatype
sa.raw.Pkttype = sa.Pkttype sa.raw.Pkttype = sa.Pkttype
sa.raw.Halen = sa.Halen sa.raw.Halen = sa.Halen
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
} }
@ -830,12 +862,10 @@ func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
if sa.Addr == nil { if sa.Addr == nil {
return nil, 0, EINVAL return nil, 0, EINVAL
} }
sa.raw.Family = AF_TIPC sa.raw.Family = AF_TIPC
sa.raw.Scope = int8(sa.Scope) sa.raw.Scope = int8(sa.Scope)
sa.raw.Addrtype = sa.Addr.tipcAddrtype() sa.raw.Addrtype = sa.Addr.tipcAddrtype()
sa.raw.Addr = sa.Addr.tipcAddr() sa.raw.Addr = sa.Addr.tipcAddr()
return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
} }
@ -849,9 +879,7 @@ type SockaddrL2TPIP struct {
func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) { func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_INET sa.raw.Family = AF_INET
sa.raw.Conn_id = sa.ConnId sa.raw.Conn_id = sa.ConnId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
} }
@ -867,9 +895,7 @@ func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_INET6 sa.raw.Family = AF_INET6
sa.raw.Conn_id = sa.ConnId sa.raw.Conn_id = sa.ConnId
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
} }
@ -965,9 +991,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Hatype = pp.Hatype sa.Hatype = pp.Hatype
sa.Pkttype = pp.Pkttype sa.Pkttype = pp.Pkttype
sa.Halen = pp.Halen sa.Halen = pp.Halen
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_UNIX: case AF_UNIX:
@ -991,8 +1015,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
for n < len(pp.Path) && pp.Path[n] != 0 { for n < len(pp.Path) && pp.Path[n] != 0 {
n++ n++
} }
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
sa.Name = string(bytes)
return sa, nil return sa, nil
case AF_INET: case AF_INET:
@ -1006,18 +1029,14 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa)) pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
sa := new(SockaddrL2TPIP) sa := new(SockaddrL2TPIP)
sa.ConnId = pp.Conn_id sa.ConnId = pp.Conn_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
default: default:
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
@ -1033,9 +1052,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrL2TPIP6) sa := new(SockaddrL2TPIP6)
sa.ConnId = pp.Conn_id sa.ConnId = pp.Conn_id
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
default: default:
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
@ -1043,9 +1060,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
@ -1349,6 +1364,10 @@ func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) {
return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o))) return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o)))
} }
func SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error {
return setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s))
}
// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
// KeyctlInt calls keyctl commands in which each argument is an int. // KeyctlInt calls keyctl commands in which each argument is an int.
@ -1484,19 +1503,13 @@ func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error
//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr var msg Msghdr
var rsa RawSockaddrAny msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Namelen = uint32(SizeofSockaddrAny) msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
if len(p) == 0 { if emptyIovecs(iov) {
var sockType int var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil { if err != nil {
@ -1504,53 +1517,36 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
} }
// receive at least one normal byte // receive at least one normal byte
if sockType != SOCK_DGRAM { if sockType != SOCK_DGRAM {
iov.Base = &dummy var iova [1]Iovec
iov.SetLen(1) iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
} }
msg.Control = &oob[0] msg.Control = &oob[0]
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); err != nil { if n, err = recvmsg(fd, &msg, flags); err != nil {
return return
} }
oobn = int(msg.Controllen) oobn = int(msg.Controllen)
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return return
} }
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
var err error
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
var msg Msghdr var msg Msghdr
msg.Name = (*byte)(ptr) msg.Name = (*byte)(ptr)
msg.Namelen = uint32(salen) msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte var dummy byte
var empty bool
if len(oob) > 0 { if len(oob) > 0 {
if len(p) == 0 { empty = emptyIovecs(iov)
if empty {
var sockType int var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil { if err != nil {
@ -1558,19 +1554,23 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
} }
// send at least one normal byte // send at least one normal byte
if sockType != SOCK_DGRAM { if sockType != SOCK_DGRAM {
iov.Base = &dummy var iova [1]Iovec
iov.SetLen(1) iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
} }
msg.Control = &oob[0] msg.Control = &oob[0]
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil { if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err return 0, err
} }
if len(oob) > 0 && len(p) == 0 { if len(oob) > 0 && empty {
n = 0 n = 0
} }
return n, nil return n, nil
@ -1582,6 +1582,7 @@ func BindToDevice(fd int, device string) (err error) {
} }
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
//sys ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE
func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
// The peek requests are machine-size oriented, so we wrap it // The peek requests are machine-size oriented, so we wrap it
@ -1599,7 +1600,7 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro
// boundary. // boundary.
n := 0 n := 0
if addr%SizeofPtr != 0 { if addr%SizeofPtr != 0 {
err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) err = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -1611,7 +1612,7 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro
for len(out) > 0 { for len(out) > 0 {
// We use an internal buffer to guarantee alignment. // We use an internal buffer to guarantee alignment.
// It's not documented if this is necessary, but we're paranoid. // It's not documented if this is necessary, but we're paranoid.
err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
if err != nil { if err != nil {
return n, err return n, err
} }
@ -1643,7 +1644,7 @@ func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (c
n := 0 n := 0
if addr%SizeofPtr != 0 { if addr%SizeofPtr != 0 {
var buf [SizeofPtr]byte var buf [SizeofPtr]byte
err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) err = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -1670,7 +1671,7 @@ func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (c
// Trailing edge. // Trailing edge.
if len(data) > 0 { if len(data) > 0 {
var buf [SizeofPtr]byte var buf [SizeofPtr]byte
err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
if err != nil { if err != nil {
return n, err return n, err
} }
@ -1698,12 +1699,23 @@ func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {
return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data) return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
} }
// elfNT_PRSTATUS is a copy of the debug/elf.NT_PRSTATUS constant so
// x/sys/unix doesn't need to depend on debug/elf and thus
// compress/zlib, debug/dwarf, and other packages.
const elfNT_PRSTATUS = 1
func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) var iov Iovec
iov.Base = (*byte)(unsafe.Pointer(regsout))
iov.SetLen(int(unsafe.Sizeof(*regsout)))
return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
} }
func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) var iov Iovec
iov.Base = (*byte)(unsafe.Pointer(regs))
iov.SetLen(int(unsafe.Sizeof(*regs)))
return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
} }
func PtraceSetOptions(pid int, options int) (err error) { func PtraceSetOptions(pid int, options int) (err error) {
@ -1712,7 +1724,7 @@ func PtraceSetOptions(pid int, options int) (err error) {
func PtraceGetEventMsg(pid int) (msg uint, err error) { func PtraceGetEventMsg(pid int) (msg uint, err error) {
var data _C_long var data _C_long
err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data))) err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
msg = uint(data) msg = uint(data)
return return
} }
@ -1772,6 +1784,16 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
return mount(source, target, fstype, flags, datap) return mount(source, target, fstype, flags, datap)
} }
//sys mountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) = SYS_MOUNT_SETATTR
// MountSetattr is a wrapper for mount_setattr(2).
// https://man7.org/linux/man-pages/man2/mount_setattr.2.html
//
// Requires kernel >= 5.12.
func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error {
return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr))
}
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
if raceenabled { if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync)) raceReleaseMerge(unsafe.Pointer(&ioSync))
@ -1793,6 +1815,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error) //sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error)
//sys Chdir(path string) (err error) //sys Chdir(path string) (err error)
//sys Chroot(path string) (err error) //sys Chroot(path string) (err error)
//sys ClockAdjtime(clockid int32, buf *Timex) (state int, err error)
//sys ClockGetres(clockid int32, res *Timespec) (err error) //sys ClockGetres(clockid int32, res *Timespec) (err error)
//sys ClockGettime(clockid int32, time *Timespec) (err error) //sys ClockGettime(clockid int32, time *Timespec) (err error)
//sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error)
@ -1803,12 +1826,8 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Dup(oldfd int) (fd int, err error) //sys Dup(oldfd int) (fd int, err error)
func Dup2(oldfd, newfd int) error { func Dup2(oldfd, newfd int) error {
// Android O and newer blocks dup2; riscv and arm64 don't implement dup2.
if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" {
return Dup3(oldfd, newfd, 0) return Dup3(oldfd, newfd, 0)
} }
return dup2(oldfd, newfd)
}
//sys Dup3(oldfd int, newfd int, flags int) (err error) //sys Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb EpollCreate1(flag int) (fd int, err error) //sysnb EpollCreate1(flag int) (fd int, err error)
@ -1827,6 +1846,9 @@ func Dup2(oldfd, newfd int) error {
//sys Fremovexattr(fd int, attr string) (err error) //sys Fremovexattr(fd int, attr string) (err error)
//sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
//sys Fsopen(fsName string, flags int) (fd int, err error)
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
//sysnb Getpgid(pid int) (pgid int, err error) //sysnb Getpgid(pid int) (pgid int, err error)
@ -1857,12 +1879,13 @@ func Getpgrp() (pid int) {
//sys MemfdCreate(name string, flags int) (fd int, err error) //sys MemfdCreate(name string, flags int) (fd int, err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys MoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys OpenTree(dfd int, fileName string, flags uint) (r int, err error)
//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
//sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 //sys pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Removexattr(path string, attr string) (err error) //sys Removexattr(path string, attr string) (err error)
//sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
@ -1874,6 +1897,15 @@ func Getpgrp() (pid int) {
//sysnb Settimeofday(tv *Timeval) (err error) //sysnb Settimeofday(tv *Timeval) (err error)
//sys Setns(fd int, nstype int) (err error) //sys Setns(fd int, nstype int) (err error)
//go:linkname syscall_prlimit syscall.prlimit
func syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error
func Prlimit(pid, resource int, newlimit, old *Rlimit) error {
// Just call the syscall version, because as of Go 1.21
// it will affect starting a new process.
return syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old))
}
// PrctlRetInt performs a prctl operation specified by option and further // PrctlRetInt performs a prctl operation specified by option and further
// optional arguments arg2 through arg5 depending on option. It returns a // optional arguments arg2 through arg5 depending on option. It returns a
// non-negative integer that is returned by the prctl syscall. // non-negative integer that is returned by the prctl syscall.
@ -1885,17 +1917,28 @@ func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uint
return int(ret), nil return int(ret), nil
} }
// issue 1435.
// On linux Setuid and Setgid only affects the current thread, not the process.
// This does not match what most callers expect so we must return an error
// here rather than letting the caller think that the call succeeded.
func Setuid(uid int) (err error) { func Setuid(uid int) (err error) {
return EOPNOTSUPP return syscall.Setuid(uid)
} }
func Setgid(uid int) (err error) { func Setgid(gid int) (err error) {
return EOPNOTSUPP return syscall.Setgid(gid)
}
func Setreuid(ruid, euid int) (err error) {
return syscall.Setreuid(ruid, euid)
}
func Setregid(rgid, egid int) (err error) {
return syscall.Setregid(rgid, egid)
}
func Setresuid(ruid, euid, suid int) (err error) {
return syscall.Setresuid(ruid, euid, suid)
}
func Setresgid(rgid, egid, sgid int) (err error) {
return syscall.Setresgid(rgid, egid, sgid)
} }
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set. // SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
@ -1954,36 +1997,46 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
//sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 //sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
//sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 //sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
func bytes2iovec(bs [][]byte) []Iovec { // minIovec is the size of the small initial allocation used by
iovecs := make([]Iovec, len(bs)) // Readv, Writev, etc.
for i, b := range bs { //
iovecs[i].SetLen(len(b)) // This small allocation gets stack allocated, which lets the
// common use case of len(iovs) <= minIovs avoid more expensive
// heap allocations.
const minIovec = 8
// appendBytes converts bs to Iovecs and appends them to vecs.
func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
for _, b := range bs {
var v Iovec
v.SetLen(len(b))
if len(b) > 0 { if len(b) > 0 {
iovecs[i].Base = &b[0] v.Base = &b[0]
} else { } else {
iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero)) v.Base = (*byte)(unsafe.Pointer(&_zero))
} }
vecs = append(vecs, v)
} }
return iovecs return vecs
} }
// offs2lohi splits offs into its lower and upper unsigned long. On 64-bit // offs2lohi splits offs into its low and high order bits.
// systems, hi will always be 0. On 32-bit systems, offs will be split in half.
// preadv/pwritev chose this calling convention so they don't need to add a
// padding-register for alignment on ARM.
func offs2lohi(offs int64) (lo, hi uintptr) { func offs2lohi(offs int64) (lo, hi uintptr) {
return uintptr(offs), uintptr(uint64(offs) >> SizeofLong) const longBits = SizeofLong * 8
return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet
} }
func Readv(fd int, iovs [][]byte) (n int, err error) { func Readv(fd int, iovs [][]byte) (n int, err error) {
iovecs := bytes2iovec(iovs) iovecs := make([]Iovec, 0, minIovec)
iovecs = appendBytes(iovecs, iovs)
n, err = readv(fd, iovecs) n, err = readv(fd, iovecs)
readvRacedetect(iovecs, n, err) readvRacedetect(iovecs, n, err)
return n, err return n, err
} }
func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
iovecs := bytes2iovec(iovs) iovecs := make([]Iovec, 0, minIovec)
iovecs = appendBytes(iovecs, iovs)
lo, hi := offs2lohi(offset) lo, hi := offs2lohi(offset)
n, err = preadv(fd, iovecs, lo, hi) n, err = preadv(fd, iovecs, lo, hi)
readvRacedetect(iovecs, n, err) readvRacedetect(iovecs, n, err)
@ -1991,7 +2044,8 @@ func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
} }
func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
iovecs := bytes2iovec(iovs) iovecs := make([]Iovec, 0, minIovec)
iovecs = appendBytes(iovecs, iovs)
lo, hi := offs2lohi(offset) lo, hi := offs2lohi(offset)
n, err = preadv2(fd, iovecs, lo, hi, flags) n, err = preadv2(fd, iovecs, lo, hi, flags)
readvRacedetect(iovecs, n, err) readvRacedetect(iovecs, n, err)
@ -2018,7 +2072,8 @@ func readvRacedetect(iovecs []Iovec, n int, err error) {
} }
func Writev(fd int, iovs [][]byte) (n int, err error) { func Writev(fd int, iovs [][]byte) (n int, err error) {
iovecs := bytes2iovec(iovs) iovecs := make([]Iovec, 0, minIovec)
iovecs = appendBytes(iovecs, iovs)
if raceenabled { if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync)) raceReleaseMerge(unsafe.Pointer(&ioSync))
} }
@ -2028,7 +2083,8 @@ func Writev(fd int, iovs [][]byte) (n int, err error) {
} }
func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
iovecs := bytes2iovec(iovs) iovecs := make([]Iovec, 0, minIovec)
iovecs = appendBytes(iovecs, iovs)
if raceenabled { if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync)) raceReleaseMerge(unsafe.Pointer(&ioSync))
} }
@ -2039,7 +2095,8 @@ func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
} }
func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
iovecs := bytes2iovec(iovs) iovecs := make([]Iovec, 0, minIovec)
iovecs = appendBytes(iovecs, iovs)
if raceenabled { if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync)) raceReleaseMerge(unsafe.Pointer(&ioSync))
} }
@ -2067,21 +2124,7 @@ func writevRacedetect(iovecs []Iovec, n int) {
// mmap varies by architecture; see syscall_linux_*.go. // mmap varies by architecture; see syscall_linux_*.go.
//sys munmap(addr uintptr, length uintptr) (err error) //sys munmap(addr uintptr, length uintptr) (err error)
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
var mapper = &mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
}
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
return mapper.Mmap(fd, offset, length, prot, flags)
}
func Munmap(b []byte) (err error) {
return mapper.Munmap(b)
}
//sys Madvise(b []byte, advice int) (err error) //sys Madvise(b []byte, advice int) (err error)
//sys Mprotect(b []byte, prot int) (err error) //sys Mprotect(b []byte, prot int) (err error)
//sys Mlock(b []byte) (err error) //sys Mlock(b []byte) (err error)
@ -2090,6 +2133,12 @@ func Munmap(b []byte) (err error) {
//sys Munlock(b []byte) (err error) //sys Munlock(b []byte) (err error)
//sys Munlockall() (err error) //sys Munlockall() (err error)
const (
mremapFixed = MREMAP_FIXED
mremapDontunmap = MREMAP_DONTUNMAP
mremapMaymove = MREMAP_MAYMOVE
)
// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
// using the specified flags. // using the specified flags.
func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
@ -2120,6 +2169,14 @@ func isGroupMember(gid int) bool {
return false return false
} }
func isCapDacOverrideSet() bool {
hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3}
data := [2]CapUserData{}
err := Capget(&hdr, &data[0])
return err == nil && data[0].Effective&(1<<CAP_DAC_OVERRIDE) != 0
}
//sys faccessat(dirfd int, path string, mode uint32) (err error) //sys faccessat(dirfd int, path string, mode uint32) (err error)
//sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) //sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error)
@ -2155,6 +2212,12 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
var uid int var uid int
if flags&AT_EACCESS != 0 { if flags&AT_EACCESS != 0 {
uid = Geteuid() uid = Geteuid()
if uid != 0 && isCapDacOverrideSet() {
// If CAP_DAC_OVERRIDE is set, file access check is
// done by the kernel in the same way as for root
// (see generic_permission() in the Linux sources).
uid = 0
}
} else { } else {
uid = Getuid() uid = Getuid()
} }
@ -2182,7 +2245,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
gid = Getgid() gid = Getgid()
} }
if uint32(gid) == st.Gid || isGroupMember(gid) { if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
fmode = (st.Mode >> 3) & 7 fmode = (st.Mode >> 3) & 7
} else { } else {
fmode = st.Mode & 7 fmode = st.Mode & 7
@ -2234,7 +2297,7 @@ func (fh *FileHandle) Bytes() []byte {
if n == 0 { if n == 0 {
return nil return nil
} }
return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n] return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
} }
// NameToHandleAt wraps the name_to_handle_at system call; it obtains // NameToHandleAt wraps the name_to_handle_at system call; it obtains
@ -2297,12 +2360,144 @@ type RemoteIovec struct {
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN //sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD //sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
//sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
//sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error)
//sys getitimer(which int, currValue *Itimerval) (err error)
//sys setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error)
// MakeItimerval creates an Itimerval from interval and value durations.
func MakeItimerval(interval, value time.Duration) Itimerval {
return Itimerval{
Interval: NsecToTimeval(interval.Nanoseconds()),
Value: NsecToTimeval(value.Nanoseconds()),
}
}
// A value which may be passed to the which parameter for Getitimer and
// Setitimer.
type ItimerWhich int
// Possible which values for Getitimer and Setitimer.
const (
ItimerReal ItimerWhich = ITIMER_REAL
ItimerVirtual ItimerWhich = ITIMER_VIRTUAL
ItimerProf ItimerWhich = ITIMER_PROF
)
// Getitimer wraps getitimer(2) to return the current value of the timer
// specified by which.
func Getitimer(which ItimerWhich) (Itimerval, error) {
var it Itimerval
if err := getitimer(int(which), &it); err != nil {
return Itimerval{}, err
}
return it, nil
}
// Setitimer wraps setitimer(2) to arm or disarm the timer specified by which.
// It returns the previous value of the timer.
//
// If the Itimerval argument is the zero value, the timer will be disarmed.
func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
var prev Itimerval
if err := setitimer(int(which), &it, &prev); err != nil {
return Itimerval{}, err
}
return prev, nil
}
//sysnb rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK
func PthreadSigmask(how int, set, oldset *Sigset_t) error {
if oldset != nil {
// Explicitly clear in case Sigset_t is larger than _C__NSIG.
*oldset = Sigset_t{}
}
return rtSigprocmask(how, set, oldset, _C__NSIG/8)
}
//sysnb getresuid(ruid *_C_int, euid *_C_int, suid *_C_int)
//sysnb getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int)
func Getresuid() (ruid, euid, suid int) {
var r, e, s _C_int
getresuid(&r, &e, &s)
return int(r), int(e), int(s)
}
func Getresgid() (rgid, egid, sgid int) {
var r, e, s _C_int
getresgid(&r, &e, &s)
return int(r), int(e), int(s)
}
// Pselect is a wrapper around the Linux pselect6 system call.
// This version does not modify the timeout argument.
func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
// Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES,
// The Linux pselect6() system call modifies its timeout argument.
// [Not modifying the argument] is the behavior required by POSIX.1-2001.
var mutableTimeout *Timespec
if timeout != nil {
mutableTimeout = new(Timespec)
*mutableTimeout = *timeout
}
// The final argument of the pselect6() system call is not a
// sigset_t * pointer, but is instead a structure
var kernelMask *sigset_argpack
if sigmask != nil {
wordBits := 32 << (^uintptr(0) >> 63) // see math.intSize
// A sigset stores one bit per signal,
// offset by 1 (because signal 0 does not exist).
// So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉.
sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits)
sigsetBytes := uintptr(sigsetWords * (wordBits / 8))
kernelMask = &sigset_argpack{
ss: sigmask,
ssLen: sigsetBytes,
}
}
return pselect6(nfd, r, w, e, mutableTimeout, kernelMask)
}
//sys schedSetattr(pid int, attr *SchedAttr, flags uint) (err error)
//sys schedGetattr(pid int, attr *SchedAttr, size uint, flags uint) (err error)
// SchedSetAttr is a wrapper for sched_setattr(2) syscall.
// https://man7.org/linux/man-pages/man2/sched_setattr.2.html
func SchedSetAttr(pid int, attr *SchedAttr, flags uint) error {
if attr == nil {
return EINVAL
}
attr.Size = SizeofSchedAttr
return schedSetattr(pid, attr, flags)
}
// SchedGetAttr is a wrapper for sched_getattr(2) syscall.
// https://man7.org/linux/man-pages/man2/sched_getattr.2.html
func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) {
attr := &SchedAttr{}
if err := schedGetattr(pid, attr, SizeofSchedAttr, flags); err != nil {
return nil, err
}
return attr, nil
}
/* /*
* Unimplemented * Unimplemented
*/ */
// AfsSyscall // AfsSyscall
// Alarm
// ArchPrctl // ArchPrctl
// Brk // Brk
// ClockNanosleep // ClockNanosleep
@ -2318,7 +2513,6 @@ type RemoteIovec struct {
// GetMempolicy // GetMempolicy
// GetRobustList // GetRobustList
// GetThreadArea // GetThreadArea
// Getitimer
// Getpmsg // Getpmsg
// IoCancel // IoCancel
// IoDestroy // IoDestroy
@ -2341,7 +2535,6 @@ type RemoteIovec struct {
// MqTimedreceive // MqTimedreceive
// MqTimedsend // MqTimedsend
// MqUnlink // MqUnlink
// Mremap
// Msgctl // Msgctl
// Msgget // Msgget
// Msgrcv // Msgrcv
@ -2358,7 +2551,6 @@ type RemoteIovec struct {
// RestartSyscall // RestartSyscall
// RtSigaction // RtSigaction
// RtSigpending // RtSigpending
// RtSigprocmask
// RtSigqueueinfo // RtSigqueueinfo
// RtSigreturn // RtSigreturn
// RtSigsuspend // RtSigsuspend
@ -2379,10 +2571,6 @@ type RemoteIovec struct {
// SetRobustList // SetRobustList
// SetThreadArea // SetThreadArea
// SetTidAddress // SetTidAddress
// Shmat
// Shmctl
// Shmdt
// Shmget
// Sigaltstack // Sigaltstack
// Swapoff // Swapoff
// Swapon // Swapon
@ -2400,5 +2588,4 @@ type RemoteIovec struct {
// Vfork // Vfork
// Vhangup // Vhangup
// Vserver // Vserver
// Waitid
// _Sysctl // _Sysctl

View file

@ -19,35 +19,8 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)} return Timeval{Sec: int32(sec), Usec: int32(usec)}
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (386 default is 32-bit file system and 16-bit uid). // (386 default is 32-bit file system and 16-bit uid).
//sys dup2(oldfd int, newfd int) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
@ -62,16 +35,12 @@ func Pipe2(p []int, flags int) (err error) {
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32 //sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32 //sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
@ -128,33 +97,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) {
return return
} }
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = Prlimit(0, resource, rlim, nil)
if err != ENOSYS {
return err
}
rl := rlimit32{}
if rlim.Cur == rlimInf64 {
rl.Cur = rlimInf32
} else if rlim.Cur < uint64(rlimInf32) {
rl.Cur = uint32(rlim.Cur)
} else {
return EINVAL
}
if rlim.Max == rlimInf64 {
rl.Max = rlimInf32
} else if rlim.Max < uint64(rlimInf32) {
rl.Max = uint32(rlim.Max)
} else {
return EINVAL
}
return setrlimit(resource, &rl)
}
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
newoffset, errno := seek(fd, offset, whence) newoffset, errno := seek(fd, offset, whence)
if errno != 0 { if errno != 0 {
@ -200,14 +142,6 @@ const (
_SENDMMSG = 20 _SENDMMSG = 20
) )
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
if e != 0 {
err = e
}
return
}
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
if e != 0 { if e != 0 {
@ -379,12 +313,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) { func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length) rsa.Service_name_len = uint32(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

14
vendor/golang.org/x/sys/unix/syscall_linux_alarm.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build linux && (386 || amd64 || mips || mipsle || mips64 || mipsle || ppc64 || ppc64le || ppc || s390x || sparc64)
// +build linux
// +build 386 amd64 mips mipsle mips64 mipsle ppc64 ppc64le ppc s390x sparc64
package unix
// SYS_ALARM is not defined on arm or riscv, but is available for other GOARCH
// values.
//sys Alarm(seconds uint) (remaining uint, err error)

View file

@ -7,7 +7,6 @@
package unix package unix
//sys dup2(oldfd int, newfd int) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -29,9 +28,10 @@ func Lstat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW) return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
} }
//sys MemfdSecret(flags int) (fd int, err error)
//sys Pause() (err error) //sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -40,17 +40,12 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
if timeout != nil { if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
} }
return Pselect(nfd, r, w, e, ts, nil) return pselect6(nfd, r, w, e, ts, nil)
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error) //sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
@ -63,7 +58,6 @@ func Stat(path string, stat *Stat_t) (err error) {
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -114,32 +108,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec} return Timeval{Sec: sec, Usec: usec}
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func (r *PtraceRegs) PC() uint64 { return r.Rip } func (r *PtraceRegs) PC() uint64 { return r.Rip }
func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc } func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
@ -164,15 +132,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

View file

@ -19,32 +19,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)} return Timeval{Sec: int32(sec), Usec: int32(usec)}
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
newoffset, errno := seek(fd, offset, whence) newoffset, errno := seek(fd, offset, whence)
if errno != 0 { if errno != 0 {
@ -53,7 +27,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
return newoffset, nil return newoffset, nil
} }
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -72,7 +45,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (16-bit uid calls are not always supported in newer kernels) // (16-bit uid calls are not always supported in newer kernels)
//sys dup2(oldfd int, newfd int) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
@ -90,10 +62,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32 //sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32 //sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
@ -124,8 +92,8 @@ func Utime(path string, buf *Utimbuf) error {
//sys utimes(path string, times *[2]Timeval) (err error) //sys utimes(path string, times *[2]Timeval) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
@ -203,33 +171,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) {
return return
} }
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = Prlimit(0, resource, rlim, nil)
if err != ENOSYS {
return err
}
rl := rlimit32{}
if rlim.Cur == rlimInf64 {
rl.Cur = rlimInf32
} else if rlim.Cur < uint64(rlimInf32) {
rl.Cur = uint32(rlim.Cur)
} else {
return EINVAL
}
if rlim.Max == rlimInf64 {
rl.Max = rlimInf32
} else if rlim.Max < uint64(rlimInf32) {
rl.Max = uint32(rlim.Max)
} else {
return EINVAL
}
return setrlimit(resource, &rl)
}
func (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) } func (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) }
func (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) } func (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) }
@ -254,15 +195,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length) rsa.Service_name_len = uint32(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE //sys armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE
func SyncFileRange(fd int, off int64, n int64, flags int) error { func SyncFileRange(fd int, off int64, n int64, flags int) error {

View file

@ -22,8 +22,9 @@ import "unsafe"
//sysnb getrlimit(resource int, rlim *Rlimit) (err error) //sysnb getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys MemfdSecret(flags int) (fd int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -32,17 +33,12 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
if timeout != nil { if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
} }
return Pselect(nfd, r, w, e, ts, nil) return pselect6(nfd, r, w, e, ts, nil)
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error) //sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
@ -66,7 +62,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS return ENOSYS
} }
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -138,30 +133,6 @@ func utimes(path string, tv *[2]Timeval) (err error) {
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
} }
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
// Getrlimit prefers the prlimit64 system call. See issue 38604. // Getrlimit prefers the prlimit64 system call. See issue 38604.
func Getrlimit(resource int, rlim *Rlimit) error { func Getrlimit(resource int, rlim *Rlimit) error {
err := Prlimit(0, resource, nil, rlim) err := Prlimit(0, resource, nil, rlim)
@ -171,15 +142,6 @@ func Getrlimit(resource int, rlim *Rlimit) error {
return getrlimit(resource, rlim) return getrlimit(resource, rlim)
} }
// Setrlimit prefers the prlimit64 system call. See issue 38604.
func Setrlimit(resource int, rlim *Rlimit) error {
err := Prlimit(0, resource, rlim, nil)
if err != ENOSYS {
return err
}
return setrlimit(resource, rlim)
}
func (r *PtraceRegs) PC() uint64 { return r.Pc } func (r *PtraceRegs) PC() uint64 { return r.Pc }
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
@ -204,27 +166,11 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
// dup2 exists because func Dup3 in syscall_linux.go references
// it in an unreachable path. dup2 isn't available on arm64.
func dup2(oldfd int, newfd int) error
func Pause() error { func Pause() error {
_, err := ppoll(nil, 0, nil, nil) _, err := ppoll(nil, 0, nil, nil)
return err return err
} }
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

217
vendor/golang.org/x/sys/unix/syscall_linux_loong64.go generated vendored Normal file
View file

@ -0,0 +1,217 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build loong64 && linux
// +build loong64,linux
package unix
import "unsafe"
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error)
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
var ts *Timespec
if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return pselect6(nfd, r, w, e, ts, nil)
}
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error)
//sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
func timespecFromStatxTimestamp(x StatxTimestamp) Timespec {
return Timespec{
Sec: x.Sec,
Nsec: int64(x.Nsec),
}
}
func Fstatat(fd int, path string, stat *Stat_t, flags int) error {
var r Statx_t
// Do it the glibc way, add AT_NO_AUTOMOUNT.
if err := Statx(fd, path, AT_NO_AUTOMOUNT|flags, STATX_BASIC_STATS, &r); err != nil {
return err
}
stat.Dev = Mkdev(r.Dev_major, r.Dev_minor)
stat.Ino = r.Ino
stat.Mode = uint32(r.Mode)
stat.Nlink = r.Nlink
stat.Uid = r.Uid
stat.Gid = r.Gid
stat.Rdev = Mkdev(r.Rdev_major, r.Rdev_minor)
// hope we don't get to process files so large to overflow these size
// fields...
stat.Size = int64(r.Size)
stat.Blksize = int32(r.Blksize)
stat.Blocks = int64(r.Blocks)
stat.Atim = timespecFromStatxTimestamp(r.Atime)
stat.Mtim = timespecFromStatxTimestamp(r.Mtime)
stat.Ctim = timespecFromStatxTimestamp(r.Ctime)
return nil
}
func Fstat(fd int, stat *Stat_t) (err error) {
return Fstatat(fd, "", stat, AT_EMPTY_PATH)
}
func Stat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, 0)
}
func Lchown(path string, uid int, gid int) (err error) {
return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW)
}
func Lstat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
}
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sysnb Gettimeofday(tv *Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
func Getrlimit(resource int, rlim *Rlimit) (err error) {
err = Prlimit(0, resource, nil, rlim)
return
}
func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(dirfd, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func Time(t *Time_t) (Time_t, error) {
var tv Timeval
err := Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
func Utime(path string, buf *Utimbuf) error {
tv := []Timeval{
{Sec: buf.Actime},
{Sec: buf.Modtime},
}
return Utimes(path, tv)
}
func utimes(path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(AT_FDCWD, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func (r *PtraceRegs) PC() uint64 { return r.Era }
func (r *PtraceRegs) SetPC(era uint64) { r.Era = era }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length)
}
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length)
}
func Pause() error {
_, err := ppoll(nil, 0, nil, nil)
return err
}
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
cmdlineLen := len(cmdline)
if cmdlineLen > 0 {
// Account for the additional NULL byte added by
// BytePtrFromString in kexecFileLoad. The kexec_file_load
// syscall expects a NULL-terminated string.
cmdlineLen++
}
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
}

View file

@ -8,7 +8,6 @@
package unix package unix
//sys dup2(oldfd int, newfd int) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -22,8 +21,8 @@ package unix
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Pause() (err error) //sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -32,24 +31,18 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
if timeout != nil { if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
} }
return Pselect(nfd, r, w, e, ts, nil) return pselect6(nfd, r, w, e, ts, nil)
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error) //sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -93,30 +86,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec} return Timeval{Sec: sec, Usec: usec}
} }
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Ioperm(from int, num int, on int) (err error) { func Ioperm(from int, num int, on int) (err error) {
return ENOSYS return ENOSYS
} }
@ -219,12 +188,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) { func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

Some files were not shown because too many files have changed in this diff Show more