Commit 804a341a authored by Darren Shepherd's avatar Darren Shepherd

Update vendor

parent 21db1ca4
...@@ -9,10 +9,10 @@ package=github.com/opencontainers/runc/libcontainer/nsenter ...@@ -9,10 +9,10 @@ package=github.com/opencontainers/runc/libcontainer/nsenter
package=github.com/opencontainers/runc/libcontainer/specconv package=github.com/opencontainers/runc/libcontainer/specconv
package=github.com/opencontainers/runc/contrib/cmd/recvtty package=github.com/opencontainers/runc/contrib/cmd/recvtty
k8s.io/kubernetes v1.13.2-k3s4 https://github.com/ibuildthecloud/k3s.git transitive=true,staging=true k8s.io/kubernetes v1.13.3-klp1 file:///home/darren/src/kuberlite/.git transitive=true,staging=true
github.com/rancher/norman 628eb6b32906125ddd77e23f3ad3c9bdb6e93664 https://github.com/ibuildthecloud/norman.git github.com/rancher/norman d640c72bf09d9fbff596dead44338453bba718cc https://github.com/ibuildthecloud/norman.git
github.com/coreos/flannel 3d7cff78e2ca4cade87c6c7d44adf27fe3de2709 https://github.com/ibuildthecloud/flannel.git github.com/coreos/flannel 823afe66b2266bf71f5bec24e6e28b26d70cfc7c https://github.com/ibuildthecloud/flannel.git
github.com/natefinch/lumberjack aee4629129445bbdfb69aa565537dcfa16544311 github.com/natefinch/lumberjack aee4629129445bbdfb69aa565537dcfa16544311
github.com/gorilla/mux v1.6.2 github.com/gorilla/mux v1.6.2
github.com/gorilla/websocket v1.2.0 github.com/gorilla/websocket v1.2.0
...@@ -36,7 +36,7 @@ github.com/alexflint/go-filemutex 72bdc8eae2aef913234599b837f5dda445ca9bd9 ...@@ -36,7 +36,7 @@ github.com/alexflint/go-filemutex 72bdc8eae2aef913234599b837f5dda445ca9bd9
github.com/opencontainers/runtime-spec 5684b8af48c1ac3b1451fa499724e30e3c20a294 github.com/opencontainers/runtime-spec 5684b8af48c1ac3b1451fa499724e30e3c20a294
# containerd # containerd
github.com/containerd/containerd v1.2.1 github.com/containerd/containerd v1.2.2-k3s2 https://github.com/ibuildthecloud/containerd
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3 github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23 github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2 github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
...@@ -66,7 +66,7 @@ golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac ...@@ -66,7 +66,7 @@ golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
google.golang.org/grpc v1.12.0 google.golang.org/grpc v1.12.0
github.com/pkg/errors v0.8.0 github.com/pkg/errors v0.8.0
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7 github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
#golang.org/x/sys 1b2967e3c290b7c545b3db0deeda16e9be4f98a2 https://github.com/golang/sys golang.org/x/sys 1b2967e3c290b7c545b3db0deeda16e9be4f98a2 https://github.com/golang/sys
github.com/opencontainers/image-spec v1.0.1 github.com/opencontainers/image-spec v1.0.1
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
...@@ -82,7 +82,7 @@ github.com/google/go-cmp v0.1.0 ...@@ -82,7 +82,7 @@ github.com/google/go-cmp v0.1.0
go.etcd.io/bbolt v1.3.1-etcd.8 go.etcd.io/bbolt v1.3.1-etcd.8
# cri dependencies # cri dependencies
github.com/containerd/cri 0ca1e3c2b73b5c38e72f29bb76338d0078b23d6c # release/1.2 branch github.com/containerd/cri 0d5cabd006cb5319dc965046067b8432d9fa5ef8 # release/1.2 branch
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90 github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
github.com/blang/semver v3.1.0 github.com/blang/semver v3.1.0
github.com/containernetworking/cni v0.6.0 github.com/containernetworking/cni v0.6.0
......
...@@ -23,3 +23,4 @@ Jian Liao <jliao@alauda.io> liaoj <jliao@alauda.io> ...@@ -23,3 +23,4 @@ Jian Liao <jliao@alauda.io> liaoj <jliao@alauda.io>
Jian Liao <jliao@alauda.io> liaojian <liaojian@Dabllo.local> Jian Liao <jliao@alauda.io> liaojian <liaojian@Dabllo.local>
Rui Cao <ruicao@alauda.io> ruicao <ruicao@alauda.io> Rui Cao <ruicao@alauda.io> ruicao <ruicao@alauda.io>
Xuean Yan <yan.xuean@zte.com.cn> yanxuean <yan.xuean@zte.com.cn> Xuean Yan <yan.xuean@zte.com.cn> yanxuean <yan.xuean@zte.com.cn>
Mike Brown <brownwm@us.ibm.com> Mike Brown <mikebrow@users.noreply.github.com>
...@@ -555,6 +555,10 @@ func (nw *namespacedWriter) Commit(ctx context.Context, size int64, expected dig ...@@ -555,6 +555,10 @@ func (nw *namespacedWriter) Commit(ctx context.Context, size int64, expected dig
var innerErr error var innerErr error
if expected != "" {
size = 0
}
if err := update(ctx, nw.db, func(tx *bolt.Tx) error { if err := update(ctx, nw.db, func(tx *bolt.Tx) error {
dgst, err := nw.commit(ctx, tx, size, expected, opts...) dgst, err := nw.commit(ctx, tx, size, expected, opts...)
if err != nil { if err != nil {
......
...@@ -209,22 +209,27 @@ func (e *execProcess) start(ctx context.Context) (err error) { ...@@ -209,22 +209,27 @@ func (e *execProcess) start(ctx context.Context) (err error) {
e.stdin = sc e.stdin = sc
} }
var copyWaitGroup sync.WaitGroup var copyWaitGroup sync.WaitGroup
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
if socket != nil { if socket != nil {
console, err := socket.ReceiveMaster() console, err := socket.ReceiveMaster()
if err != nil { if err != nil {
cancel()
return errors.Wrap(err, "failed to retrieve console master") return errors.Wrap(err, "failed to retrieve console master")
} }
if e.console, err = e.parent.Platform.CopyConsole(ctx, console, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil { if e.console, err = e.parent.Platform.CopyConsole(ctx, console, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil {
cancel()
return errors.Wrap(err, "failed to start console copy") return errors.Wrap(err, "failed to start console copy")
} }
} else if !e.stdio.IsNull() { } else if !e.stdio.IsNull() {
if err := copyPipes(ctx, e.io, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil { if err := copyPipes(ctx, e.io, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil {
cancel()
return errors.Wrap(err, "failed to start io pipe copy") return errors.Wrap(err, "failed to start io pipe copy")
} }
} }
copyWaitGroup.Wait() copyWaitGroup.Wait()
pid, err := runc.ReadPidFile(opts.PidFile) pid, err := runc.ReadPidFile(opts.PidFile)
if err != nil { if err != nil {
cancel()
return errors.Wrap(err, "failed to retrieve OCI runtime exec pid") return errors.Wrap(err, "failed to retrieve OCI runtime exec pid")
} }
e.pid = pid e.pid = pid
......
...@@ -168,18 +168,22 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error { ...@@ -168,18 +168,22 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
p.closers = append(p.closers, sc) p.closers = append(p.closers, sc)
} }
var copyWaitGroup sync.WaitGroup var copyWaitGroup sync.WaitGroup
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
if socket != nil { if socket != nil {
console, err := socket.ReceiveMaster() console, err := socket.ReceiveMaster()
if err != nil { if err != nil {
cancel()
return errors.Wrap(err, "failed to retrieve console master") return errors.Wrap(err, "failed to retrieve console master")
} }
console, err = p.Platform.CopyConsole(ctx, console, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup) console, err = p.Platform.CopyConsole(ctx, console, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup)
if err != nil { if err != nil {
cancel()
return errors.Wrap(err, "failed to start console copy") return errors.Wrap(err, "failed to start console copy")
} }
p.console = console p.console = console
} else if !hasNoIO(r) { } else if !hasNoIO(r) {
if err := copyPipes(ctx, p.io, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup); err != nil { if err := copyPipes(ctx, p.io, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup); err != nil {
cancel()
return errors.Wrap(err, "failed to start io pipe copy") return errors.Wrap(err, "failed to start io pipe copy")
} }
} }
...@@ -187,6 +191,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error { ...@@ -187,6 +191,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
copyWaitGroup.Wait() copyWaitGroup.Wait()
pid, err := runc.ReadPidFile(pidFile) pid, err := runc.ReadPidFile(pidFile)
if err != nil { if err != nil {
cancel()
return errors.Wrap(err, "failed to retrieve OCI runtime container pid") return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
} }
p.pid = pid p.pid = pid
......
...@@ -43,7 +43,7 @@ github.com/google/go-cmp v0.1.0 ...@@ -43,7 +43,7 @@ github.com/google/go-cmp v0.1.0
go.etcd.io/bbolt v1.3.1-etcd.8 go.etcd.io/bbolt v1.3.1-etcd.8
# cri dependencies # cri dependencies
github.com/containerd/cri 0ca1e3c2b73b5c38e72f29bb76338d0078b23d6c # release/1.2 branch github.com/containerd/cri 0d5cabd006cb5319dc965046067b8432d9fa5ef8 # release/1.2 branch
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90 github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
github.com/blang/semver v3.1.0 github.com/blang/semver v3.1.0
github.com/containernetworking/cni v0.6.0 github.com/containernetworking/cni v0.6.0
......
...@@ -21,7 +21,7 @@ var ( ...@@ -21,7 +21,7 @@ var (
Package = "github.com/containerd/containerd" Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time. // Version holds the complete version number. Filled in at linking time.
Version = "1.2.1+unknown" Version = "1.2.2+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build // Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time. // the program at linking time.
......
...@@ -187,6 +187,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta ...@@ -187,6 +187,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
opts = append(opts, customopts.WithVolumes(mountMap)) opts = append(opts, customopts.WithVolumes(mountMap))
} }
meta.ImageRef = image.ID meta.ImageRef = image.ID
meta.StopSignal = image.ImageSpec.Config.StopSignal
// Get container log path. // Get container log path.
if config.GetLogPath() != "" { if config.GetLogPath() != "" {
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"github.com/containerd/cri/pkg/store"
containerstore "github.com/containerd/cri/pkg/store/container" containerstore "github.com/containerd/cri/pkg/store/container"
) )
...@@ -43,17 +44,20 @@ func (c *criService) ContainerStatus(ctx context.Context, r *runtime.ContainerSt ...@@ -43,17 +44,20 @@ func (c *criService) ContainerStatus(ctx context.Context, r *runtime.ContainerSt
imageRef := container.ImageRef imageRef := container.ImageRef
image, err := c.imageStore.Get(imageRef) image, err := c.imageStore.Get(imageRef)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to get image %q", imageRef) if err != store.ErrNotExist {
} return nil, errors.Wrapf(err, "failed to get image %q", imageRef)
repoTags, repoDigests := parseImageReferences(image.References) }
if len(repoTags) > 0 { } else {
// Based on current behavior of dockershim, this field should be repoTags, repoDigests := parseImageReferences(image.References)
// image tag. if len(repoTags) > 0 {
spec = &runtime.ImageSpec{Image: repoTags[0]} // Based on current behavior of dockershim, this field should be
} // image tag.
if len(repoDigests) > 0 { spec = &runtime.ImageSpec{Image: repoTags[0]}
// Based on the CRI definition, this field will be consumed by user. }
imageRef = repoDigests[0] if len(repoDigests) > 0 {
// Based on the CRI definition, this field will be consumed by user.
imageRef = repoDigests[0]
}
} }
status := toCRIContainerStatus(container, spec, imageRef) status := toCRIContainerStatus(container, spec, imageRef)
info, err := toCRIContainerInfo(ctx, container, r.GetVerbose()) info, err := toCRIContainerInfo(ctx, container, r.GetVerbose())
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"github.com/containerd/cri/pkg/store"
containerstore "github.com/containerd/cri/pkg/store/container" containerstore "github.com/containerd/cri/pkg/store/container"
) )
...@@ -76,24 +77,36 @@ func (c *criService) stopContainer(ctx context.Context, container containerstore ...@@ -76,24 +77,36 @@ func (c *criService) stopContainer(ctx context.Context, container containerstore
// We only need to kill the task. The event handler will Delete the // We only need to kill the task. The event handler will Delete the
// task from containerd after it handles the Exited event. // task from containerd after it handles the Exited event.
if timeout > 0 { if timeout > 0 {
stopSignal := unix.SIGTERM stopSignal := "SIGTERM"
image, err := c.imageStore.Get(container.ImageRef) if container.StopSignal != "" {
if err != nil { stopSignal = container.StopSignal
// NOTE(random-liu): It's possible that the container is stopped, } else {
// deleted and image is garbage collected before this point. However, // The image may have been deleted, and the `StopSignal` field is
// the chance is really slim, even it happens, it's still fine to return // just introduced to handle that.
// an error here. // However, for containers created before the `StopSignal` field is
return errors.Wrapf(err, "failed to get image metadata %q", container.ImageRef) // introduced, still try to get the stop signal from the image config.
} // If the image has been deleted, logging an error and using the
if image.ImageSpec.Config.StopSignal != "" { // default SIGTERM is still better than returning error and leaving
stopSignal, err = signal.ParseSignal(image.ImageSpec.Config.StopSignal) // the container unstoppable. (See issue #990)
// TODO(random-liu): Remove this logic when containerd 1.2 is deprecated.
image, err := c.imageStore.Get(container.ImageRef)
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to parse stop signal %q", if err != store.ErrNotExist {
image.ImageSpec.Config.StopSignal) return errors.Wrapf(err, "failed to get image %q", container.ImageRef)
}
logrus.Warningf("Image %q not found, stop container with signal %q", container.ImageRef, stopSignal)
} else {
if image.ImageSpec.Config.StopSignal != "" {
stopSignal = image.ImageSpec.Config.StopSignal
}
} }
} }
logrus.Infof("Stop container %q with signal %v", id, stopSignal) sig, err := signal.ParseSignal(stopSignal)
if err = task.Kill(ctx, stopSignal); err != nil && !errdefs.IsNotFound(err) { if err != nil {
return errors.Wrapf(err, "failed to parse stop signal %q", stopSignal)
}
logrus.Infof("Stop container %q with signal %v", id, sig)
if err = task.Kill(ctx, sig); err != nil && !errdefs.IsNotFound(err) {
return errors.Wrapf(err, "failed to stop container %q", id) return errors.Wrapf(err, "failed to stop container %q", id)
} }
......
...@@ -32,6 +32,7 @@ import ( ...@@ -32,6 +32,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
"k8s.io/apimachinery/pkg/util/clock" "k8s.io/apimachinery/pkg/util/clock"
"github.com/containerd/cri/pkg/constants"
ctrdutil "github.com/containerd/cri/pkg/containerd/util" ctrdutil "github.com/containerd/cri/pkg/containerd/util"
"github.com/containerd/cri/pkg/store" "github.com/containerd/cri/pkg/store"
containerstore "github.com/containerd/cri/pkg/store/container" containerstore "github.com/containerd/cri/pkg/store/container"
...@@ -83,7 +84,6 @@ type backOffQueue struct { ...@@ -83,7 +84,6 @@ type backOffQueue struct {
// Create new event monitor. New event monitor will start subscribing containerd event. All events // Create new event monitor. New event monitor will start subscribing containerd event. All events
// happen after it should be monitored. // happen after it should be monitored.
func newEventMonitor(c *criService) *eventMonitor { func newEventMonitor(c *criService) *eventMonitor {
// event subscribe doesn't need namespace.
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
return &eventMonitor{ return &eventMonitor{
c: c, c: c,
...@@ -95,6 +95,8 @@ func newEventMonitor(c *criService) *eventMonitor { ...@@ -95,6 +95,8 @@ func newEventMonitor(c *criService) *eventMonitor {
// subscribe starts to subscribe containerd events. // subscribe starts to subscribe containerd events.
func (em *eventMonitor) subscribe(subscriber events.Subscriber) { func (em *eventMonitor) subscribe(subscriber events.Subscriber) {
// note: filters are any match, if you want any match but not in namespace foo
// then you have to manually filter namespace foo
filters := []string{ filters := []string{
`topic=="/tasks/exit"`, `topic=="/tasks/exit"`,
`topic=="/tasks/oom"`, `topic=="/tasks/oom"`,
...@@ -142,6 +144,10 @@ func (em *eventMonitor) start() <-chan error { ...@@ -142,6 +144,10 @@ func (em *eventMonitor) start() <-chan error {
select { select {
case e := <-em.ch: case e := <-em.ch:
logrus.Debugf("Received containerd event timestamp - %v, namespace - %q, topic - %q", e.Timestamp, e.Namespace, e.Topic) logrus.Debugf("Received containerd event timestamp - %v, namespace - %q, topic - %q", e.Timestamp, e.Namespace, e.Topic)
if e.Namespace != constants.K8sContainerdNamespace {
logrus.Debugf("Ignoring events in namespace - %q", e.Namespace)
break
}
id, evt, err := convertEvent(e.Event) id, evt, err := convertEvent(e.Event)
if err != nil { if err != nil {
logrus.WithError(err).Errorf("Failed to convert event %+v", e) logrus.WithError(err).Errorf("Failed to convert event %+v", e)
......
...@@ -27,7 +27,7 @@ import ( ...@@ -27,7 +27,7 @@ import (
// 1) Metadata is immutable after created. // 1) Metadata is immutable after created.
// 2) Metadata is checkpointed as containerd container label. // 2) Metadata is checkpointed as containerd container label.
// metadataVersion is current version of container metadata. // metadataVersion is current version of container metadata.
const metadataVersion = "v1" // nolint const metadataVersion = "v1" // nolint
// versionedMetadata is the internal versioned container metadata. // versionedMetadata is the internal versioned container metadata.
...@@ -58,6 +58,9 @@ type Metadata struct { ...@@ -58,6 +58,9 @@ type Metadata struct {
ImageRef string ImageRef string
// LogPath is the container log path. // LogPath is the container log path.
LogPath string LogPath string
// StopSignal is the system call signal that will be sent to the container to exit.
// TODO(random-liu): Add integration test for stop signal.
StopSignal string
} }
// MarshalJSON encodes Metadata into bytes in json format. // MarshalJSON encodes Metadata into bytes in json format.
......
...@@ -132,11 +132,31 @@ func DirectRouting(ip net.IP) (bool, error) { ...@@ -132,11 +132,31 @@ func DirectRouting(ip net.IP) (bool, error) {
return false, nil return false, nil
} }
func linkAddrsAndRemoveLinkLocal(link netlink.Link) ([]netlink.Addr, error) {
existingAddrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
if err != nil {
return nil, err
}
var result []netlink.Addr
for _, addr := range existingAddrs {
if addr.IP.IsLinkLocalUnicast() {
if err := netlink.AddrDel(link, &addr); err != nil {
return nil, fmt.Errorf("failed to remove IP address %s from %s: %s", addr.IP.String(), link.Attrs().Name, err)
}
} else {
result = append(result, addr)
}
}
return result, nil
}
// EnsureV4AddressOnLink ensures that there is only one v4 Addr on `link` and it equals `ipn`. // EnsureV4AddressOnLink ensures that there is only one v4 Addr on `link` and it equals `ipn`.
// If there exist multiple addresses on link, it returns an error message to tell callers to remove additional address. // If there exist multiple addresses on link, it returns an error message to tell callers to remove additional address.
func EnsureV4AddressOnLink(ipn IP4Net, link netlink.Link) error { func EnsureV4AddressOnLink(ipn IP4Net, link netlink.Link) error {
addr := netlink.Addr{IPNet: ipn.ToIPNet()} addr := netlink.Addr{IPNet: ipn.ToIPNet()}
existingAddrs, err := netlink.AddrList(link, netlink.FAMILY_V4) existingAddrs, err := linkAddrsAndRemoveLinkLocal(link)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -149,7 +149,7 @@ func (g *Generic) List(ctx context.Context, revision, limit int64, rangeKey, sta ...@@ -149,7 +149,7 @@ func (g *Generic) List(ctx context.Context, revision, limit int64, rangeKey, sta
listRevision := atomic.LoadInt64(&g.revision) listRevision := atomic.LoadInt64(&g.revision)
if !strings.HasSuffix(rangeKey, "%") && revision <= 0 { if !strings.HasSuffix(rangeKey, "%") && revision <= 0 {
rows, err = g.QueryContext(ctx, g.GetSQL, rangeKey, limit) rows, err = g.QueryContext(ctx, g.GetSQL, rangeKey, 1)
} else if revision <= 0 { } else if revision <= 0 {
rows, err = g.QueryContext(ctx, g.ListSQL, rangeKey, limit) rows, err = g.QueryContext(ctx, g.ListSQL, rangeKey, limit)
} else if len(startKey) > 0 { } else if len(startKey) > 0 {
......
...@@ -133,7 +133,7 @@ func (c *Config) registerControllers(ctx context.Context, controllers []Controll ...@@ -133,7 +133,7 @@ func (c *Config) registerControllers(ctx context.Context, controllers []Controll
} }
func (c *Config) masterControllers(ctx context.Context, starters []controller.Starter, r *Runtime) { func (c *Config) masterControllers(ctx context.Context, starters []controller.Starter, r *Runtime) {
leader.RunOrDie(ctx, c.LeaderLockNamespace, c.Name, c.K8sClient, func(ctx context.Context) { f := func(ctx context.Context) {
var ( var (
err error err error
) )
...@@ -155,7 +155,13 @@ func (c *Config) masterControllers(ctx context.Context, starters []controller.St ...@@ -155,7 +155,13 @@ func (c *Config) masterControllers(ctx context.Context, starters []controller.St
} }
<-ctx.Done() <-ctx.Done()
}) }
if c.DisableLeaderElection {
go f(ctx)
} else {
leader.RunOrDie(ctx, c.LeaderLockNamespace, c.Name, c.K8sClient, f)
}
} }
func (c *Config) defaults(ctx context.Context, r *Runtime, opts Options) (context.Context, error) { func (c *Config) defaults(ctx context.Context, r *Runtime, opts Options) (context.Context, error) {
......
package condition
import (
"reflect"
"regexp"
"time"
"github.com/pkg/errors"
"github.com/rancher/norman/controller"
"github.com/rancher/norman/objectclient"
"k8s.io/api/core/v1"
err2 "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
type Cond string
var temfileRegexp = regexp.MustCompile("/tmp/[-_a-zA-Z0-9]+")
func (c Cond) True(obj runtime.Object) {
setStatus(obj, string(c), "True")
}
func (c Cond) IsTrue(obj runtime.Object) bool {
return getStatus(obj, string(c)) == "True"
}
func (c Cond) LastUpdated(obj runtime.Object, ts string) {
setTS(obj, string(c), ts)
}
func (c Cond) GetLastUpdated(obj runtime.Object) string {
return getTS(obj, string(c))
}
func (c Cond) False(obj runtime.Object) {
setStatus(obj, string(c), "False")
}
func (c Cond) IsFalse(obj runtime.Object) bool {
return getStatus(obj, string(c)) == "False"
}
func (c Cond) GetStatus(obj runtime.Object) string {
return getStatus(obj, string(c))
}
func (c Cond) SetStatus(obj runtime.Object, status string) {
setStatus(obj, string(c), status)
}
func (c Cond) Unknown(obj runtime.Object) {
setStatus(obj, string(c), "Unknown")
}
func (c Cond) CreateUnknownIfNotExists(obj runtime.Object) {
condSlice := getValue(obj, "Status", "Conditions")
cond := findCond(condSlice, string(c))
if cond == nil {
c.Unknown(obj)
}
}
func (c Cond) IsUnknown(obj runtime.Object) bool {
return getStatus(obj, string(c)) == "Unknown"
}
func (c Cond) Reason(obj runtime.Object, reason string) {
cond := findOrCreateCond(obj, string(c))
getFieldValue(cond, "Reason").SetString(reason)
}
func (c Cond) SetMessageIfBlank(obj runtime.Object, message string) {
if c.GetMessage(obj) == "" {
c.Message(obj, message)
}
}
func (c Cond) Message(obj runtime.Object, message string) {
cond := findOrCreateCond(obj, string(c))
setValue(cond, "Message", message)
}
func (c Cond) GetMessage(obj runtime.Object) string {
cond := findOrNotCreateCond(obj, string(c))
if cond == nil {
return ""
}
return getFieldValue(*cond, "Message").String()
}
func (c Cond) ReasonAndMessageFromError(obj runtime.Object, err error) {
if err2.IsConflict(err) {
return
}
cond := findOrCreateCond(obj, string(c))
setValue(cond, "Message", err.Error())
switch ce := err.(type) {
case *conditionError:
setValue(cond, "Reason", ce.reason)
case *controller.ForgetError:
if ce.Reason != "" {
setValue(cond, "Reason", ce.Reason)
} else {
setValue(cond, "Reason", "Error")
}
default:
setValue(cond, "Reason", "Error")
}
}
func (c Cond) GetReason(obj runtime.Object) string {
cond := findOrNotCreateCond(obj, string(c))
if cond == nil {
return ""
}
return getFieldValue(*cond, "Reason").String()
}
func (c Cond) Once(obj runtime.Object, f func() (runtime.Object, error)) (runtime.Object, error) {
if c.IsFalse(obj) {
return obj, &controller.ForgetError{
Err: errors.New(c.GetReason(obj)),
}
}
return c.DoUntilTrue(obj, f)
}
func (c Cond) DoUntilTrue(obj runtime.Object, f func() (runtime.Object, error)) (runtime.Object, error) {
if c.IsTrue(obj) {
return obj, nil
}
return c.do(obj, f)
}
func (c Cond) Do(obj runtime.Object, f func() (runtime.Object, error)) (runtime.Object, error) {
return c.do(obj, f)
}
type ObjectClientGetter interface {
ObjectClient() *objectclient.ObjectClient
}
func (c Cond) Track(obj runtime.Object, client ObjectClientGetter, f func() (runtime.Object, error)) (runtime.Object, error) {
obj = obj.DeepCopyObject()
retObj, changed, err := c.do2(false, obj, f)
if !changed {
return retObj, err
}
c.SetStatus(retObj, c.GetStatus(obj))
c.LastUpdated(retObj, c.GetLastUpdated(obj))
c.Reason(retObj, c.GetReason(obj))
c.Message(retObj, c.GetMessage(obj))
if obj, ok := retObj.(metav1.Object); ok {
updated, uerr := client.ObjectClient().Update(obj.GetName(), retObj)
if uerr == nil {
return updated, err
}
}
return retObj, err
}
func (c Cond) do(obj runtime.Object, f func() (runtime.Object, error)) (runtime.Object, error) {
obj, _, err := c.do2(true, obj, f)
return obj, err
}
func (c Cond) do2(setReturned bool, obj runtime.Object, f func() (runtime.Object, error)) (runtime.Object, bool, error) {
status := c.GetStatus(obj)
ts := c.GetLastUpdated(obj)
reason := c.GetReason(obj)
message := c.GetMessage(obj)
checkObj := obj
retObj, err := c.doInternal(setReturned, obj, f)
if setReturned {
checkObj = retObj
}
// This is to prevent non stop flapping of states and update
if status == c.GetStatus(checkObj) &&
reason == c.GetReason(checkObj) {
if message != c.GetMessage(checkObj) {
replaced := temfileRegexp.ReplaceAllString(c.GetMessage(checkObj), "file_path_redacted")
c.Message(checkObj, replaced)
}
if message == c.GetMessage(checkObj) {
c.LastUpdated(checkObj, ts)
}
}
changed := status != c.GetStatus(checkObj) ||
ts != c.GetLastUpdated(checkObj) ||
reason != c.GetReason(checkObj) ||
message != c.GetMessage(checkObj)
return retObj, changed, err
}
func (c Cond) doInternal(setReturned bool, obj runtime.Object, f func() (runtime.Object, error)) (runtime.Object, error) {
if !c.IsFalse(obj) {
c.Unknown(obj)
}
setObject := obj
newObj, err := f()
if newObj != nil && !reflect.ValueOf(newObj).IsNil() {
obj = newObj
if setReturned {
setObject = obj
}
}
if err != nil {
if _, ok := err.(*controller.ForgetError); ok {
if c.GetMessage(setObject) == "" {
c.ReasonAndMessageFromError(setObject, err)
}
return obj, err
}
c.False(setObject)
c.ReasonAndMessageFromError(setObject, err)
return obj, err
}
c.True(setObject)
c.Reason(setObject, "")
c.Message(setObject, "")
return obj, nil
}
func touchTS(value reflect.Value) {
now := time.Now().Format(time.RFC3339)
getFieldValue(value, "LastUpdateTime").SetString(now)
}
func getStatus(obj interface{}, condName string) string {
cond := findOrNotCreateCond(obj, condName)
if cond == nil {
return ""
}
return getFieldValue(*cond, "Status").String()
}
func setTS(obj interface{}, condName, ts string) {
cond := findOrCreateCond(obj, condName)
getFieldValue(cond, "LastUpdateTime").SetString(ts)
}
func getTS(obj interface{}, condName string) string {
cond := findOrNotCreateCond(obj, condName)
if cond == nil {
return ""
}
return getFieldValue(*cond, "LastUpdateTime").String()
}
func setStatus(obj interface{}, condName, status string) {
cond := findOrCreateCond(obj, condName)
setValue(cond, "Status", status)
}
func setValue(cond reflect.Value, fieldName, newValue string) {
value := getFieldValue(cond, fieldName)
if value.String() != newValue {
value.SetString(newValue)
touchTS(cond)
}
}
func findOrNotCreateCond(obj interface{}, condName string) *reflect.Value {
condSlice := getValue(obj, "Status", "Conditions")
return findCond(condSlice, condName)
}
func findOrCreateCond(obj interface{}, condName string) reflect.Value {
condSlice := getValue(obj, "Status", "Conditions")
cond := findCond(condSlice, condName)
if cond != nil {
return *cond
}
newCond := reflect.New(condSlice.Type().Elem()).Elem()
newCond.FieldByName("Type").SetString(condName)
newCond.FieldByName("Status").SetString("Unknown")
condSlice.Set(reflect.Append(condSlice, newCond))
return *findCond(condSlice, condName)
}
func findCond(val reflect.Value, name string) *reflect.Value {
for i := 0; i < val.Len(); i++ {
cond := val.Index(i)
typeVal := getFieldValue(cond, "Type")
if typeVal.String() == name {
return &cond
}
}
return nil
}
func getValue(obj interface{}, name ...string) reflect.Value {
if obj == nil {
return reflect.Value{}
}
v := reflect.ValueOf(obj)
t := v.Type()
if t.Kind() == reflect.Ptr {
v = v.Elem()
t = v.Type()
}
field := v.FieldByName(name[0])
if len(name) == 1 {
return field
}
return getFieldValue(field, name[1:]...)
}
func getFieldValue(v reflect.Value, name ...string) reflect.Value {
field := v.FieldByName(name[0])
if len(name) == 1 {
return field
}
return getFieldValue(field, name[1:]...)
}
func Error(reason string, err error) error {
return &conditionError{
reason: reason,
message: err.Error(),
}
}
type conditionError struct {
reason string
message string
}
func (e *conditionError) Error() string {
return e.message
}
type GenericCondition struct {
// Type of cluster condition.
Type string `json:"type"`
// Status of the condition, one of True, False, Unknown.
Status v1.ConditionStatus `json:"status"`
// The last time this condition was updated.
LastUpdateTime string `json:"lastUpdateTime,omitempty"`
// Last time the condition transitioned from one status to another.
LastTransitionTime string `json:"lastTransitionTime,omitempty"`
// The reason for the condition's last transition.
Reason string `json:"reason,omitempty"`
// Human-readable message indicating details about last transition
Message string `json:"message,omitempty"`
}
...@@ -304,7 +304,7 @@ func filterConflictsError(err error) error { ...@@ -304,7 +304,7 @@ func filterConflictsError(err error) error {
var newErrors []error var newErrors []error
for _, err := range errs.Errors { for _, err := range errs.Errors {
if !ignoreError(err, true) { if !ignoreError(err, true) {
newErrors = append(newErrors) newErrors = append(newErrors, err)
} }
} }
return types.NewErrors(newErrors...) return types.NewErrors(newErrors...)
......
...@@ -264,7 +264,7 @@ func CheckFieldCriteria(fieldName string, field types.Field, value interface{}) ...@@ -264,7 +264,7 @@ func CheckFieldCriteria(fieldName string, field types.Field, value interface{})
} }
} }
if hasStrVal { if hasStrVal || value == "" {
if field.MinLength != nil && int64(len(strVal)) < *field.MinLength { if field.MinLength != nil && int64(len(strVal)) < *field.MinLength {
return httperror.NewFieldAPIError(httperror.MinLengthExceeded, fieldName, "") return httperror.NewFieldAPIError(httperror.MinLengthExceeded, fieldName, "")
} }
......
package changeset
import (
"context"
"strings"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/runtime"
)
type Key struct {
Namespace string
Name string
}
type ControllerProvider interface {
Generic() controller.GenericController
}
type Enqueuer interface {
Enqueue(namespace, name string)
}
type Resolver func(namespace, name string, obj runtime.Object) ([]Key, error)
func Watch(ctx context.Context, name string, resolve Resolver, enq Enqueuer, controllers ...ControllerProvider) {
for _, c := range controllers {
watch(ctx, name, enq, resolve, c.Generic())
}
}
func watch(ctx context.Context, name string, enq Enqueuer, resolve Resolver, genericController controller.GenericController) {
genericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
obj, exists, err := genericController.Informer().GetStore().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
obj = nil
}
var (
ns string
name string
)
parts := strings.SplitN(key, "/", 2)
if len(parts) == 2 {
ns = parts[0]
name = parts[1]
} else {
name = parts[0]
}
ro, ok := obj.(runtime.Object)
if !ok {
ro = nil
}
keys, err := resolve(ns, name, ro)
if err != nil {
return nil, err
}
for _, key := range keys {
if key.Name != "" {
enq.Enqueue(key.Namespace, key.Name)
}
}
return nil, nil
})
}
...@@ -45,10 +45,11 @@ type server struct { ...@@ -45,10 +45,11 @@ type server struct {
servers []*http.Server servers []*http.Server
// dynamic config change on refresh // dynamic config change on refresh
activeCert *tls.Certificate activeCert *tls.Certificate
activeCA *x509.Certificate activeCA *x509.Certificate
activeCAKey *rsa.PrivateKey activeCAKey *rsa.PrivateKey
domains map[string]bool activeCAKeyString string
domains map[string]bool
} }
func NewServer(listenConfigStorage ListenerConfigStorage, config UserConfig) (ServerInterface, error) { func NewServer(listenConfigStorage ListenerConfigStorage, config UserConfig) (ServerInterface, error) {
...@@ -98,6 +99,9 @@ func (s *server) save() { ...@@ -98,6 +99,9 @@ func (s *server) save() {
return return
} }
s.Lock()
defer s.Unlock()
changed := false changed := false
cfg, err := s.listenConfigStorage.Get() cfg, err := s.listenConfigStorage.Get()
if apierrors.IsNotFound(err) { if apierrors.IsNotFound(err) {
...@@ -149,6 +153,7 @@ func (s *server) save() { ...@@ -149,6 +153,7 @@ func (s *server) save() {
cfg.CACert = string(caCertBuffer.Bytes()) cfg.CACert = string(caCertBuffer.Bytes())
cfg.CAKey = string(caKeyBuffer.Bytes()) cfg.CAKey = string(caKeyBuffer.Bytes())
s.activeCAKeyString = cfg.CAKey
changed = true changed = true
} }
...@@ -185,6 +190,13 @@ func (s *server) userConfigure() error { ...@@ -185,6 +190,13 @@ func (s *server) userConfigure() error {
return s.reload() return s.reload()
} }
for _, ip := range s.userConfig.KnownIPs {
netIP := net.ParseIP(ip)
if netIP != nil {
s.ips.Add(ip, netIP)
}
}
return nil return nil
} }
...@@ -210,18 +222,20 @@ func (s *server) Update(status *ListenerStatus) error { ...@@ -210,18 +222,20 @@ func (s *server) Update(status *ListenerStatus) error {
defer s.getCertificate(&tls.ClientHelloInfo{ServerName: "localhost"}) defer s.getCertificate(&tls.ClientHelloInfo{ServerName: "localhost"})
defer s.Unlock() defer s.Unlock()
if status.CACert != "" && status.CAKey != "" { if status.CACert != "" && status.CAKey != "" && s.activeCAKeyString != status.CAKey {
cert, err := tls.X509KeyPair([]byte(status.CACert), []byte(status.CAKey)) cert, err := tls.X509KeyPair([]byte(status.CACert), []byte(status.CAKey))
if err != nil { if err != nil {
return err return err
} }
s.activeCAKey = cert.PrivateKey.(*rsa.PrivateKey) s.activeCAKey = cert.PrivateKey.(*rsa.PrivateKey)
s.activeCAKeyString = status.CAKey
x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil { if err != nil {
return err return err
} }
s.activeCA = x509Cert s.activeCA = x509Cert
s.certs = map[string]*tls.Certificate{}
} }
for ipStr := range status.KnownIPs { for ipStr := range status.KnownIPs {
...@@ -324,11 +338,11 @@ func (s *server) ipMapKey() string { ...@@ -324,11 +338,11 @@ func (s *server) ipMapKey() string {
func (s *server) getCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { func (s *server) getCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
s.Lock() s.Lock()
defer s.Unlock()
if s.activeCert != nil { if s.activeCert != nil {
s.Unlock()
return s.activeCert, nil return s.activeCert, nil
} }
defer s.Unlock()
mapKey := hello.ServerName mapKey := hello.ServerName
cn := hello.ServerName cn := hello.ServerName
......
...@@ -26,6 +26,7 @@ type UserConfig struct { ...@@ -26,6 +26,7 @@ type UserConfig struct {
// Optional fields // Optional fields
KnownIPs []string
Domains []string Domains []string
Mode string Mode string
NoCACerts bool NoCACerts bool
......
...@@ -19,6 +19,7 @@ type DesiredSet struct { ...@@ -19,6 +19,7 @@ type DesiredSet struct {
objs *ObjectSet objs *ObjectSet
codeVersion string codeVersion string
clients map[schema.GroupVersionKind]Client clients map[schema.GroupVersionKind]Client
patchers map[schema.GroupVersionKind]Patcher
owner runtime.Object owner runtime.Object
injectors []injectors.ConfigInjector injectors []injectors.ConfigInjector
errs []error errs []error
......
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
"github.com/rancher/norman/types/convert" "github.com/rancher/norman/types/convert"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
...@@ -133,7 +133,7 @@ func sanitizePatch(patch []byte) ([]byte, error) { ...@@ -133,7 +133,7 @@ func sanitizePatch(patch []byte) ([]byte, error) {
return json.Marshal(data) return json.Marshal(data)
} }
func applyPatch(client objectclient.GenericClient, debugID, inputID string, oldObject, newObject runtime.Object) (bool, error) { func applyPatch(patcher Patcher, client objectclient.GenericClient, debugID, inputID string, oldObject, newObject runtime.Object) (bool, error) {
gvk := client.GroupVersionKind() gvk := client.GroupVersionKind()
oldMetadata, err := meta.Accessor(oldObject) oldMetadata, err := meta.Accessor(oldObject)
...@@ -173,19 +173,19 @@ func applyPatch(client objectclient.GenericClient, debugID, inputID string, oldO ...@@ -173,19 +173,19 @@ func applyPatch(client objectclient.GenericClient, debugID, inputID string, oldO
patch, original, modified, current) patch, original, modified, current)
logrus.Debugf("DesiredSet - Updated %s %s/%s for %s -- %s %s", gvk, oldMetadata.GetNamespace(), oldMetadata.GetName(), debugID, patchType, patch) logrus.Debugf("DesiredSet - Updated %s %s/%s for %s -- %s %s", gvk, oldMetadata.GetNamespace(), oldMetadata.GetName(), debugID, patchType, patch)
_, err = client.Patch(oldMetadata.GetName(), oldObject, patchType, patch) _, err = patcher(oldMetadata.GetName(), oldObject, patchType, patch)
return true, err return true, err
} }
func (o *DesiredSet) compareObjects(client objectclient.GenericClient, debugID, inputID string, oldObject, newObject runtime.Object, force bool) error { func (o *DesiredSet) compareObjects(patcher Patcher, client objectclient.GenericClient, debugID, inputID string, oldObject, newObject runtime.Object, force bool) error {
oldMetadata, err := meta.Accessor(oldObject) oldMetadata, err := meta.Accessor(oldObject)
if err != nil { if err != nil {
return err return err
} }
gvk := client.GroupVersionKind() gvk := client.GroupVersionKind()
if ran, err := applyPatch(client, debugID, inputID, oldObject, newObject); err != nil { if ran, err := applyPatch(patcher, client, debugID, inputID, oldObject, newObject); err != nil {
return err return err
} else if !ran { } else if !ran {
logrus.Debugf("DesiredSet - No change(2) %s %s/%s for %s", gvk, oldMetadata.GetNamespace(), oldMetadata.GetName(), debugID) logrus.Debugf("DesiredSet - No change(2) %s %s/%s for %s", gvk, oldMetadata.GetNamespace(), oldMetadata.GetName(), debugID)
......
...@@ -18,13 +18,18 @@ import ( ...@@ -18,13 +18,18 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
types2 "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
) )
var ( var (
deletePolicy = v1.DeletePropagationBackground deletePolicy = v1.DeletePropagationBackground
ErrReplace = errors.New("replace object with changes")
ReplaceOnChange = func(name string, o runtime.Object, patchType types2.PatchType, data []byte, subresources ...string) (runtime.Object, error) {
return nil, ErrReplace
}
) )
func NewDiscoveredClient(gvk schema.GroupVersionKind, restConfig rest.Config, discovery discovery.DiscoveryInterface) (*objectclient.ObjectClient, error) { func NewDiscoveredClient(gvk schema.GroupVersionKind, restConfig rest.Config, discovery discovery.DiscoveryInterface) (*objectclient.ObjectClient, error) {
...@@ -85,6 +90,11 @@ func (o *DesiredSet) process(inputID, debugID string, set labels.Selector, gvk s ...@@ -85,6 +90,11 @@ func (o *DesiredSet) process(inputID, debugID string, set labels.Selector, gvk s
return return
} }
patcher, ok := o.patchers[gvk]
if !ok {
patcher = objectClient.Patch
}
existing, err := list(controller, objectClient, set) existing, err := list(controller, objectClient, set)
if err != nil { if err != nil {
o.err(fmt.Errorf("failed to list %s for %s", gvk, debugID)) o.err(fmt.Errorf("failed to list %s for %s", gvk, debugID))
...@@ -92,12 +102,13 @@ func (o *DesiredSet) process(inputID, debugID string, set labels.Selector, gvk s ...@@ -92,12 +102,13 @@ func (o *DesiredSet) process(inputID, debugID string, set labels.Selector, gvk s
} }
toCreate, toDelete, toUpdate := compareSets(existing, objs) toCreate, toDelete, toUpdate := compareSets(existing, objs)
for _, k := range toCreate {
createF := func(k objectKey) {
obj := objs[k] obj := objs[k]
obj, err := prepareObjectForCreate(inputID, obj) obj, err := prepareObjectForCreate(inputID, obj)
if err != nil { if err != nil {
o.err(errors.Wrapf(err, "failed to prepare create %s %s for %s", k, gvk, debugID)) o.err(errors.Wrapf(err, "failed to prepare create %s %s for %s", k, gvk, debugID))
continue return
} }
_, err = objectClient.Create(obj) _, err = objectClient.Create(obj)
...@@ -107,34 +118,48 @@ func (o *DesiredSet) process(inputID, debugID string, set labels.Selector, gvk s ...@@ -107,34 +118,48 @@ func (o *DesiredSet) process(inputID, debugID string, set labels.Selector, gvk s
if err == nil { if err == nil {
toUpdate = append(toUpdate, k) toUpdate = append(toUpdate, k)
existing[k] = existingObj existing[k] = existingObj
continue return
} }
} }
if err != nil { if err != nil {
o.err(errors.Wrapf(err, "failed to create %s %s for %s", k, gvk, debugID)) o.err(errors.Wrapf(err, "failed to create %s %s for %s", k, gvk, debugID))
continue return
} }
logrus.Debugf("DesiredSet - Created %s %s for %s", gvk, k, debugID) logrus.Debugf("DesiredSet - Created %s %s for %s", gvk, k, debugID)
} }
for _, k := range toUpdate { deleteF := func(k objectKey) {
err := o.compareObjects(objectClient, debugID, inputID, existing[k], objs[k], len(toCreate) > 0 || len(toDelete) > 0)
if err != nil {
o.err(errors.Wrapf(err, "failed to update %s %s for %s", k, gvk, debugID))
continue
}
}
for _, k := range toDelete {
err := objectClient.DeleteNamespaced(k.namespace, k.name, &v1.DeleteOptions{ err := objectClient.DeleteNamespaced(k.namespace, k.name, &v1.DeleteOptions{
PropagationPolicy: &deletePolicy, PropagationPolicy: &deletePolicy,
}) })
if err != nil { if err != nil {
o.err(errors.Wrapf(err, "failed to delete %s %s for %s", k, gvk, debugID)) o.err(errors.Wrapf(err, "failed to delete %s %s for %s", k, gvk, debugID))
continue return
} }
logrus.Debugf("DesiredSet - Delete %s %s for %s", gvk, k, debugID) logrus.Debugf("DesiredSet - Delete %s %s for %s", gvk, k, debugID)
} }
updateF := func(k objectKey) {
err := o.compareObjects(patcher, objectClient, debugID, inputID, existing[k], objs[k], len(toCreate) > 0 || len(toDelete) > 0)
if err == ErrReplace {
deleteF(k)
o.err(fmt.Errorf("DesiredSet - Replace Wait %s %s for %s", gvk, k, debugID))
} else if err != nil {
o.err(errors.Wrapf(err, "failed to update %s %s for %s", k, gvk, debugID))
}
}
for _, k := range toCreate {
createF(k)
}
for _, k := range toUpdate {
updateF(k)
}
for _, k := range toDelete {
deleteF(k)
}
} }
func compareSets(existingSet, newSet map[objectKey]runtime.Object) (toCreate, toDelete, toUpdate []objectKey) { func compareSets(existingSet, newSet map[objectKey]runtime.Object) (toCreate, toDelete, toUpdate []objectKey) {
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"github.com/rancher/norman/objectclient" "github.com/rancher/norman/objectclient"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
) )
...@@ -14,6 +15,8 @@ type Client interface { ...@@ -14,6 +15,8 @@ type Client interface {
ObjectClient() *objectclient.ObjectClient ObjectClient() *objectclient.ObjectClient
} }
type Patcher func(name string, o runtime.Object, patchType types.PatchType, data []byte, subresources ...string) (runtime.Object, error)
type Processor struct { type Processor struct {
setID string setID string
codeVersion string codeVersion string
...@@ -22,6 +25,7 @@ type Processor struct { ...@@ -22,6 +25,7 @@ type Processor struct {
allowSlowPath string allowSlowPath string
slowClient rest.HTTPClient slowClient rest.HTTPClient
clients map[schema.GroupVersionKind]Client clients map[schema.GroupVersionKind]Client
patchers map[schema.GroupVersionKind]Patcher
} }
func NewProcessor(setID string) *Processor { func NewProcessor(setID string) *Processor {
...@@ -59,6 +63,14 @@ func (t *Processor) Client(clients ...Client) *Processor { ...@@ -59,6 +63,14 @@ func (t *Processor) Client(clients ...Client) *Processor {
return t return t
} }
func (t *Processor) Patcher(gvk schema.GroupVersionKind, patcher Patcher) *Processor {
if t.patchers == nil {
t.patchers = map[schema.GroupVersionKind]Patcher{}
}
t.patchers[gvk] = patcher
return t
}
func (t Processor) Remove(owner runtime.Object) error { func (t Processor) Remove(owner runtime.Object) error {
return t.NewDesiredSet(owner, nil).Apply() return t.NewDesiredSet(owner, nil).Apply()
} }
...@@ -77,6 +89,7 @@ func (t Processor) NewDesiredSet(owner runtime.Object, objs *ObjectSet) *Desired ...@@ -77,6 +89,7 @@ func (t Processor) NewDesiredSet(owner runtime.Object, objs *ObjectSet) *Desired
setID: t.setID, setID: t.setID,
codeVersion: t.codeVersion, codeVersion: t.codeVersion,
clients: t.clients, clients: t.clients,
patchers: t.patchers,
owner: owner, owner: owner,
} }
} }
...@@ -18,20 +18,21 @@ type ClientFactory func(context.Context, rest.Config) (context.Context, controll ...@@ -18,20 +18,21 @@ type ClientFactory func(context.Context, rest.Config) (context.Context, controll
type ControllerRegister func(ctx context.Context) error type ControllerRegister func(ctx context.Context) error
type Config struct { type Config struct {
Name string Name string
EnableAPI bool EnableAPI bool
Schemas []*types.Schemas Schemas []*types.Schemas
CRDs map[*types.APIVersion][]string CRDs map[*types.APIVersion][]string
Clients []ClientFactory Clients []ClientFactory
ClientGetter proxy.ClientGetter ClientGetter proxy.ClientGetter
CRDStorageContext types.StorageContext CRDStorageContext types.StorageContext
K8sClient kubernetes.Interface K8sClient kubernetes.Interface
APIExtClient clientset.Interface APIExtClient clientset.Interface
Config *rest.Config Config *rest.Config
LeaderLockNamespace string DisableLeaderElection bool
KubeConfig string LeaderLockNamespace string
IgnoredKubeConfigEnv bool KubeConfig string
Threadiness int IgnoredKubeConfigEnv bool
Threadiness int
CustomizeSchemas func(context.Context, proxy.ClientGetter, *types.Schemas) error CustomizeSchemas func(context.Context, proxy.ClientGetter, *types.Schemas) error
GlobalSetup func(context.Context) (context.Context, error) GlobalSetup func(context.Context) (context.Context, error)
......
...@@ -4,16 +4,15 @@ Go is an open source project. ...@@ -4,16 +4,15 @@ Go is an open source project.
It is the work of hundreds of contributors. We appreciate your help! It is the work of hundreds of contributors. We appreciate your help!
## Filing issues ## Filing issues
When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
1. What version of Go are you using (`go version`)? 1. What version of Go are you using (`go version`)?
2. What operating system and processor architecture are you using? 2. What operating system and processor architecture are you using?
3. What did you do? 3. What did you do?
4. What did you expect to see? 4. What did you expect to see?
5. What did you see instead? 5. What did you see instead?
General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
The gophers there will answer or ask you to file an issue if you've tripped over a bug. The gophers there will answer or ask you to file an issue if you've tripped over a bug.
...@@ -23,9 +22,5 @@ The gophers there will answer or ask you to file an issue if you've tripped over ...@@ -23,9 +22,5 @@ The gophers there will answer or ask you to file an issue if you've tripped over
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
before sending patches. before sending patches.
**We do not accept GitHub pull requests**
(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
Unless otherwise noted, the Go source files are distributed under Unless otherwise noted, the Go source files are distributed under
the BSD-style license found in the LICENSE file. the BSD-style license found in the LICENSE file.
// 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.
// CPU affinity functions
package unix
import (
"unsafe"
)
const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
// CPUSet represents a CPU affinity mask.
type CPUSet [cpuSetSize]cpuMask
func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
if e != 0 {
return errnoErr(e)
}
return nil
}
// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
// If pid is 0 the calling thread is used.
func SchedGetaffinity(pid int, set *CPUSet) error {
return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
}
// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
// If pid is 0 the calling thread is used.
func SchedSetaffinity(pid int, set *CPUSet) error {
return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
}
// Zero clears the set s, so that it contains no CPUs.
func (s *CPUSet) Zero() {
for i := range s {
s[i] = 0
}
}
func cpuBitsIndex(cpu int) int {
return cpu / _NCPUBITS
}
func cpuBitsMask(cpu int) cpuMask {
return cpuMask(1 << (uint(cpu) % _NCPUBITS))
}
// Set adds cpu to the set s.
func (s *CPUSet) Set(cpu int) {
i := cpuBitsIndex(cpu)
if i < len(s) {
s[i] |= cpuBitsMask(cpu)
}
}
// Clear removes cpu from the set s.
func (s *CPUSet) Clear(cpu int) {
i := cpuBitsIndex(cpu)
if i < len(s) {
s[i] &^= cpuBitsMask(cpu)
}
}
// IsSet reports whether cpu is in the set s.
func (s *CPUSet) IsSet(cpu int) bool {
i := cpuBitsIndex(cpu)
if i < len(s) {
return s[i]&cpuBitsMask(cpu) != 0
}
return false
}
// Count returns the number of CPUs in the set s.
func (s *CPUSet) Count() int {
c := 0
for _, b := range s {
c += onesCount64(uint64(b))
}
return c
}
// onesCount64 is a copy of Go 1.9's math/bits.OnesCount64.
// Once this package can require Go 1.9, we can delete this
// and update the caller to use bits.OnesCount64.
func onesCount64(x uint64) int {
const m0 = 0x5555555555555555 // 01010101 ...
const m1 = 0x3333333333333333 // 00110011 ...
const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
const m3 = 0x00ff00ff00ff00ff // etc.
const m4 = 0x0000ffff0000ffff
// Implementation: Parallel summing of adjacent bits.
// See "Hacker's Delight", Chap. 5: Counting Bits.
// The following pattern shows the general approach:
//
// x = x>>1&(m0&m) + x&(m0&m)
// x = x>>2&(m1&m) + x&(m1&m)
// x = x>>4&(m2&m) + x&(m2&m)
// x = x>>8&(m3&m) + x&(m3&m)
// x = x>>16&(m4&m) + x&(m4&m)
// x = x>>32&(m5&m) + x&(m5&m)
// return int(x)
//
// Masking (& operations) can be left away when there's no
// danger that a field's sum will carry over into the next
// field: Since the result cannot be > 64, 8 bits is enough
// and we can ignore the masks for the shifts by 8 and up.
// Per "Hacker's Delight", the first line can be simplified
// more, but it saves at best one instruction, so we leave
// it alone for clarity.
const m = 1<<64 - 1
x = x>>1&(m0&m) + x&(m0&m)
x = x>>2&(m1&m) + x&(m1&m)
x = (x>>4 + x) & (m2 & m)
x += x >> 8
x += x >> 16
x += x >> 32
return int(x) & (1<<7 - 1)
}
...@@ -13,17 +13,17 @@ ...@@ -13,17 +13,17 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-64 TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB) JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-88 TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB) JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-112 TEXT ·Syscall9(SB),NOSPLIT,$0-104
JMP syscall·Syscall9(SB) JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-64 TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB) JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-88 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB) JMP syscall·RawSyscall6(SB)
...@@ -10,21 +10,51 @@ ...@@ -10,21 +10,51 @@
// System calls for 386, Linux // System calls for 386, Linux
// //
// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
// instead of the glibc-specific "CALL 0x10(GS)".
#define INVOKE_SYSCALL INT $0x80
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-28 TEXT ·Syscall(SB),NOSPLIT,$0-28
JMP syscall·Syscall(SB) JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-40 TEXT ·Syscall6(SB),NOSPLIT,$0-40
JMP syscall·Syscall6(SB) JMP syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
CALL runtime·entersyscall(SB)
MOVL trap+0(FP), AX // syscall entry
MOVL a1+4(FP), BX
MOVL a2+8(FP), CX
MOVL a3+12(FP), DX
MOVL $0, SI
MOVL $0, DI
INVOKE_SYSCALL
MOVL AX, r1+16(FP)
MOVL DX, r2+20(FP)
CALL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 TEXT ·RawSyscall(SB),NOSPLIT,$0-28
JMP syscall·RawSyscall(SB) JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
JMP syscall·RawSyscall6(SB) JMP syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
MOVL trap+0(FP), AX // syscall entry
MOVL a1+4(FP), BX
MOVL a2+8(FP), CX
MOVL a3+12(FP), DX
MOVL $0, SI
MOVL $0, DI
INVOKE_SYSCALL
MOVL AX, r1+16(FP)
MOVL DX, r2+20(FP)
RET
TEXT ·socketcall(SB),NOSPLIT,$0-36 TEXT ·socketcall(SB),NOSPLIT,$0-36
JMP syscall·socketcall(SB) JMP syscall·socketcall(SB)
......
...@@ -13,17 +13,45 @@ ...@@ -13,17 +13,45 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56 TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB) JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80 TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB) JMP syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
CALL runtime·entersyscall(SB)
MOVQ a1+8(FP), DI
MOVQ a2+16(FP), SI
MOVQ a3+24(FP), DX
MOVQ $0, R10
MOVQ $0, R8
MOVQ $0, R9
MOVQ trap+0(FP), AX // syscall entry
SYSCALL
MOVQ AX, r1+32(FP)
MOVQ DX, r2+40(FP)
CALL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB) JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB) JMP syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVQ a1+8(FP), DI
MOVQ a2+16(FP), SI
MOVQ a3+24(FP), DX
MOVQ $0, R10
MOVQ $0, R8
MOVQ $0, R9
MOVQ trap+0(FP), AX // syscall entry
SYSCALL
MOVQ AX, r1+32(FP)
MOVQ DX, r2+40(FP)
RET
TEXT ·gettimeofday(SB),NOSPLIT,$0-16 TEXT ·gettimeofday(SB),NOSPLIT,$0-16
JMP syscall·gettimeofday(SB) JMP syscall·gettimeofday(SB)
...@@ -13,17 +13,44 @@ ...@@ -13,17 +13,44 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-28 TEXT ·Syscall(SB),NOSPLIT,$0-28
B syscall·Syscall(SB) B syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-40 TEXT ·Syscall6(SB),NOSPLIT,$0-40
B syscall·Syscall6(SB) B syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
BL runtime·entersyscall(SB)
MOVW trap+0(FP), R7
MOVW a1+4(FP), R0
MOVW a2+8(FP), R1
MOVW a3+12(FP), R2
MOVW $0, R3
MOVW $0, R4
MOVW $0, R5
SWI $0
MOVW R0, r1+16(FP)
MOVW $0, R0
MOVW R0, r2+20(FP)
BL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 TEXT ·RawSyscall(SB),NOSPLIT,$0-28
B syscall·RawSyscall(SB) B syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
B syscall·RawSyscall6(SB) B syscall·RawSyscall6(SB)
TEXT ·seek(SB),NOSPLIT,$0-32 TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
MOVW trap+0(FP), R7 // syscall entry
MOVW a1+4(FP), R0
MOVW a2+8(FP), R1
MOVW a3+12(FP), R2
SWI $0
MOVW R0, r1+16(FP)
MOVW $0, R0
MOVW R0, r2+20(FP)
RET
TEXT ·seek(SB),NOSPLIT,$0-28
B syscall·seek(SB) B syscall·seek(SB)
...@@ -11,14 +11,42 @@ ...@@ -11,14 +11,42 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56 TEXT ·Syscall(SB),NOSPLIT,$0-56
B syscall·Syscall(SB) B syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80 TEXT ·Syscall6(SB),NOSPLIT,$0-80
B syscall·Syscall6(SB) B syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
BL runtime·entersyscall(SB)
MOVD a1+8(FP), R0
MOVD a2+16(FP), R1
MOVD a3+24(FP), R2
MOVD $0, R3
MOVD $0, R4
MOVD $0, R5
MOVD trap+0(FP), R8 // syscall entry
SVC
MOVD R0, r1+32(FP) // r1
MOVD R1, r2+40(FP) // r2
BL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 TEXT ·RawSyscall(SB),NOSPLIT,$0-56
B syscall·RawSyscall(SB) B syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
B syscall·RawSyscall6(SB) B syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R0
MOVD a2+16(FP), R1
MOVD a3+24(FP), R2
MOVD $0, R3
MOVD $0, R4
MOVD $0, R5
MOVD trap+0(FP), R8 // syscall entry
SVC
MOVD R0, r1+32(FP)
MOVD R1, r2+40(FP)
RET
...@@ -15,14 +15,42 @@ ...@@ -15,14 +15,42 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56 TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB) JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80 TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB) JMP syscall·Syscall6(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 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), R2 // syscall entry
SYSCALL
MOVV R2, r1+32(FP)
MOVV R3, r2+40(FP)
JAL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB) JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB) 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), R2 // syscall entry
SYSCALL
MOVV R2, r1+32(FP)
MOVV R3, r2+40(FP)
RET
...@@ -15,17 +15,40 @@ ...@@ -15,17 +15,40 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-28 TEXT ·Syscall(SB),NOSPLIT,$0-28
JMP syscall·Syscall(SB) JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-40 TEXT ·Syscall6(SB),NOSPLIT,$0-40
JMP syscall·Syscall6(SB) JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-52 TEXT ·Syscall9(SB),NOSPLIT,$0-52
JMP syscall·Syscall9(SB) JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
JAL runtime·entersyscall(SB)
MOVW a1+4(FP), R4
MOVW a2+8(FP), R5
MOVW a3+12(FP), R6
MOVW R0, R7
MOVW trap+0(FP), R2 // syscall entry
SYSCALL
MOVW R2, r1+16(FP) // r1
MOVW R3, r2+20(FP) // r2
JAL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
JMP syscall·RawSyscall(SB) JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
JMP syscall·RawSyscall6(SB) JMP syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
MOVW a1+4(FP), R4
MOVW a2+8(FP), R5
MOVW a3+12(FP), R6
MOVW trap+0(FP), R2 // syscall entry
SYSCALL
MOVW R2, r1+16(FP)
MOVW R3, r2+20(FP)
RET
...@@ -15,14 +15,42 @@ ...@@ -15,14 +15,42 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56 TEXT ·Syscall(SB),NOSPLIT,$0-56
BR syscall·Syscall(SB) BR syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80 TEXT ·Syscall6(SB),NOSPLIT,$0-80
BR syscall·Syscall6(SB) BR syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
BL runtime·entersyscall(SB)
MOVD a1+8(FP), R3
MOVD a2+16(FP), R4
MOVD a3+24(FP), R5
MOVD R0, R6
MOVD R0, R7
MOVD R0, R8
MOVD trap+0(FP), R9 // syscall entry
SYSCALL R9
MOVD R3, r1+32(FP)
MOVD R4, r2+40(FP)
BL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 TEXT ·RawSyscall(SB),NOSPLIT,$0-56
BR syscall·RawSyscall(SB) BR syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
BR syscall·RawSyscall6(SB) BR syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R3
MOVD a2+16(FP), R4
MOVD a3+24(FP), R5
MOVD R0, R6
MOVD R0, R7
MOVD R0, R8
MOVD trap+0(FP), R9 // syscall entry
SYSCALL R9
MOVD R3, r1+32(FP)
MOVD R4, r2+40(FP)
RET
...@@ -21,8 +21,36 @@ TEXT ·Syscall(SB),NOSPLIT,$0-56 ...@@ -21,8 +21,36 @@ TEXT ·Syscall(SB),NOSPLIT,$0-56
TEXT ·Syscall6(SB),NOSPLIT,$0-80 TEXT ·Syscall6(SB),NOSPLIT,$0-80
BR syscall·Syscall6(SB) BR syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
BL runtime·entersyscall(SB)
MOVD a1+8(FP), R2
MOVD a2+16(FP), R3
MOVD a3+24(FP), R4
MOVD $0, R5
MOVD $0, R6
MOVD $0, R7
MOVD trap+0(FP), R1 // syscall entry
SYSCALL
MOVD R2, r1+32(FP)
MOVD R3, r2+40(FP)
BL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 TEXT ·RawSyscall(SB),NOSPLIT,$0-56
BR syscall·RawSyscall(SB) BR syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
BR syscall·RawSyscall6(SB) BR syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R2
MOVD a2+16(FP), R3
MOVD a3+24(FP), R4
MOVD $0, R5
MOVD $0, R6
MOVD $0, R7
MOVD trap+0(FP), R1 // syscall entry
SYSCALL
MOVD R2, r1+32(FP)
MOVD R3, r2+40(FP)
RET
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
package unix package unix
import ( import (
errorspkg "errors" "errors"
"fmt" "fmt"
) )
...@@ -60,26 +60,26 @@ func CapRightsSet(rights *CapRights, setrights []uint64) error { ...@@ -60,26 +60,26 @@ func CapRightsSet(rights *CapRights, setrights []uint64) error {
n := caparsize(rights) n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax { if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size") return errors.New("bad rights size")
} }
for _, right := range setrights { for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 { if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version") return errors.New("bad right version")
} }
i, err := rightToIndex(right) i, err := rightToIndex(right)
if err != nil { if err != nil {
return err return err
} }
if i >= n { if i >= n {
return errorspkg.New("index overflow") return errors.New("index overflow")
} }
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch") return errors.New("index mismatch")
} }
rights.Rights[i] |= right rights.Rights[i] |= right
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)") return errors.New("index mismatch (after assign)")
} }
} }
...@@ -95,26 +95,26 @@ func CapRightsClear(rights *CapRights, clearrights []uint64) error { ...@@ -95,26 +95,26 @@ func CapRightsClear(rights *CapRights, clearrights []uint64) error {
n := caparsize(rights) n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax { if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size") return errors.New("bad rights size")
} }
for _, right := range clearrights { for _, right := range clearrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 { if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version") return errors.New("bad right version")
} }
i, err := rightToIndex(right) i, err := rightToIndex(right)
if err != nil { if err != nil {
return err return err
} }
if i >= n { if i >= n {
return errorspkg.New("index overflow") return errors.New("index overflow")
} }
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch") return errors.New("index mismatch")
} }
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF) rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)") return errors.New("index mismatch (after assign)")
} }
} }
...@@ -130,22 +130,22 @@ func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) { ...@@ -130,22 +130,22 @@ func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
n := caparsize(rights) n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax { if n < capArSizeMin || n > capArSizeMax {
return false, errorspkg.New("bad rights size") return false, errors.New("bad rights size")
} }
for _, right := range setrights { for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 { if caprver(right) != CAP_RIGHTS_VERSION_00 {
return false, errorspkg.New("bad right version") return false, errors.New("bad right version")
} }
i, err := rightToIndex(right) i, err := rightToIndex(right)
if err != nil { if err != nil {
return false, err return false, err
} }
if i >= n { if i >= n {
return false, errorspkg.New("index overflow") return false, errors.New("index overflow")
} }
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return false, errorspkg.New("index mismatch") return false, errors.New("index mismatch")
} }
if (rights.Rights[i] & right) != right { if (rights.Rights[i] & right) != right {
return false, nil return false, nil
......
...@@ -6,97 +6,12 @@ ...@@ -6,97 +6,12 @@
package unix package unix
import "unsafe" import "syscall"
// readInt returns the size-bytes unsigned integer in native byte order at offset off.
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
if len(b) < int(off+size) {
return 0, false
}
if isBigEndian {
return readIntBE(b[off:], size), true
}
return readIntLE(b[off:], size), true
}
func readIntBE(b []byte, size uintptr) uint64 {
switch size {
case 1:
return uint64(b[0])
case 2:
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[1]) | uint64(b[0])<<8
case 4:
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
case 8:
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
default:
panic("syscall: readInt with unsupported size")
}
}
func readIntLE(b []byte, size uintptr) uint64 {
switch size {
case 1:
return uint64(b[0])
case 2:
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[0]) | uint64(b[1])<<8
case 4:
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
case 8:
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
default:
panic("syscall: readInt with unsupported size")
}
}
// ParseDirent parses up to max directory entries in buf, // ParseDirent parses up to max directory entries in buf,
// appending the names to names. It returns the number of // appending the names to names. It returns the number of
// bytes consumed from buf, the number of entries added // bytes consumed from buf, the number of entries added
// to names, and the new names slice. // to names, and the new names slice.
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
origlen := len(buf) return syscall.ParseDirent(buf, max, names)
count = 0
for max != 0 && len(buf) > 0 {
reclen, ok := direntReclen(buf)
if !ok || reclen > uint64(len(buf)) {
return origlen, count, names
}
rec := buf[:reclen]
buf = buf[reclen:]
ino, ok := direntIno(rec)
if !ok {
break
}
if ino == 0 { // File absent in directory.
continue
}
const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
namlen, ok := direntNamlen(rec)
if !ok || namoff+namlen > uint64(len(rec)) {
break
}
name := rec[namoff : namoff+namlen]
for i, c := range name {
if c == 0 {
name = name[:i]
break
}
}
// Check for useless names before allocating a string.
if string(name) == "." || string(name) == ".." {
continue
}
max--
count++
names = append(names, string(name))
}
return origlen - len(buf), count, names
} }
...@@ -25,3 +25,7 @@ func Clearenv() { ...@@ -25,3 +25,7 @@ func Clearenv() {
func Environ() []string { func Environ() []string {
return syscall.Environ() return syscall.Environ()
} }
func Unsetenv(key string) error {
return syscall.Unsetenv(key)
}
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.4
package unix
import "syscall"
func Unsetenv(key string) error {
// This was added in Go 1.4.
return syscall.Unsetenv(key)
}
...@@ -12,6 +12,16 @@ import "unsafe" ...@@ -12,6 +12,16 @@ import "unsafe"
// systems by flock_linux_32bit.go to be SYS_FCNTL64. // systems by flock_linux_32bit.go to be SYS_FCNTL64.
var fcntl64Syscall uintptr = SYS_FCNTL var fcntl64Syscall uintptr = SYS_FCNTL
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
var err error
if errno != 0 {
err = errno
}
return int(valptr), err
}
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk))) _, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
......
// 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
import (
"os"
"syscall"
)
// FIXME: unexported function from os
// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
func syscallMode(i os.FileMode) (o uint32) {
o |= uint32(i.Perm())
if i&os.ModeSetuid != 0 {
o |= syscall.S_ISUID
}
if i&os.ModeSetgid != 0 {
o |= syscall.S_ISGID
}
if i&os.ModeSticky != 0 {
o |= syscall.S_ISVTX
}
// No mapping for Go's ModeTemporary (plan9 only).
return
}
...@@ -11,9 +11,19 @@ import "syscall" ...@@ -11,9 +11,19 @@ import "syscall"
// We can't use the gc-syntax .s files for gccgo. On the plus side // We can't use the gc-syntax .s files for gccgo. On the plus side
// much of the functionality can be written directly in Go. // much of the functionality can be written directly in Go.
//extern gccgoRealSyscallNoError
func realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr)
//extern gccgoRealSyscall //extern gccgoRealSyscall
func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr) func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr)
func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
syscall.Entersyscall()
r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
syscall.Exitsyscall()
return r, 0
}
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
syscall.Entersyscall() syscall.Entersyscall()
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
...@@ -35,6 +45,11 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, ...@@ -35,6 +45,11 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
return r, 0, syscall.Errno(errno) return r, 0, syscall.Errno(errno)
} }
func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
return r, 0
}
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
return r, 0, syscall.Errno(errno) return r, 0, syscall.Errno(errno)
......
...@@ -31,11 +31,8 @@ gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintp ...@@ -31,11 +31,8 @@ gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintp
return r; return r;
} }
// Define the use function in C so that it is not inlined. uintptr_t
gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline));
void
use(void *p __attribute__ ((unused)))
{ {
return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
} }
...@@ -80,12 +80,6 @@ darwin_arm64) ...@@ -80,12 +80,6 @@ darwin_arm64)
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
dragonfly_386)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -dragonfly"
mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
dragonfly_amd64) dragonfly_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="./mksyscall.pl -dragonfly" mksyscall="./mksyscall.pl -dragonfly"
......
...@@ -38,6 +38,8 @@ includes_Darwin=' ...@@ -38,6 +38,8 @@ includes_Darwin='
#define _DARWIN_C_SOURCE #define _DARWIN_C_SOURCE
#define KERNEL #define KERNEL
#define _DARWIN_USE_64_BIT_INODE #define _DARWIN_USE_64_BIT_INODE
#include <stdint.h>
#include <sys/attr.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/event.h> #include <sys/event.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
...@@ -46,7 +48,9 @@ includes_Darwin=' ...@@ -46,7 +48,9 @@ includes_Darwin='
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/xattr.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>
...@@ -168,6 +172,8 @@ struct ltchars { ...@@ -168,6 +172,8 @@ struct ltchars {
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/keyctl.h> #include <linux/keyctl.h>
#include <linux/magic.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/random.h> #include <linux/random.h>
...@@ -184,7 +190,10 @@ struct ltchars { ...@@ -184,7 +190,10 @@ struct ltchars {
#include <linux/vm_sockets.h> #include <linux/vm_sockets.h>
#include <linux/taskstats.h> #include <linux/taskstats.h>
#include <linux/genetlink.h> #include <linux/genetlink.h>
#include <linux/stat.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
#include <linux/hdreg.h>
#include <linux/rtc.h>
#include <net/route.h> #include <net/route.h>
#include <asm/termbits.h> #include <asm/termbits.h>
...@@ -360,6 +369,7 @@ ccflags="$@" ...@@ -360,6 +369,7 @@ ccflags="$@"
$2 ~ /^IGN/ || $2 ~ /^IGN/ ||
$2 ~ /^IX(ON|ANY|OFF)$/ || $2 ~ /^IX(ON|ANY|OFF)$/ ||
$2 ~ /^IN(LCR|PCK)$/ || $2 ~ /^IN(LCR|PCK)$/ ||
$2 !~ "X86_CR3_PCID_NOFLUSH" &&
$2 ~ /(^FLU?SH)|(FLU?SH$)/ || $2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ || $2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
$2 == "BRKINT" || $2 == "BRKINT" ||
...@@ -378,13 +388,16 @@ ccflags="$@" ...@@ -378,13 +388,16 @@ ccflags="$@"
$2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ || $2 ~ /^IN_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ || $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
$2 ~ /^TP_STATUS_/ ||
$2 ~ /^FALLOC_/ || $2 ~ /^FALLOC_/ ||
$2 == "ICMPV6_FILTER" || $2 == "ICMPV6_FILTER" ||
$2 == "SOMAXCONN" || $2 == "SOMAXCONN" ||
$2 == "NAME_MAX" || $2 == "NAME_MAX" ||
$2 == "IFNAMSIZ" || $2 == "IFNAMSIZ" ||
$2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ || $2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
$2 ~ /^HW_MACHINE$/ ||
$2 ~ /^SYSCTL_VERS/ || $2 ~ /^SYSCTL_VERS/ ||
$2 ~ /^(MS|MNT|UMOUNT)_/ || $2 ~ /^(MS|MNT|UMOUNT)_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
...@@ -392,7 +405,7 @@ ccflags="$@" ...@@ -392,7 +405,7 @@ ccflags="$@"
$2 ~ /^LINUX_REBOOT_CMD_/ || $2 ~ /^LINUX_REBOOT_CMD_/ ||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
$2 !~ "NLA_TYPE_MASK" && $2 !~ "NLA_TYPE_MASK" &&
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ || $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
$2 ~ /^SIOC/ || $2 ~ /^SIOC/ ||
$2 ~ /^TIOC/ || $2 ~ /^TIOC/ ||
$2 ~ /^TCGET/ || $2 ~ /^TCGET/ ||
...@@ -418,12 +431,21 @@ ccflags="$@" ...@@ -418,12 +431,21 @@ ccflags="$@"
$2 ~ /^PERF_EVENT_IOC_/ || $2 ~ /^PERF_EVENT_IOC_/ ||
$2 ~ /^SECCOMP_MODE_/ || $2 ~ /^SECCOMP_MODE_/ ||
$2 ~ /^SPLICE_/ || $2 ~ /^SPLICE_/ ||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
$2 ~ /^[A-Z0-9_]+_MAGIC2?$/ ||
$2 ~ /^(VM|VMADDR)_/ || $2 ~ /^(VM|VMADDR)_/ ||
$2 ~ /^IOCTL_VM_SOCKETS_/ ||
$2 ~ /^(TASKSTATS|TS)_/ || $2 ~ /^(TASKSTATS|TS)_/ ||
$2 ~ /^CGROUPSTATS_/ ||
$2 ~ /^GENL_/ || $2 ~ /^GENL_/ ||
$2 ~ /^STATX_/ ||
$2 ~ /^UTIME_/ || $2 ~ /^UTIME_/ ||
$2 ~ /^XATTR_(CREATE|REPLACE)/ || $2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
$2 ~ /^FSOPT_/ ||
$2 ~ /^WDIOC_/ || $2 ~ /^WDIOC_/ ||
$2 ~ /^NFN/ ||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
$2 !~ "WMESGLEN" && $2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ || $2 ~ /^W[A-Z0-9]+$/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
...@@ -493,21 +515,26 @@ echo ')' ...@@ -493,21 +515,26 @@ echo ')'
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
int errors[] = { struct tuple {
int num;
const char *name;
};
struct tuple errors[] = {
" "
for i in $errors for i in $errors
do do
echo -E ' '$i, echo -E ' {'$i', "'$i'" },'
done done
echo -E " echo -E "
}; };
int signals[] = { struct tuple signals[] = {
" "
for i in $signals for i in $signals
do do
echo -E ' '$i, echo -E ' {'$i', "'$i'" },'
done done
# Use -E because on some systems bash builtin interprets \n itself. # Use -E because on some systems bash builtin interprets \n itself.
...@@ -515,9 +542,9 @@ int signals[] = { ...@@ -515,9 +542,9 @@ int signals[] = {
}; };
static int static int
intcmp(const void *a, const void *b) tuplecmp(const void *a, const void *b)
{ {
return *(int*)a - *(int*)b; return ((struct tuple *)a)->num - ((struct tuple *)b)->num;
} }
int int
...@@ -527,26 +554,34 @@ main(void) ...@@ -527,26 +554,34 @@ main(void)
char buf[1024], *p; char buf[1024], *p;
printf("\n\n// Error table\n"); printf("\n\n// Error table\n");
printf("var errors = [...]string {\n"); printf("var errorList = [...]struct {\n");
qsort(errors, nelem(errors), sizeof errors[0], intcmp); printf("\tnum syscall.Errno\n");
printf("\tname string\n");
printf("\tdesc string\n");
printf("} {\n");
qsort(errors, nelem(errors), sizeof errors[0], tuplecmp);
for(i=0; i<nelem(errors); i++) { for(i=0; i<nelem(errors); i++) {
e = errors[i]; e = errors[i].num;
if(i > 0 && errors[i-1] == e) if(i > 0 && errors[i-1].num == e)
continue; continue;
strcpy(buf, strerror(e)); strcpy(buf, strerror(e));
// 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;
printf("\t%d: \"%s\",\n", e, buf); printf("\t{ %d, \"%s\", \"%s\" },\n", e, errors[i].name, buf);
} }
printf("}\n\n"); printf("}\n\n");
printf("\n\n// Signal table\n"); printf("\n\n// Signal table\n");
printf("var signals = [...]string {\n"); printf("var signalList = [...]struct {\n");
qsort(signals, nelem(signals), sizeof signals[0], intcmp); printf("\tnum syscall.Signal\n");
printf("\tname string\n");
printf("\tdesc string\n");
printf("} {\n");
qsort(signals, nelem(signals), sizeof signals[0], tuplecmp);
for(i=0; i<nelem(signals); i++) { for(i=0; i<nelem(signals); i++) {
e = signals[i]; e = signals[i].num;
if(i > 0 && signals[i-1] == e) if(i > 0 && signals[i-1].num == e)
continue; continue;
strcpy(buf, strsignal(e)); strcpy(buf, strsignal(e));
// lowercase first letter: Bad -> bad, but STREAM -> STREAM. // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
...@@ -556,7 +591,7 @@ main(void) ...@@ -556,7 +591,7 @@ main(void)
p = strrchr(buf, ":"[0]); p = strrchr(buf, ":"[0]);
if(p) if(p)
*p = '\0'; *p = '\0';
printf("\t%d: \"%s\",\n", e, buf); printf("\t{ %d, \"%s\", \"%s\" },\n", e, signals[i].name, buf);
} }
printf("}\n\n"); printf("}\n\n");
......
...@@ -42,6 +42,10 @@ func main() { ...@@ -42,6 +42,10 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
// Intentionally export __val fields in Fsid and Sigset_t
valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`)
b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}"))
// If we have empty Ptrace structs, we should delete them. Only s390x emits // If we have empty Ptrace structs, we should delete them. Only s390x emits
// nonempty Ptrace structs. // nonempty Ptrace structs.
ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`) ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
...@@ -61,16 +65,17 @@ func main() { ...@@ -61,16 +65,17 @@ func main() {
convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`) convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte")) b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
// We refuse to export private fields on s390x // Remove spare fields (e.g. in Statx_t)
if goarch == "s390x" && goos == "linux" { spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
// Remove cgo padding fields b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
removeFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove padding, hidden, or unused fields // Remove cgo padding fields
removeFieldsRegex = regexp.MustCompile(`X_\S+`) removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_")) b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_"))
}
// Remove padding, hidden, or unused fields
removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove the first line of warning from cgo // Remove the first line of warning from cgo
b = b[bytes.IndexByte(b, '\n')+1:] b = b[bytes.IndexByte(b, '\n')+1:]
......
...@@ -210,7 +210,15 @@ while(<>) { ...@@ -210,7 +210,15 @@ while(<>) {
# Determine which form to use; pad args with zeros. # Determine which form to use; pad args with zeros.
my $asm = "Syscall"; my $asm = "Syscall";
if ($nonblock) { if ($nonblock) {
$asm = "RawSyscall"; if ($errvar eq "" && $ENV{'GOOS'} eq "linux") {
$asm = "RawSyscallNoError";
} else {
$asm = "RawSyscall";
}
} else {
if ($errvar eq "" && $ENV{'GOOS'} eq "linux") {
$asm = "SyscallNoError";
}
} }
if(@args <= 3) { if(@args <= 3) {
while(@args < 3) { while(@args < 3) {
...@@ -284,7 +292,12 @@ while(<>) { ...@@ -284,7 +292,12 @@ while(<>) {
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
$text .= "\t$call\n"; $text .= "\t$call\n";
} else { } else {
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; if ($errvar eq "" && $ENV{'GOOS'} eq "linux") {
# raw syscall without error on Linux, see golang.org/issue/22924
$text .= "\t$ret[0], $ret[1] := $call\n";
} else {
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
}
} }
$text .= $body; $text .= $body;
......
...@@ -240,7 +240,7 @@ foreach my $header (@headers) { ...@@ -240,7 +240,7 @@ foreach my $header (@headers) {
print <<EOF; print <<EOF;
// mksysctl_openbsd.pl // mksysctl_openbsd.pl
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT // Code generated by the command above; DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'} // +build $ENV{'GOARCH'},$ENV{'GOOS'}
......
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
) )
const ( const (
SYS_PLEDGE = 108 _SYS_PLEDGE = 108
) )
// Pledge implements the pledge syscall. For more information see pledge(2). // Pledge implements the pledge syscall. For more information see pledge(2).
...@@ -30,7 +30,7 @@ func Pledge(promises string, paths []string) error { ...@@ -30,7 +30,7 @@ func Pledge(promises string, paths []string) error {
} }
pathsUnsafe = unsafe.Pointer(&pathsPtr[0]) pathsUnsafe = unsafe.Pointer(&pathsPtr[0])
} }
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0) _, _, e := syscall.Syscall(_SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
if e != 0 { if e != 0 {
return e return e
} }
......
...@@ -11,24 +11,27 @@ ...@@ -11,24 +11,27 @@
// system, set $GOOS and $GOARCH to the desired system. For example, if // system, set $GOOS and $GOARCH to the desired system. For example, if
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
// to freebsd and $GOARCH to arm. // to freebsd and $GOARCH to arm.
//
// The primary use of this package is inside other packages that provide a more // The primary use of this package is inside other packages that provide a more
// portable interface to the system, such as "os", "time" and "net". Use // portable interface to the system, such as "os", "time" and "net". Use
// those packages rather than this one if you can. // those packages rather than this one if you can.
//
// For details of the functions and data types in this package consult // For details of the functions and data types in this package consult
// the manuals for the appropriate operating system. // the manuals for the appropriate operating system.
//
// These calls return err == nil to indicate success; otherwise // These calls return err == nil to indicate success; otherwise
// err represents an operating system error describing the failure and // err represents an operating system error describing the failure and
// holds a value of type syscall.Errno. // holds a value of type syscall.Errno.
package unix // import "golang.org/x/sys/unix" package unix // import "golang.org/x/sys/unix"
import "strings"
// ByteSliceFromString returns a NUL-terminated slice of bytes // ByteSliceFromString returns a NUL-terminated slice of bytes
// containing the text of s. If s contains a NUL byte at any // containing the text of s. If s contains a NUL byte at any
// location, it returns (nil, EINVAL). // location, it returns (nil, EINVAL).
func ByteSliceFromString(s string) ([]byte, error) { func ByteSliceFromString(s string) ([]byte, error) {
for i := 0; i < len(s); i++ { if strings.IndexByte(s, 0) != -1 {
if s[i] == 0 { return nil, EINVAL
return nil, EINVAL
}
} }
a := make([]byte, len(s)+1) a := make([]byte, len(s)+1)
copy(a, s) copy(a, s)
......
...@@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) { ...@@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
} }
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_LINK: case AF_LINK:
pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa)) pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
...@@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { ...@@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
Close(nfd) Close(nfd)
return 0, nil, ECONNABORTED return 0, nil, ECONNABORTED
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
...@@ -306,50 +306,21 @@ func Getsockname(fd int) (sa Sockaddr, err error) { ...@@ -306,50 +306,21 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
rsa.Addr.Family = AF_UNIX rsa.Addr.Family = AF_UNIX
rsa.Addr.Len = SizeofSockaddrUnix rsa.Addr.Len = SizeofSockaddrUnix
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
} }
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
func GetsockoptByte(fd, level, opt int) (value byte, err error) { // GetsockoptString returns the string value of the socket option opt for the
var n byte // socket associated with fd at the given socket level.
vallen := _Socklen(1) func GetsockoptString(fd, level, opt int) (string, error) {
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) buf := make([]byte, 256)
return n, err vallen := _Socklen(len(buf))
} err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
if err != nil {
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { return "", err
vallen := _Socklen(4) }
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) return string(buf[:vallen-1]), nil
return value, err
}
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
var value IPMreq
vallen := _Socklen(SizeofIPMreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
var value IPv6Mreq
vallen := _Socklen(SizeofIPv6Mreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
var value IPv6MTUInfo
vallen := _Socklen(SizeofIPv6MTUInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
var value ICMPv6Filter
vallen := _Socklen(SizeofICMPv6Filter)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
} }
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
...@@ -385,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from ...@@ -385,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected // source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
...@@ -570,7 +541,12 @@ func UtimesNano(path string, ts []Timespec) error { ...@@ -570,7 +541,12 @@ func UtimesNano(path string, ts []Timespec) error {
if len(ts) != 2 { if len(ts) != 2 {
return EINVAL return EINVAL
} }
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) // Darwin setattrlist can set nanosecond timestamps
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
} }
...@@ -590,6 +566,10 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { ...@@ -590,6 +566,10 @@ 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)
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
package unix package unix
import ( import (
errorspkg "errors" "errors"
"syscall" "syscall"
"unsafe" "unsafe"
) )
...@@ -36,6 +36,7 @@ func Getwd() (string, error) { ...@@ -36,6 +36,7 @@ func Getwd() (string, error) {
return "", ENOTSUP return "", ENOTSUP
} }
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
...@@ -76,18 +77,6 @@ func nametomib(name string) (mib []_C_int, err error) { ...@@ -76,18 +77,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil return buf[0 : n/siz], nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
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) }
...@@ -109,7 +98,7 @@ type attrList struct { ...@@ -109,7 +98,7 @@ type attrList struct {
func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) { func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
if len(attrBuf) < 4 { if len(attrBuf) < 4 {
return nil, errorspkg.New("attrBuf too small") return nil, errors.New("attrBuf too small")
} }
attrList.bitmapCount = attrBitMapCount attrList.bitmapCount = attrBitMapCount
...@@ -145,12 +134,12 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) ( ...@@ -145,12 +134,12 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (
for i := uint32(0); int(i) < len(dat); { for i := uint32(0); int(i) < len(dat); {
header := dat[i:] header := dat[i:]
if len(header) < 8 { if len(header) < 8 {
return attrs, errorspkg.New("truncated attribute header") return attrs, errors.New("truncated attribute header")
} }
datOff := *(*int32)(unsafe.Pointer(&header[0])) datOff := *(*int32)(unsafe.Pointer(&header[0]))
attrLen := *(*uint32)(unsafe.Pointer(&header[4])) attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) { if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
return attrs, errorspkg.New("truncated results; attrBuf too small") return attrs, errors.New("truncated results; attrBuf too small")
} }
end := uint32(datOff) + attrLen end := uint32(datOff) + attrLen
attrs = append(attrs, dat[datOff:end]) attrs = append(attrs, dat[datOff:end])
...@@ -187,6 +176,119 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -187,6 +176,119 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
return return
} }
func xattrPointer(dest []byte) *byte {
// It's only when dest is set to NULL that the OS X implementations of
// getxattr() and listxattr() return the current sizes of the named attributes.
// An empty byte array is not sufficient. To maintain the same behaviour as the
// linux implementation, we wrap around the system calls and pass in NULL when
// dest is empty.
var destp *byte
if len(dest) > 0 {
destp = &dest[0]
}
return destp
}
//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0)
}
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)
}
//sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error)
func Setxattr(path string, attr string, data []byte, flags int) (err error) {
// The parameters for the OS X implementation vary slightly compared to the
// linux system call, specifically the position parameter:
//
// linux:
// int setxattr(
// const char *path,
// const char *name,
// const void *value,
// size_t size,
// int flags
// );
//
// darwin:
// int setxattr(
// const char *path,
// const char *name,
// void *value,
// size_t size,
// u_int32_t position,
// int options
// );
//
// position specifies the offset within the extended attribute. In the
// current implementation, only the resource fork extended attribute makes
// use of this argument. For all others, position is reserved. We simply
// default to setting it to zero.
return setxattr(path, attr, xattrPointer(data), len(data), 0, flags)
}
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
}
//sys removexattr(path string, attr string, options int) (err error)
func Removexattr(path string, attr string) (err error) {
// We wrap around and explicitly zero out the options provided to the OS X
// implementation of removexattr, we do so for interoperability with the
// linux variant.
return removexattr(path, attr, 0)
}
func Lremovexattr(link string, attr string) (err error) {
return removexattr(link, attr, XATTR_NOFOLLOW)
}
//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error)
func Listxattr(path string, dest []byte) (sz int, err error) {
return listxattr(path, xattrPointer(dest), len(dest), 0)
}
func Llistxattr(link string, dest []byte) (sz int, err error) {
return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
}
func setattrlistTimes(path string, times []Timespec, flags int) 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
}
_, _, e1 := Syscall6(
SYS_SETATTRLIST,
uintptr(unsafe.Pointer(_p0)),
uintptr(unsafe.Pointer(&attrList)),
uintptr(unsafe.Pointer(&attributes)),
uintptr(unsafe.Sizeof(attributes)),
uintptr(options),
0,
)
if e1 != 0 {
return e1
}
return nil
}
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error { func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
// Darwin doesn't support SYS_UTIMENSAT // Darwin doesn't support SYS_UTIMENSAT
return ENOSYS return ENOSYS
...@@ -239,6 +341,52 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { ...@@ -239,6 +341,52 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
return &value, err return &value, err
} }
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
return err
}
return nil
}
/* /*
* Exposed directly * Exposed directly
*/ */
...@@ -264,6 +412,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { ...@@ -264,6 +412,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, 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_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
//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)
...@@ -380,13 +529,9 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { ...@@ -380,13 +529,9 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
// Watchevent // Watchevent
// Waitevent // Waitevent
// Modwatch // Modwatch
// Getxattr
// Fgetxattr // Fgetxattr
// Setxattr
// Fsetxattr // Fsetxattr
// Removexattr
// Fremovexattr // Fremovexattr
// Listxattr
// Flistxattr // Flistxattr
// Fsctl // Fsctl
// Initgroups // Initgroups
......
...@@ -60,3 +60,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e ...@@ -60,3 +60,7 @@ 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) // sic func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
// of darwin/arm the syscall is called sysctl instead of __sysctl.
const SYS___SYSCTL = SYS_SYSCTL
...@@ -14,6 +14,7 @@ package unix ...@@ -14,6 +14,7 @@ package unix
import "unsafe" import "unsafe"
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
...@@ -56,22 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) { ...@@ -56,22 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil return buf[0 : n/siz], nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
namlen, ok := direntNamlen(buf)
if !ok {
return 0, false
}
return (16 + namlen + 1 + 7) &^ 7, true
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (r int, w int, err error) //sysnb pipe() (r int, w int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
...@@ -102,7 +87,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { ...@@ -102,7 +87,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
if len > SizeofSockaddrAny { if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small") panic("RawSockaddrAny too small")
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
...@@ -110,6 +95,23 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { ...@@ -110,6 +95,23 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
return return
} }
const ImplementsGetwd = true
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD
func Getwd() (string, error) {
var buf [PathMax]byte
_, err := Getcwd(buf[0:])
if err != nil {
return "", err
}
n := clen(buf[:])
if n < 1 {
return "", EINVAL
}
return string(buf[:n]), nil
}
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
var _p0 unsafe.Pointer var _p0 unsafe.Pointer
var bufsize uintptr var bufsize uintptr
...@@ -125,6 +127,113 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -125,6 +127,113 @@ 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)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
func IoctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error {
err := sysctl(mib, old, oldlen, nil, 0)
if err != nil {
// Utsname members on Dragonfly are only 32 bytes and
// the syscall returns ENOMEM in case the actual value
// is longer.
if err == ENOMEM {
err = nil
}
}
return err
}
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctlUname(mib, &uname.Sysname[0], &n); err != nil {
return err
}
uname.Sysname[unsafe.Sizeof(uname.Sysname)-1] = 0
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctlUname(mib, &uname.Nodename[0], &n); err != nil {
return err
}
uname.Nodename[unsafe.Sizeof(uname.Nodename)-1] = 0
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctlUname(mib, &uname.Release[0], &n); err != nil {
return err
}
uname.Release[unsafe.Sizeof(uname.Release)-1] = 0
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctlUname(mib, &uname.Version[0], &n); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctlUname(mib, &uname.Machine[0], &n); err != nil {
return err
}
uname.Machine[unsafe.Sizeof(uname.Machine)-1] = 0
return nil
}
/* /*
* Exposed directly * Exposed directly
*/ */
...@@ -142,10 +251,12 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -142,10 +251,12 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error) //sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid 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_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fstatfs(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)
...@@ -225,7 +336,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -225,7 +336,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// Getlogin // Getlogin
// Sigpending // Sigpending
// Sigaltstack // Sigaltstack
// Ioctl
// Reboot // Reboot
// Execve // Execve
// Vfork // Vfork
......
...@@ -12,8 +12,12 @@ ...@@ -12,8 +12,12 @@
package unix package unix
import "unsafe" import (
"strings"
"unsafe"
)
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
...@@ -54,18 +58,6 @@ func nametomib(name string) (mib []_C_int, err error) { ...@@ -54,18 +58,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil return buf[0 : n/siz], nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (r int, w int, err error) //sysnb pipe() (r int, w int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
...@@ -97,7 +89,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { ...@@ -97,7 +89,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
if len > SizeofSockaddrAny { if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small") panic("RawSockaddrAny too small")
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
...@@ -105,6 +97,23 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { ...@@ -105,6 +97,23 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
return return
} }
const ImplementsGetwd = true
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD
func Getwd() (string, error) {
var buf [PathMax]byte
_, err := Getcwd(buf[0:])
if err != nil {
return "", err
}
n := clen(buf[:])
if n < 1 {
return "", EINVAL
}
return string(buf[:n]), nil
}
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
var _p0 unsafe.Pointer var _p0 unsafe.Pointer
var bufsize uintptr var bufsize uintptr
...@@ -120,17 +129,15 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -120,17 +129,15 @@ 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
}
// Derive extattr namespace and attribute name // Derive extattr namespace and attribute name
func xattrnamespace(fullattr string) (ns int, attr string, err error) { func xattrnamespace(fullattr string) (ns int, attr string, err error) {
s := -1 s := strings.IndexByte(fullattr, '.')
for idx, val := range fullattr {
if val == '.' {
s = idx
break
}
}
if s == -1 { if s == -1 {
return -1, "", ENOATTR return -1, "", ENOATTR
} }
...@@ -271,7 +278,6 @@ func Listxattr(file string, dest []byte) (sz int, err error) { ...@@ -271,7 +278,6 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
// FreeBSD won't allow you to list xattrs from multiple namespaces // FreeBSD won't allow you to list xattrs from multiple namespaces
s := 0 s := 0
var e error
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
...@@ -283,7 +289,6 @@ func Listxattr(file string, dest []byte) (sz int, err error) { ...@@ -283,7 +289,6 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
* we don't have read permissions on, so don't ignore those errors * we don't have read permissions on, so don't ignore those errors
*/ */
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
e = nil
continue continue
} else if e != nil { } else if e != nil {
return s, e return s, e
...@@ -297,7 +302,7 @@ func Listxattr(file string, dest []byte) (sz int, err error) { ...@@ -297,7 +302,7 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
d = initxattrdest(dest, s) d = initxattrdest(dest, s)
} }
return s, e return s, nil
} }
func Flistxattr(fd int, dest []byte) (sz int, err error) { func Flistxattr(fd int, dest []byte) (sz int, err error) {
...@@ -305,11 +310,9 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) { ...@@ -305,11 +310,9 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) {
destsiz := len(dest) destsiz := len(dest)
s := 0 s := 0
var e error
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
e = nil
continue continue
} else if e != nil { } else if e != nil {
return s, e return s, e
...@@ -323,7 +326,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) { ...@@ -323,7 +326,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) {
d = initxattrdest(dest, s) d = initxattrdest(dest, s)
} }
return s, e return s, nil
} }
func Llistxattr(link string, dest []byte) (sz int, err error) { func Llistxattr(link string, dest []byte) (sz int, err error) {
...@@ -331,11 +334,9 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { ...@@ -331,11 +334,9 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
destsiz := len(dest) destsiz := len(dest)
s := 0 s := 0
var e error
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
e = nil
continue continue
} else if e != nil { } else if e != nil {
return s, e return s, e
...@@ -349,7 +350,7 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { ...@@ -349,7 +350,7 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
d = initxattrdest(dest, s) d = initxattrdest(dest, s)
} }
return s, e return s, nil
} }
//sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctl(fd int, req uint, arg uintptr) (err error)
...@@ -391,6 +392,52 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { ...@@ -391,6 +392,52 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
return &value, err return &value, err
} }
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
return err
}
return nil
}
/* /*
* Exposed directly * Exposed directly
*/ */
...@@ -431,9 +478,11 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { ...@@ -431,9 +478,11 @@ func IoctlGetTermios(fd int, req uint) (*Termios, 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_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fstatfs(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 Getdents(fd int, buf []byte) (n int, err error)
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) //sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
//sys Getdtablesize() (size int) //sys Getdtablesize() (size int)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
package unix package unix
import ( import (
"syscall"
"unsafe" "unsafe"
) )
...@@ -51,9 +50,12 @@ func Pipe2(p []int, flags int) (err error) { ...@@ -51,9 +50,12 @@ func Pipe2(p []int, flags int) (err error) {
// 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 Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd 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
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
//sysnb Getegid() (egid int) = SYS_GETEGID32 //sysnb Getegid() (egid int) = SYS_GETEGID32
//sysnb Geteuid() (euid int) = SYS_GETEUID32 //sysnb Geteuid() (euid int) = SYS_GETEUID32
...@@ -77,12 +79,12 @@ func Pipe2(p []int, flags int) (err error) { ...@@ -77,12 +79,12 @@ func Pipe2(p []int, flags 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)
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32 //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
//sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32 //sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
//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 mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Pause() (err error) //sys Pause() (err error)
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
...@@ -156,10 +158,6 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) { ...@@ -156,10 +158,6 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) {
return setrlimit(resource, &rl) return setrlimit(resource, &rl)
} }
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
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 {
...@@ -168,11 +166,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { ...@@ -168,11 +166,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
return newoffset, nil return newoffset, nil
} }
// Vsyscalls on amd64. //sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error) //sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
// On x86 Linux, all the socket calls go through an extra indirection, // On x86 Linux, all the socket calls go through an extra indirection,
// I think because the 5-register system call interface can't handle // I think because the 5-register system call interface can't handle
...@@ -205,9 +203,6 @@ const ( ...@@ -205,9 +203,6 @@ const (
_SENDMMSG = 20 _SENDMMSG = 20
) )
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { 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) fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
if e != 0 { if e != 0 {
......
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
package unix package unix
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd 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)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
//sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
...@@ -28,7 +30,15 @@ package unix ...@@ -28,7 +30,15 @@ package unix
//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 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
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
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 Pselect(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) (err error) //sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error) //sys Setfsuid(uid int) (err error)
...@@ -39,10 +49,16 @@ package unix ...@@ -39,10 +49,16 @@ package unix
//sysnb Setreuid(ruid int, euid int) (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 Stat(path string, stat *Stat_t) (err error)
func Stat(path string, stat *Stat_t) (err error) {
// Use fstatat, because Android's seccomp policy blocks stat.
return Fstatat(AT_FDCWD, path, stat, 0)
}
//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 accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, 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)
...@@ -61,6 +77,8 @@ package unix ...@@ -61,6 +77,8 @@ package unix
//sys sendmsg(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) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
func Gettimeofday(tv *Timeval) (err error) { func Gettimeofday(tv *Timeval) (err error) {
errno := gettimeofday(tv) errno := gettimeofday(tv)
if errno != 0 { if errno != 0 {
...@@ -82,6 +100,7 @@ func Time(t *Time_t) (tt Time_t, err error) { ...@@ -82,6 +100,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
......
...@@ -75,8 +75,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { ...@@ -75,8 +75,11 @@ 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 Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd 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
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sysnb Getegid() (egid int) = SYS_GETEGID32 //sysnb Getegid() (egid int) = SYS_GETEGID32
//sysnb Geteuid() (euid int) = SYS_GETEUID32 //sysnb Geteuid() (euid int) = SYS_GETEUID32
//sysnb Getgid() (gid int) = SYS_GETGID32 //sysnb Getgid() (gid int) = SYS_GETGID32
...@@ -85,6 +88,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { ...@@ -85,6 +88,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, 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 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_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Pause() (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 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) (err error) = SYS_SETFSGID32 //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
...@@ -96,11 +100,10 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { ...@@ -96,11 +100,10 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, 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 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 Ustat(dev int, ubuf *Ustat_t) (err error)
// Vsyscalls on amd64. //sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Pause() (err error)
func Time(t *Time_t) (Time_t, error) { func Time(t *Time_t) (Time_t, error) {
var tv Timeval var tv Timeval
...@@ -122,6 +125,8 @@ func Utime(path string, buf *Utimbuf) error { ...@@ -122,6 +125,8 @@ func Utime(path string, buf *Utimbuf) error {
return Utimes(path, tv) return Utimes(path, tv)
} }
//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
......
...@@ -6,7 +6,17 @@ ...@@ -6,7 +6,17 @@
package unix package unix
import "unsafe"
func EpollCreate(size int) (fd int, err error) {
if size <= 0 {
return -1, EINVAL
}
return EpollCreate1(0)
}
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT //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 Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(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_t, flags int) (err error)
...@@ -23,8 +33,11 @@ package unix ...@@ -23,8 +33,11 @@ package unix
//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
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} var ts *Timespec
return Pselect(nfd, r, w, e, &ts, nil) if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return Pselect(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)
...@@ -53,6 +66,11 @@ func Lstat(path string, stat *Stat_t) (err error) { ...@@ -53,6 +66,11 @@ func Lstat(path string, stat *Stat_t) (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)
func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, 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)
...@@ -81,6 +99,18 @@ func setTimeval(sec, usec int64) Timeval { ...@@ -81,6 +99,18 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec} return Timeval{Sec: sec, Usec: usec}
} }
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) { func Time(t *Time_t) (Time_t, error) {
var tv Timeval var tv Timeval
err := Gettimeofday(&tv) err := Gettimeofday(&tv)
...@@ -101,6 +131,18 @@ func Utime(path string, buf *Utimbuf) error { ...@@ -101,6 +131,18 @@ func Utime(path string, buf *Utimbuf) error {
return Utimes(path, tv) 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 Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
...@@ -157,22 +199,6 @@ func Pause() (err error) { ...@@ -157,22 +199,6 @@ func Pause() (err error) {
return return
} }
// TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove
// these when the deprecated syscalls that the syscall package relies on
// are removed.
const (
SYS_GETPGRP = 1060
SYS_UTIMES = 1037
SYS_FUTIMESAT = 1066
SYS_PAUSE = 1061
SYS_USTAT = 1070
SYS_UTIME = 1063
SYS_LCHOWN = 1032
SYS_TIME = 1062
SYS_EPOLL_CREATE = 1042
SYS_EPOLL_WAIT = 1069
)
func Poll(fds []PollFd, timeout int) (n int, err error) { func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec var ts *Timespec
if timeout >= 0 { if timeout >= 0 {
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,!gccgo
package unix
// SyscallNoError may be used instead of Syscall for syscalls that don't fail.
func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
// RawSyscallNoError may be used instead of RawSyscall for syscalls that don't
// fail.
func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,!gccgo,386
package unix
import "syscall"
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,gccgo,386
package unix
import (
"syscall"
"unsafe"
)
func seek(fd int, offset int64, whence int) (int64, syscall.Errno) {
var newoffset int64
offsetLow := uint32(offset & 0xffffffff)
offsetHigh := uint32((offset >> 32) & 0xffffffff)
_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)
return newoffset, err
}
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {
fd, _, err := Syscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)
return int(fd), err
}
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {
fd, _, err := RawSyscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)
return int(fd), err
}
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,gccgo,arm
package unix
import (
"syscall"
"unsafe"
)
func seek(fd int, offset int64, whence int) (int64, syscall.Errno) {
var newoffset int64
offsetLow := uint32(offset & 0xffffffff)
offsetHigh := uint32((offset >> 32) & 0xffffffff)
_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)
return newoffset, err
}
...@@ -8,8 +8,11 @@ ...@@ -8,8 +8,11 @@
package unix package unix
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd 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 Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
//sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
...@@ -25,8 +28,11 @@ package unix ...@@ -25,8 +28,11 @@ package unix
//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
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} var ts *Timespec
return Pselect(nfd, r, w, e, &ts, nil) if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return Pselect(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)
...@@ -42,6 +48,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err ...@@ -42,6 +48,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//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 accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, 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)
...@@ -60,6 +67,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err ...@@ -60,6 +67,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys sendmsg(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) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) { func Time(t *Time_t) (tt Time_t, err error) {
...@@ -75,6 +83,7 @@ func Time(t *Time_t) (tt Time_t, err error) { ...@@ -75,6 +83,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
......
...@@ -15,6 +15,9 @@ import ( ...@@ -15,6 +15,9 @@ import (
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd 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 Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
...@@ -32,13 +35,12 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, ...@@ -32,13 +35,12 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid 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 Setreuid(ruid int, euid int) (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 int, 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_TRUNCATE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, 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)
...@@ -60,15 +62,17 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, ...@@ -60,15 +62,17 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error) //sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Utime(path string, buf *Utimbuf) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Pause() (err error) //sys Pause() (err error)
func Fstatfs(fd int, buf *Statfs_t) (err error) { func Fstatfs(fd int, buf *Statfs_t) (err error) {
......
...@@ -7,10 +7,13 @@ ...@@ -7,10 +7,13 @@
package unix package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd 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 Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
//sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
...@@ -43,6 +46,7 @@ package unix ...@@ -43,6 +46,7 @@ package unix
//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_SYNC_FILE_RANGE2 //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2
//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 accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, 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)
...@@ -61,10 +65,11 @@ package unix ...@@ -61,10 +65,11 @@ package unix
//sys sendmsg(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) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error) //sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
......
...@@ -11,10 +11,12 @@ import ( ...@@ -11,10 +11,12 @@ import (
) )
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd 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)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
//sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
...@@ -43,9 +45,11 @@ import ( ...@@ -43,9 +45,11 @@ import (
//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)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) //sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error) //sysnb setgroups(n int, list *_Gid_t) (err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) { func Time(t *Time_t) (tt Time_t, err error) {
...@@ -61,6 +65,7 @@ func Time(t *Time_t) (tt Time_t, err error) { ...@@ -61,6 +65,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
......
...@@ -7,9 +7,11 @@ ...@@ -7,9 +7,11 @@
package unix package unix
//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 Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
...@@ -66,6 +68,7 @@ func Iopl(level int) (err error) { ...@@ -66,6 +68,7 @@ func Iopl(level int) (err error) {
return ENOSYS return ENOSYS
} }
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) { func Time(t *Time_t) (tt Time_t, err error) {
...@@ -81,6 +84,7 @@ func Time(t *Time_t) (tt Time_t, err error) { ...@@ -81,6 +84,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
......
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
"unsafe" "unsafe"
) )
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
...@@ -55,7 +56,6 @@ func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) { ...@@ -55,7 +56,6 @@ func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) {
} }
func nametomib(name string) (mib []_C_int, err error) { func nametomib(name string) (mib []_C_int, err error) {
// Split name into components. // Split name into components.
var parts []string var parts []string
last := 0 last := 0
...@@ -93,18 +93,6 @@ func nametomib(name string) (mib []_C_int, err error) { ...@@ -93,18 +93,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return mib, nil return mib, nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (fd1 int, fd2 int, err error) //sysnb pipe() (fd1 int, fd2 int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
...@@ -119,11 +107,118 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { ...@@ -119,11 +107,118 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
return getdents(fd, buf) return getdents(fd, buf)
} }
const ImplementsGetwd = true
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD
func Getwd() (string, error) {
var buf [PathMax]byte
_, err := Getcwd(buf[0:])
if err != nil {
return "", err
}
n := clen(buf[:])
if n < 1 {
return "", EINVAL
}
return string(buf[:n]), nil
}
// TODO // TODO
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) {
return -1, ENOSYS return -1, ENOSYS
} }
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)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
func IoctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
return err
}
return nil
}
/* /*
* Exposed directly * Exposed directly
*/ */
...@@ -138,13 +233,17 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e ...@@ -138,13 +233,17 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//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)
//sys Exit(code int) //sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error) //sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid 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_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (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)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
...@@ -225,7 +324,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e ...@@ -225,7 +324,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
// __msync13 // __msync13
// __ntp_gettime30 // __ntp_gettime30
// __posix_chown // __posix_chown
// __posix_fadvise50
// __posix_fchown // __posix_fchown
// __posix_lchown // __posix_lchown
// __posix_rename // __posix_rename
...@@ -384,7 +482,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e ...@@ -384,7 +482,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
// getitimer // getitimer
// getvfsstat // getvfsstat
// getxattr // getxattr
// ioctl
// ktrace // ktrace
// lchflags // lchflags
// lchmod // lchmod
......
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build dragonfly freebsd netbsd openbsd
package unix
const ImplementsGetwd = false
func Getwd() (string, error) { return "", ENOTSUP }
...@@ -13,10 +13,12 @@ ...@@ -13,10 +13,12 @@
package unix package unix
import ( import (
"sort"
"syscall" "syscall"
"unsafe" "unsafe"
) )
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
...@@ -32,39 +34,15 @@ type SockaddrDatalink struct { ...@@ -32,39 +34,15 @@ type SockaddrDatalink struct {
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func nametomib(name string) (mib []_C_int, err error) { func nametomib(name string) (mib []_C_int, err error) {
i := sort.Search(len(sysctlMib), func(i int) bool {
// Perform lookup via a binary search return sysctlMib[i].ctlname >= name
left := 0 })
right := len(sysctlMib) - 1 if i < len(sysctlMib) && sysctlMib[i].ctlname == name {
for { return sysctlMib[i].ctloid, nil
idx := left + (right-left)/2
switch {
case name == sysctlMib[idx].ctlname:
return sysctlMib[idx].ctloid, nil
case name > sysctlMib[idx].ctlname:
left = idx + 1
default:
right = idx - 1
}
if left > right {
break
}
} }
return nil, EINVAL return nil, EINVAL
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe(p *[2]_C_int) (err error) //sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
...@@ -82,6 +60,23 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { ...@@ -82,6 +60,23 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
return getdents(fd, buf) return getdents(fd, buf)
} }
const ImplementsGetwd = true
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD
func Getwd() (string, error) {
var buf [PathMax]byte
_, err := Getcwd(buf[0:])
if err != nil {
return "", err
}
n := clen(buf[:])
if n < 1 {
return "", EINVAL
}
return string(buf[:n]), nil
}
// TODO // TODO
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) {
return -1, ENOSYS return -1, ENOSYS
...@@ -102,6 +97,96 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -102,6 +97,96 @@ 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)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
func IoctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
return err
}
return nil
}
/* /*
* Exposed directly * Exposed directly
*/ */
...@@ -116,13 +201,16 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -116,13 +201,16 @@ func Getfsstat(buf []Statfs_t, flags int) (n 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)
//sys Exit(code int) //sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error) //sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid 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_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fstatfs(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)
...@@ -135,6 +223,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -135,6 +223,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
//sysnb Getppid() (ppid int) //sysnb Getppid() (ppid int)
//sys Getpriority(which int, who int) (prio int, err error) //sys Getpriority(which int, who int) (prio int, err error)
//sysnb Getrlimit(which int, lim *Rlimit) (err error) //sysnb Getrlimit(which int, lim *Rlimit) (err error)
//sysnb Getrtable() (rtable int, err error)
//sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getrusage(who int, rusage *Rusage) (err error)
//sysnb Getsid(pid int) (sid int, err error) //sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
...@@ -172,6 +261,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -172,6 +261,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n 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 Setrlimit(which int, lim *Rlimit) (err error)
//sysnb Setrtable(rtable int) (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)
...@@ -220,9 +310,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -220,9 +310,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// getlogin // getlogin
// getresgid // getresgid
// getresuid // getresuid
// getrtable
// getthrid // getthrid
// ioctl
// ktrace // ktrace
// lfs_bmapv // lfs_bmapv
// lfs_markv // lfs_markv
...@@ -257,7 +345,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { ...@@ -257,7 +345,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// semop // semop
// setgroups // setgroups
// setitimer // setitimer
// setrtable
// setsockopt // setsockopt
// shmat // shmat
// shmctl // shmctl
......
...@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) { ...@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
// of openbsd/amd64 the syscall is called sysctl instead of __sysctl.
const SYS___SYSCTL = SYS_SYSCTL
...@@ -23,6 +23,7 @@ type syscallFunc uintptr ...@@ -23,6 +23,7 @@ type syscallFunc uintptr
func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Family uint16 Family uint16
Index uint16 Index uint16
...@@ -34,31 +35,6 @@ type SockaddrDatalink struct { ...@@ -34,31 +35,6 @@ type SockaddrDatalink struct {
raw RawSockaddrDatalink raw RawSockaddrDatalink
} }
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
if n[i] == 0 {
return i
}
}
return len(n)
}
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
reclen, ok := direntReclen(buf)
if !ok {
return 0, false
}
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
}
//sysnb pipe(p *[2]_C_int) (n int, err error) //sysnb pipe(p *[2]_C_int) (n int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
...@@ -136,7 +112,19 @@ func Getsockname(fd int) (sa Sockaddr, err error) { ...@@ -136,7 +112,19 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
if err = getsockname(fd, &rsa, &len); err != nil { if err = getsockname(fd, &rsa, &len); err != nil {
return return
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
}
// GetsockoptString returns the string value of the socket option opt for the
// socket associated with fd at the given socket level.
func GetsockoptString(fd, level, opt int) (string, error) {
buf := make([]byte, 256)
vallen := _Socklen(len(buf))
err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
if err != nil {
return "", err
}
return string(buf[:vallen-1]), nil
} }
const ImplementsGetwd = true const ImplementsGetwd = true
...@@ -324,6 +312,16 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { ...@@ -324,6 +312,16 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
//sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys fcntl(fd int, cmd int, arg int) (val int, err error)
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
valptr, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
var err error
if errno != 0 {
err = errno
}
return int(valptr), err
}
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
...@@ -362,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error { ...@@ -362,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error {
return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
} }
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_UNIX: case AF_UNIX:
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
...@@ -413,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { ...@@ -413,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
if nfd == -1 { if nfd == -1 {
return return
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
...@@ -450,7 +448,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from ...@@ -450,7 +448,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
oobn = int(msg.Accrightslen) oobn = int(msg.Accrightslen)
// source address is only specified if the socket is unconnected // source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
...@@ -601,15 +599,17 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { ...@@ -601,15 +599,17 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//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 Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid 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 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_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) //sys Fstatvfs(fd int, vfsstat *Statvfs_t) (err error)
//sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
...@@ -655,6 +655,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { ...@@ -655,6 +655,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
//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 Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
//sysnb Setegid(egid int) (err error) //sysnb 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)
...@@ -686,6 +687,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { ...@@ -686,6 +687,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
//sys munmap(addr uintptr, length uintptr) (err error) //sys munmap(addr uintptr, length uintptr) (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto
//sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket //sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair
......
...@@ -21,8 +21,3 @@ func (iov *Iovec) SetLen(length int) { ...@@ -21,8 +21,3 @@ func (iov *Iovec) SetLen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
// TODO(aram): implement this, see issue 5847.
panic("unimplemented")
}
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
package unix package unix
import ( import (
"bytes"
"runtime" "runtime"
"sort"
"sync" "sync"
"syscall" "syscall"
"unsafe" "unsafe"
...@@ -50,6 +52,37 @@ func errnoErr(e syscall.Errno) error { ...@@ -50,6 +52,37 @@ func errnoErr(e syscall.Errno) error {
return e return e
} }
// ErrnoName returns the error name for error number e.
func ErrnoName(e syscall.Errno) string {
i := sort.Search(len(errorList), func(i int) bool {
return errorList[i].num >= e
})
if i < len(errorList) && errorList[i].num == e {
return errorList[i].name
}
return ""
}
// SignalName returns the signal name for signal number s.
func SignalName(s syscall.Signal) string {
i := sort.Search(len(signalList), func(i int) bool {
return signalList[i].num >= s
})
if i < len(signalList) && signalList[i].num == s {
return signalList[i].name
}
return ""
}
// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
func clen(n []byte) int {
i := bytes.IndexByte(n, 0)
if i == -1 {
i = len(n)
}
return i
}
// Mmap manager, for use by operating system-specific implementations. // Mmap manager, for use by operating system-specific implementations.
type mmapper struct { type mmapper struct {
...@@ -138,16 +171,19 @@ func Write(fd int, p []byte) (n int, err error) { ...@@ -138,16 +171,19 @@ func Write(fd int, p []byte) (n int, err error) {
// creation of IPv6 sockets to return EAFNOSUPPORT. // creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool var SocketDisableIPv6 bool
// Sockaddr represents a socket address.
type Sockaddr interface { type Sockaddr interface {
sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
} }
// SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
type SockaddrInet4 struct { type SockaddrInet4 struct {
Port int Port int
Addr [4]byte Addr [4]byte
raw RawSockaddrInet4 raw RawSockaddrInet4
} }
// SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
type SockaddrInet6 struct { type SockaddrInet6 struct {
Port int Port int
ZoneId uint32 ZoneId uint32
...@@ -155,6 +191,7 @@ type SockaddrInet6 struct { ...@@ -155,6 +191,7 @@ type SockaddrInet6 struct {
raw RawSockaddrInet6 raw RawSockaddrInet6
} }
// SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
type SockaddrUnix struct { type SockaddrUnix struct {
Name string Name string
raw RawSockaddrUnix raw RawSockaddrUnix
...@@ -182,7 +219,14 @@ func Getpeername(fd int) (sa Sockaddr, err error) { ...@@ -182,7 +219,14 @@ func Getpeername(fd int) (sa Sockaddr, err error) {
if err = getpeername(fd, &rsa, &len); err != nil { if err = getpeername(fd, &rsa, &len); err != nil {
return return
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
}
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
var n byte
vallen := _Socklen(1)
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
return n, err
} }
func GetsockoptInt(fd, level, opt int) (value int, err error) { func GetsockoptInt(fd, level, opt int) (value int, err error) {
...@@ -192,6 +236,54 @@ func GetsockoptInt(fd, level, opt int) (value int, err error) { ...@@ -192,6 +236,54 @@ func GetsockoptInt(fd, level, opt int) (value int, err error) {
return int(n), err return int(n), err
} }
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
vallen := _Socklen(4)
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
return value, err
}
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
var value IPMreq
vallen := _Socklen(SizeofIPMreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
var value IPv6Mreq
vallen := _Socklen(SizeofIPv6Mreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
var value IPv6MTUInfo
vallen := _Socklen(SizeofIPv6MTUInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
var value ICMPv6Filter
vallen := _Socklen(SizeofICMPv6Filter)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
var linger Linger
vallen := _Socklen(SizeofLinger)
err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
return &linger, err
}
func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
var tv Timeval
vallen := _Socklen(unsafe.Sizeof(tv))
err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
return &tv, err
}
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
var rsa RawSockaddrAny var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny var len _Socklen = SizeofSockaddrAny
...@@ -199,7 +291,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { ...@@ -199,7 +291,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
return return
} }
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
...@@ -291,3 +383,12 @@ func SetNonblock(fd int, nonblocking bool) (err error) { ...@@ -291,3 +383,12 @@ func SetNonblock(fd int, nonblocking bool) (err error) {
_, err = fcntl(fd, F_SETFL, flag) _, err = fcntl(fd, F_SETFL, flag)
return err return err
} }
// Exec calls execve(2), which replaces the calling executable in the process
// tree. argv0 should be the full path to an executable ("/bin/ls") and the
// executable name should also be the first argument in argv (["ls", "-l"]).
// envv are the environment variables that should be passed to the new
// process (["USER=go", "PWD=/tmp"]).
func Exec(argv0 string, argv []string, envv []string) error {
return syscall.Exec(argv0, argv, envv)
}
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
package unix package unix
import "time"
// TimespecToNsec converts a Timespec value into a number of // TimespecToNsec converts a Timespec value into a number of
// nanoseconds since the Unix epoch. // nanoseconds since the Unix epoch.
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
...@@ -22,6 +24,24 @@ func NsecToTimespec(nsec int64) Timespec { ...@@ -22,6 +24,24 @@ func NsecToTimespec(nsec int64) Timespec {
return setTimespec(sec, nsec) return setTimespec(sec, nsec)
} }
// TimeToTimespec converts t into a Timespec.
// On some 32-bit systems the range of valid Timespec values are smaller
// than that of time.Time values. So if t is out of the valid range of
// Timespec, it returns a zero Timespec and ERANGE.
func TimeToTimespec(t time.Time) (Timespec, error) {
sec := t.Unix()
nsec := int64(t.Nanosecond())
ts := setTimespec(sec, nsec)
// Currently all targets have either int32 or int64 for Timespec.Sec.
// If there were a new target with floating point type for it, we have
// to consider the rounding error.
if int64(ts.Sec) != sec {
return Timespec{}, ERANGE
}
return ts, nil
}
// TimevalToNsec converts a Timeval value into a number of nanoseconds // TimevalToNsec converts a Timeval value into a number of nanoseconds
// since the Unix epoch. // since the Unix epoch.
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
......
...@@ -39,6 +39,7 @@ package unix ...@@ -39,6 +39,7 @@ package unix
#include <sys/types.h> #include <sys/types.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
...@@ -270,3 +271,7 @@ const ( ...@@ -270,3 +271,7 @@ const (
POLLWRBAND = C.POLLWRBAND POLLWRBAND = C.POLLWRBAND
POLLWRNORM = C.POLLWRNORM POLLWRNORM = C.POLLWRNORM
) )
// uname
type Utsname C.struct_utsname
...@@ -35,6 +35,7 @@ package unix ...@@ -35,6 +35,7 @@ package unix
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
...@@ -126,6 +127,12 @@ type Dirent C.struct_dirent ...@@ -126,6 +127,12 @@ type Dirent C.struct_dirent
type Fsid C.struct_fsid type Fsid C.struct_fsid
// File system limits
const (
PathMax = C.PATH_MAX
)
// Sockets // Sockets
type RawSockaddrInet4 C.struct_sockaddr_in type RawSockaddrInet4 C.struct_sockaddr_in
...@@ -242,6 +249,8 @@ type BpfHdr C.struct_bpf_hdr ...@@ -242,6 +249,8 @@ type BpfHdr C.struct_bpf_hdr
type Termios C.struct_termios type Termios C.struct_termios
type Winsize C.struct_winsize
// fchmodat-like syscalls. // fchmodat-like syscalls.
const ( const (
...@@ -265,3 +274,7 @@ const ( ...@@ -265,3 +274,7 @@ const (
POLLWRBAND = C.POLLWRBAND POLLWRBAND = C.POLLWRBAND
POLLWRNORM = C.POLLWRNORM POLLWRNORM = C.POLLWRNORM
) )
// Uname
type Utsname C.struct_utsname
...@@ -36,6 +36,7 @@ package unix ...@@ -36,6 +36,7 @@ package unix
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
...@@ -215,6 +216,12 @@ type Dirent C.struct_dirent ...@@ -215,6 +216,12 @@ type Dirent C.struct_dirent
type Fsid C.struct_fsid type Fsid C.struct_fsid
// File system limits
const (
PathMax = C.PATH_MAX
)
// Advice to Fadvise // Advice to Fadvise
const ( const (
...@@ -389,3 +396,7 @@ const ( ...@@ -389,3 +396,7 @@ const (
// Capabilities // Capabilities
type CapRights C.struct_cap_rights type CapRights C.struct_cap_rights
// Uname
type Utsname C.struct_utsname
...@@ -37,6 +37,7 @@ package unix ...@@ -37,6 +37,7 @@ package unix
#include <sys/time.h> #include <sys/time.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
...@@ -111,6 +112,23 @@ type Dirent C.struct_dirent ...@@ -111,6 +112,23 @@ type Dirent C.struct_dirent
type Fsid C.fsid_t type Fsid C.fsid_t
// File system limits
const (
PathMax = C.PATH_MAX
)
// Advice to Fadvise
const (
FADV_NORMAL = C.POSIX_FADV_NORMAL
FADV_RANDOM = C.POSIX_FADV_RANDOM
FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL
FADV_WILLNEED = C.POSIX_FADV_WILLNEED
FADV_DONTNEED = C.POSIX_FADV_DONTNEED
FADV_NOREUSE = C.POSIX_FADV_NOREUSE
)
// Sockets // Sockets
type RawSockaddrInet4 C.struct_sockaddr_in type RawSockaddrInet4 C.struct_sockaddr_in
...@@ -228,6 +246,8 @@ type BpfTimeval C.struct_bpf_timeval ...@@ -228,6 +246,8 @@ type BpfTimeval C.struct_bpf_timeval
type Termios C.struct_termios type Termios C.struct_termios
type Winsize C.struct_winsize
// fchmodat-like syscalls. // fchmodat-like syscalls.
const ( const (
...@@ -255,3 +275,7 @@ const ( ...@@ -255,3 +275,7 @@ const (
// Sysctl // Sysctl
type Sysctlnode C.struct_sysctlnode type Sysctlnode C.struct_sysctlnode
// Uname
type Utsname C.struct_utsname
...@@ -36,6 +36,7 @@ package unix ...@@ -36,6 +36,7 @@ package unix
#include <sys/time.h> #include <sys/time.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
...@@ -127,6 +128,12 @@ type Dirent C.struct_dirent ...@@ -127,6 +128,12 @@ type Dirent C.struct_dirent
type Fsid C.fsid_t type Fsid C.fsid_t
// File system limits
const (
PathMax = C.PATH_MAX
)
// Sockets // Sockets
type RawSockaddrInet4 C.struct_sockaddr_in type RawSockaddrInet4 C.struct_sockaddr_in
...@@ -244,6 +251,8 @@ type BpfTimeval C.struct_bpf_timeval ...@@ -244,6 +251,8 @@ type BpfTimeval C.struct_bpf_timeval
type Termios C.struct_termios type Termios C.struct_termios
type Winsize C.struct_winsize
// fchmodat-like syscalls. // fchmodat-like syscalls.
const ( const (
...@@ -267,3 +276,7 @@ const ( ...@@ -267,3 +276,7 @@ const (
POLLWRBAND = C.POLLWRBAND POLLWRBAND = C.POLLWRBAND
POLLWRNORM = C.POLLWRNORM POLLWRNORM = C.POLLWRNORM
) )
// Uname
type Utsname C.struct_utsname
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment