mirror of https://github.com/ethereum/go-ethereum
Merge pull request #19072 from karalabe/update-syscalls
vendor: update syscalls dependencypull/19087/head
commit
fab8c5a1cd
@ -0,0 +1,61 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !amd64,!amd64p32,!386
|
||||
|
||||
package cpu |
||||
|
||||
import ( |
||||
"encoding/binary" |
||||
"io/ioutil" |
||||
"runtime" |
||||
) |
||||
|
||||
const ( |
||||
_AT_HWCAP = 16 |
||||
_AT_HWCAP2 = 26 |
||||
|
||||
procAuxv = "/proc/self/auxv" |
||||
|
||||
uintSize uint = 32 << (^uint(0) >> 63) |
||||
) |
||||
|
||||
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
|
||||
// These are initialized in cpu_$GOARCH.go
|
||||
// and should not be changed after they are initialized.
|
||||
var HWCap uint |
||||
var HWCap2 uint |
||||
|
||||
func init() { |
||||
buf, err := ioutil.ReadFile(procAuxv) |
||||
if err != nil { |
||||
panic("read proc auxv failed: " + err.Error()) |
||||
} |
||||
|
||||
pb := int(uintSize / 8) |
||||
|
||||
for i := 0; i < len(buf)-pb*2; i += pb * 2 { |
||||
var tag, val uint |
||||
switch uintSize { |
||||
case 32: |
||||
tag = uint(binary.LittleEndian.Uint32(buf[i:])) |
||||
val = uint(binary.LittleEndian.Uint32(buf[i+pb:])) |
||||
case 64: |
||||
if runtime.GOARCH == "ppc64" { |
||||
tag = uint(binary.BigEndian.Uint64(buf[i:])) |
||||
val = uint(binary.BigEndian.Uint64(buf[i+pb:])) |
||||
} else { |
||||
tag = uint(binary.LittleEndian.Uint64(buf[i:])) |
||||
val = uint(binary.LittleEndian.Uint64(buf[i+pb:])) |
||||
} |
||||
} |
||||
switch tag { |
||||
case _AT_HWCAP: |
||||
HWCap = val |
||||
case _AT_HWCAP2: |
||||
HWCap2 = val |
||||
} |
||||
} |
||||
doinit() |
||||
} |
@ -0,0 +1,124 @@ |
||||
// 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) |
||||
} |
@ -0,0 +1,14 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
// +build go1.9
|
||||
|
||||
package unix |
||||
|
||||
import "syscall" |
||||
|
||||
type Signal = syscall.Signal |
||||
type Errno = syscall.Errno |
||||
type SysProcAttr = syscall.SysProcAttr |
@ -0,0 +1,17 @@ |
||||
// 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 !gccgo |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go |
||||
// |
||||
|
||||
TEXT ·syscall6(SB),NOSPLIT,$0-88 |
||||
JMP syscall·syscall6(SB) |
||||
|
||||
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88 |
||||
JMP syscall·rawSyscall6(SB) |
@ -0,0 +1,29 @@ |
||||
// 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 !gccgo |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for ARM64, FreeBSD |
||||
// |
||||
|
||||
// Just jump to package syscall's implementation for all these functions. |
||||
// The runtime may know about them. |
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
||||
JMP syscall·Syscall(SB) |
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
||||
JMP syscall·Syscall6(SB) |
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
||||
JMP syscall·Syscall9(SB) |
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
||||
JMP syscall·RawSyscall(SB) |
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
||||
JMP syscall·RawSyscall6(SB) |
@ -0,0 +1,29 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !gccgo |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for ARM64, NetBSD |
||||
// |
||||
|
||||
// Just jump to package syscall's implementation for all these functions. |
||||
// The runtime may know about them. |
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
||||
B syscall·Syscall(SB) |
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
||||
B syscall·Syscall6(SB) |
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
||||
B syscall·Syscall9(SB) |
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
||||
B syscall·RawSyscall(SB) |
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
||||
B syscall·RawSyscall6(SB) |
@ -0,0 +1,27 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by AIX.
|
||||
|
||||
package unix |
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 { |
||||
return uint32((dev >> 16) & 0xffff) |
||||
} |
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 { |
||||
return uint32(dev & 0xffff) |
||||
} |
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 { |
||||
return uint64(((major) << 16) | (minor)) |
||||
} |
@ -0,0 +1,29 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc64
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used AIX.
|
||||
|
||||
package unix |
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 { |
||||
return uint32((dev & 0x3fffffff00000000) >> 32) |
||||
} |
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 { |
||||
return uint32((dev & 0x00000000ffffffff) >> 0) |
||||
} |
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 { |
||||
var DEVNO64 uint64 |
||||
DEVNO64 = 0x8000000000000000 |
||||
return ((uint64(major) << 32) | (uint64(minor) & 0x00000000FFFFFFFF) | DEVNO64) |
||||
} |
@ -1,14 +0,0 @@ |
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.4
|
||||
|
||||
package unix |
||||
|
||||
import "syscall" |
||||
|
||||
func Unsetenv(key string) error { |
||||
// This was added in Go 1.4.
|
||||
return syscall.Unsetenv(key) |
||||
} |
@ -0,0 +1,18 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package unix |
||||
|
||||
import "unsafe" |
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) { |
||||
return fcntl(int(fd), cmd, arg) |
||||
} |
||||
|
||||
// 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 { |
||||
_, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk)))) |
||||
return err |
||||
} |
@ -0,0 +1,30 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix |
||||
|
||||
import "runtime" |
||||
|
||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
||||
//
|
||||
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
||||
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { |
||||
// TODO: if we get the chance, remove the req parameter and
|
||||
// hardcode TIOCSWINSZ.
|
||||
err := ioctlSetWinsize(fd, req, value) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
||||
|
||||
// IoctlSetTermios performs an ioctl on fd with a *Termios.
|
||||
//
|
||||
// The req value will usually be TCSETA or TIOCSETA.
|
||||
func IoctlSetTermios(fd int, req uint, value *Termios) error { |
||||
// TODO: if we get the chance, remove the req parameter.
|
||||
err := ioctlSetTermios(fd, req, value) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
@ -1,328 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
# Copyright 2009 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
|
||||
# This program reads a file containing function prototypes |
||||
# (like syscall_darwin.go) and generates system call bodies. |
||||
# The prototypes are marked by lines beginning with "//sys" |
||||
# and read like func declarations if //sys is replaced by func, but: |
||||
# * The parameter lists must give a name for each argument. |
||||
# This includes return parameters. |
||||
# * The parameter lists must give a type for each argument: |
||||
# the (x, y, z int) shorthand is not allowed. |
||||
# * If the return parameter is an error number, it must be named errno. |
||||
|
||||
# A line beginning with //sysnb is like //sys, except that the |
||||
# goroutine will not be suspended during the execution of the system |
||||
# call. This must only be used for system calls which can never |
||||
# block, as otherwise the system call could cause all goroutines to |
||||
# hang. |
||||
|
||||
use strict; |
||||
|
||||
my $cmdline = "mksyscall.pl " . join(' ', @ARGV); |
||||
my $errors = 0; |
||||
my $_32bit = ""; |
||||
my $plan9 = 0; |
||||
my $openbsd = 0; |
||||
my $netbsd = 0; |
||||
my $dragonfly = 0; |
||||
my $arm = 0; # 64-bit value should use (even, odd)-pair |
||||
my $tags = ""; # build tags |
||||
|
||||
if($ARGV[0] eq "-b32") { |
||||
$_32bit = "big-endian"; |
||||
shift; |
||||
} elsif($ARGV[0] eq "-l32") { |
||||
$_32bit = "little-endian"; |
||||
shift; |
||||
} |
||||
if($ARGV[0] eq "-plan9") { |
||||
$plan9 = 1; |
||||
shift; |
||||
} |
||||
if($ARGV[0] eq "-openbsd") { |
||||
$openbsd = 1; |
||||
shift; |
||||
} |
||||
if($ARGV[0] eq "-netbsd") { |
||||
$netbsd = 1; |
||||
shift; |
||||
} |
||||
if($ARGV[0] eq "-dragonfly") { |
||||
$dragonfly = 1; |
||||
shift; |
||||
} |
||||
if($ARGV[0] eq "-arm") { |
||||
$arm = 1; |
||||
shift; |
||||
} |
||||
if($ARGV[0] eq "-tags") { |
||||
shift; |
||||
$tags = $ARGV[0]; |
||||
shift; |
||||
} |
||||
|
||||
if($ARGV[0] =~ /^-/) { |
||||
print STDERR "usage: mksyscall.pl [-b32 | -l32] [-tags x,y] [file ...]\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
# Check that we are using the new build system if we should |
||||
if($ENV{'GOOS'} eq "linux" && $ENV{'GOARCH'} ne "sparc64") { |
||||
if($ENV{'GOLANG_SYS_BUILD'} ne "docker") { |
||||
print STDERR "In the new build system, mksyscall should not be called directly.\n"; |
||||
print STDERR "See README.md\n"; |
||||
exit 1; |
||||
} |
||||
} |
||||
|
||||
|
||||
sub parseparamlist($) { |
||||
my ($list) = @_; |
||||
$list =~ s/^\s*//; |
||||
$list =~ s/\s*$//; |
||||
if($list eq "") { |
||||
return (); |
||||
} |
||||
return split(/\s*,\s*/, $list); |
||||
} |
||||
|
||||
sub parseparam($) { |
||||
my ($p) = @_; |
||||
if($p !~ /^(\S*) (\S*)$/) { |
||||
print STDERR "$ARGV:$.: malformed parameter: $p\n"; |
||||
$errors = 1; |
||||
return ("xx", "int"); |
||||
} |
||||
return ($1, $2); |
||||
} |
||||
|
||||
my $text = ""; |
||||
while(<>) { |
||||
chomp; |
||||
s/\s+/ /g; |
||||
s/^\s+//; |
||||
s/\s+$//; |
||||
my $nonblock = /^\/\/sysnb /; |
||||
next if !/^\/\/sys / && !$nonblock; |
||||
|
||||
# Line must be of the form |
||||
# func Open(path string, mode int, perm int) (fd int, errno error) |
||||
# Split into name, in params, out params. |
||||
if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$/) { |
||||
print STDERR "$ARGV:$.: malformed //sys declaration\n"; |
||||
$errors = 1; |
||||
next; |
||||
} |
||||
my ($func, $in, $out, $sysname) = ($2, $3, $4, $5); |
||||
|
||||
# Split argument lists on comma. |
||||
my @in = parseparamlist($in); |
||||
my @out = parseparamlist($out); |
||||
|
||||
# Try in vain to keep people from editing this file. |
||||
# The theory is that they jump into the middle of the file |
||||
# without reading the header. |
||||
$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; |
||||
|
||||
# Go function header. |
||||
my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : ""; |
||||
$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl; |
||||
|
||||
# Check if err return available |
||||
my $errvar = ""; |
||||
foreach my $p (@out) { |
||||
my ($name, $type) = parseparam($p); |
||||
if($type eq "error") { |
||||
$errvar = $name; |
||||
last; |
||||
} |
||||
} |
||||
|
||||
# Prepare arguments to Syscall. |
||||
my @args = (); |
||||
my $n = 0; |
||||
foreach my $p (@in) { |
||||
my ($name, $type) = parseparam($p); |
||||
if($type =~ /^\*/) { |
||||
push @args, "uintptr(unsafe.Pointer($name))"; |
||||
} elsif($type eq "string" && $errvar ne "") { |
||||
$text .= "\tvar _p$n *byte\n"; |
||||
$text .= "\t_p$n, $errvar = BytePtrFromString($name)\n"; |
||||
$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; |
||||
push @args, "uintptr(unsafe.Pointer(_p$n))"; |
||||
$n++; |
||||
} elsif($type eq "string") { |
||||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; |
||||
$text .= "\tvar _p$n *byte\n"; |
||||
$text .= "\t_p$n, _ = BytePtrFromString($name)\n"; |
||||
push @args, "uintptr(unsafe.Pointer(_p$n))"; |
||||
$n++; |
||||
} elsif($type =~ /^\[\](.*)/) { |
||||
# Convert slice into pointer, length. |
||||
# Have to be careful not to take address of &a[0] if len == 0: |
||||
# pass dummy pointer in that case. |
||||
# Used to pass nil, but some OSes or simulators reject write(fd, nil, 0). |
||||
$text .= "\tvar _p$n unsafe.Pointer\n"; |
||||
$text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}"; |
||||
$text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}"; |
||||
$text .= "\n"; |
||||
push @args, "uintptr(_p$n)", "uintptr(len($name))"; |
||||
$n++; |
||||
} elsif($type eq "int64" && ($openbsd || $netbsd)) { |
||||
push @args, "0"; |
||||
if($_32bit eq "big-endian") { |
||||
push @args, "uintptr($name>>32)", "uintptr($name)"; |
||||
} elsif($_32bit eq "little-endian") { |
||||
push @args, "uintptr($name)", "uintptr($name>>32)"; |
||||
} else { |
||||
push @args, "uintptr($name)"; |
||||
} |
||||
} elsif($type eq "int64" && $dragonfly) { |
||||
if ($func !~ /^extp(read|write)/i) { |
||||
push @args, "0"; |
||||
} |
||||
if($_32bit eq "big-endian") { |
||||
push @args, "uintptr($name>>32)", "uintptr($name)"; |
||||
} elsif($_32bit eq "little-endian") { |
||||
push @args, "uintptr($name)", "uintptr($name>>32)"; |
||||
} else { |
||||
push @args, "uintptr($name)"; |
||||
} |
||||
} elsif($type eq "int64" && $_32bit ne "") { |
||||
if(@args % 2 && $arm) { |
||||
# arm abi specifies 64-bit argument uses |
||||
# (even, odd) pair |
||||
push @args, "0" |
||||
} |
||||
if($_32bit eq "big-endian") { |
||||
push @args, "uintptr($name>>32)", "uintptr($name)"; |
||||
} else { |
||||
push @args, "uintptr($name)", "uintptr($name>>32)"; |
||||
} |
||||
} else { |
||||
push @args, "uintptr($name)"; |
||||
} |
||||
} |
||||
|
||||
# Determine which form to use; pad args with zeros. |
||||
my $asm = "Syscall"; |
||||
if ($nonblock) { |
||||
$asm = "RawSyscall"; |
||||
} |
||||
if(@args <= 3) { |
||||
while(@args < 3) { |
||||
push @args, "0"; |
||||
} |
||||
} elsif(@args <= 6) { |
||||
$asm .= "6"; |
||||
while(@args < 6) { |
||||
push @args, "0"; |
||||
} |
||||
} elsif(@args <= 9) { |
||||
$asm .= "9"; |
||||
while(@args < 9) { |
||||
push @args, "0"; |
||||
} |
||||
} else { |
||||
print STDERR "$ARGV:$.: too many arguments to system call\n"; |
||||
} |
||||
|
||||
# System call number. |
||||
if($sysname eq "") { |
||||
$sysname = "SYS_$func"; |
||||
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar |
||||
$sysname =~ y/a-z/A-Z/; |
||||
} |
||||
|
||||
# Actual call. |
||||
my $args = join(', ', @args); |
||||
my $call = "$asm($sysname, $args)"; |
||||
|
||||
# Assign return values. |
||||
my $body = ""; |
||||
my @ret = ("_", "_", "_"); |
||||
my $do_errno = 0; |
||||
for(my $i=0; $i<@out; $i++) { |
||||
my $p = $out[$i]; |
||||
my ($name, $type) = parseparam($p); |
||||
my $reg = ""; |
||||
if($name eq "err" && !$plan9) { |
||||
$reg = "e1"; |
||||
$ret[2] = $reg; |
||||
$do_errno = 1; |
||||
} elsif($name eq "err" && $plan9) { |
||||
$ret[0] = "r0"; |
||||
$ret[2] = "e1"; |
||||
next; |
||||
} else { |
||||
$reg = sprintf("r%d", $i); |
||||
$ret[$i] = $reg; |
||||
} |
||||
if($type eq "bool") { |
||||
$reg = "$reg != 0"; |
||||
} |
||||
if($type eq "int64" && $_32bit ne "") { |
||||
# 64-bit number in r1:r0 or r0:r1. |
||||
if($i+2 > @out) { |
||||
print STDERR "$ARGV:$.: not enough registers for int64 return\n"; |
||||
} |
||||
if($_32bit eq "big-endian") { |
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1); |
||||
} else { |
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i); |
||||
} |
||||
$ret[$i] = sprintf("r%d", $i); |
||||
$ret[$i+1] = sprintf("r%d", $i+1); |
||||
} |
||||
if($reg ne "e1" || $plan9) { |
||||
$body .= "\t$name = $type($reg)\n"; |
||||
} |
||||
} |
||||
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { |
||||
$text .= "\t$call\n"; |
||||
} else { |
||||
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; |
||||
} |
||||
$text .= $body; |
||||
|
||||
if ($plan9 && $ret[2] eq "e1") { |
||||
$text .= "\tif int32(r0) == -1 {\n"; |
||||
$text .= "\t\terr = e1\n"; |
||||
$text .= "\t}\n"; |
||||
} elsif ($do_errno) { |
||||
$text .= "\tif e1 != 0 {\n"; |
||||
$text .= "\t\terr = errnoErr(e1)\n"; |
||||
$text .= "\t}\n"; |
||||
} |
||||
$text .= "\treturn\n"; |
||||
$text .= "}\n\n"; |
||||
} |
||||
|
||||
chomp $text; |
||||
chomp $text; |
||||
|
||||
if($errors) { |
||||
exit 1; |
||||
} |
||||
|
||||
print <<EOF; |
||||
// $cmdline |
||||
// Code generated by the command above; see README.md. DO NOT EDIT. |
||||
|
||||
// +build $tags |
||||
|
||||
package unix |
||||
|
||||
import ( |
||||
"syscall" |
||||
"unsafe" |
||||
) |
||||
|
||||
var _ syscall.Errno |
||||
|
||||
$text |
||||
EOF |
||||
exit 0; |
@ -1,289 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
# Copyright 2009 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
|
||||
# This program reads a file containing function prototypes |
||||
# (like syscall_solaris.go) and generates system call bodies. |
||||
# The prototypes are marked by lines beginning with "//sys" |
||||
# and read like func declarations if //sys is replaced by func, but: |
||||
# * The parameter lists must give a name for each argument. |
||||
# This includes return parameters. |
||||
# * The parameter lists must give a type for each argument: |
||||
# the (x, y, z int) shorthand is not allowed. |
||||
# * If the return parameter is an error number, it must be named err. |
||||
# * If go func name needs to be different than its libc name, |
||||
# * or the function is not in libc, name could be specified |
||||
# * at the end, after "=" sign, like |
||||
# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt |
||||
|
||||
use strict; |
||||
|
||||
my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV); |
||||
my $errors = 0; |
||||
my $_32bit = ""; |
||||
my $tags = ""; # build tags |
||||
|
||||
binmode STDOUT; |
||||
|
||||
if($ARGV[0] eq "-b32") { |
||||
$_32bit = "big-endian"; |
||||
shift; |
||||
} elsif($ARGV[0] eq "-l32") { |
||||
$_32bit = "little-endian"; |
||||
shift; |
||||
} |
||||
if($ARGV[0] eq "-tags") { |
||||
shift; |
||||
$tags = $ARGV[0]; |
||||
shift; |
||||
} |
||||
|
||||
if($ARGV[0] =~ /^-/) { |
||||
print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [-tags x,y] [file ...]\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
sub parseparamlist($) { |
||||
my ($list) = @_; |
||||
$list =~ s/^\s*//; |
||||
$list =~ s/\s*$//; |
||||
if($list eq "") { |
||||
return (); |
||||
} |
||||
return split(/\s*,\s*/, $list); |
||||
} |
||||
|
||||
sub parseparam($) { |
||||
my ($p) = @_; |
||||
if($p !~ /^(\S*) (\S*)$/) { |
||||
print STDERR "$ARGV:$.: malformed parameter: $p\n"; |
||||
$errors = 1; |
||||
return ("xx", "int"); |
||||
} |
||||
return ($1, $2); |
||||
} |
||||
|
||||
my $package = ""; |
||||
my $text = ""; |
||||
my $dynimports = ""; |
||||
my $linknames = ""; |
||||
my @vars = (); |
||||
while(<>) { |
||||
chomp; |
||||
s/\s+/ /g; |
||||
s/^\s+//; |
||||
s/\s+$//; |
||||
$package = $1 if !$package && /^package (\S+)$/; |
||||
my $nonblock = /^\/\/sysnb /; |
||||
next if !/^\/\/sys / && !$nonblock; |
||||
|
||||
# Line must be of the form |
||||
# func Open(path string, mode int, perm int) (fd int, err error) |
||||
# Split into name, in params, out params. |
||||
if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) { |
||||
print STDERR "$ARGV:$.: malformed //sys declaration\n"; |
||||
$errors = 1; |
||||
next; |
||||
} |
||||
my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6); |
||||
|
||||
# Split argument lists on comma. |
||||
my @in = parseparamlist($in); |
||||
my @out = parseparamlist($out); |
||||
|
||||
# So file name. |
||||
if($modname eq "") { |
||||
$modname = "libc"; |
||||
} |
||||
|
||||
# System call name. |
||||
if($sysname eq "") { |
||||
$sysname = "$func"; |
||||
} |
||||
|
||||
# System call pointer variable name. |
||||
my $sysvarname = "proc$sysname"; |
||||
|
||||
my $strconvfunc = "BytePtrFromString"; |
||||
my $strconvtype = "*byte"; |
||||
|
||||
$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. |
||||
|
||||
# Runtime import of function to allow cross-platform builds. |
||||
$dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n"; |
||||
# Link symbol to proc address variable. |
||||
$linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n"; |
||||
# Library proc address variable. |
||||
push @vars, $sysvarname; |
||||
|
||||
# Go function header. |
||||
$out = join(', ', @out); |
||||
if($out ne "") { |
||||
$out = " ($out)"; |
||||
} |
||||
if($text ne "") { |
||||
$text .= "\n" |
||||
} |
||||
$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out; |
||||
|
||||
# Check if err return available |
||||
my $errvar = ""; |
||||
foreach my $p (@out) { |
||||
my ($name, $type) = parseparam($p); |
||||
if($type eq "error") { |
||||
$errvar = $name; |
||||
last; |
||||
} |
||||
} |
||||
|
||||
# Prepare arguments to Syscall. |
||||
my @args = (); |
||||
my $n = 0; |
||||
foreach my $p (@in) { |
||||
my ($name, $type) = parseparam($p); |
||||
if($type =~ /^\*/) { |
||||
push @args, "uintptr(unsafe.Pointer($name))"; |
||||
} elsif($type eq "string" && $errvar ne "") { |
||||
$text .= "\tvar _p$n $strconvtype\n"; |
||||
$text .= "\t_p$n, $errvar = $strconvfunc($name)\n"; |
||||
$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; |
||||
push @args, "uintptr(unsafe.Pointer(_p$n))"; |
||||
$n++; |
||||
} elsif($type eq "string") { |
||||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; |
||||
$text .= "\tvar _p$n $strconvtype\n"; |
||||
$text .= "\t_p$n, _ = $strconvfunc($name)\n"; |
||||
push @args, "uintptr(unsafe.Pointer(_p$n))"; |
||||
$n++; |
||||
} elsif($type =~ /^\[\](.*)/) { |
||||
# Convert slice into pointer, length. |
||||
# Have to be careful not to take address of &a[0] if len == 0: |
||||
# pass nil in that case. |
||||
$text .= "\tvar _p$n *$1\n"; |
||||
$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n"; |
||||
push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))"; |
||||
$n++; |
||||
} elsif($type eq "int64" && $_32bit ne "") { |
||||
if($_32bit eq "big-endian") { |
||||
push @args, "uintptr($name >> 32)", "uintptr($name)"; |
||||
} else { |
||||
push @args, "uintptr($name)", "uintptr($name >> 32)"; |
||||
} |
||||
} elsif($type eq "bool") { |
||||
$text .= "\tvar _p$n uint32\n"; |
||||
$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n"; |
||||
push @args, "uintptr(_p$n)"; |
||||
$n++; |
||||
} else { |
||||
push @args, "uintptr($name)"; |
||||
} |
||||
} |
||||
my $nargs = @args; |
||||
|
||||
# Determine which form to use; pad args with zeros. |
||||
my $asm = "sysvicall6"; |
||||
if ($nonblock) { |
||||
$asm = "rawSysvicall6"; |
||||
} |
||||
if(@args <= 6) { |
||||
while(@args < 6) { |
||||
push @args, "0"; |
||||
} |
||||
} else { |
||||
print STDERR "$ARGV:$.: too many arguments to system call\n"; |
||||
} |
||||
|
||||
# Actual call. |
||||
my $args = join(', ', @args); |
||||
my $call = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $args)"; |
||||
|
||||
# Assign return values. |
||||
my $body = ""; |
||||
my $failexpr = ""; |
||||
my @ret = ("_", "_", "_"); |
||||
my @pout= (); |
||||
my $do_errno = 0; |
||||
for(my $i=0; $i<@out; $i++) { |
||||
my $p = $out[$i]; |
||||
my ($name, $type) = parseparam($p); |
||||
my $reg = ""; |
||||
if($name eq "err") { |
||||
$reg = "e1"; |
||||
$ret[2] = $reg; |
||||
$do_errno = 1; |
||||
} else { |
||||
$reg = sprintf("r%d", $i); |
||||
$ret[$i] = $reg; |
||||
} |
||||
if($type eq "bool") { |
||||
$reg = "$reg != 0"; |
||||
} |
||||
if($type eq "int64" && $_32bit ne "") { |
||||
# 64-bit number in r1:r0 or r0:r1. |
||||
if($i+2 > @out) { |
||||
print STDERR "$ARGV:$.: not enough registers for int64 return\n"; |
||||
} |
||||
if($_32bit eq "big-endian") { |
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1); |
||||
} else { |
||||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i); |
||||
} |
||||
$ret[$i] = sprintf("r%d", $i); |
||||
$ret[$i+1] = sprintf("r%d", $i+1); |
||||
} |
||||
if($reg ne "e1") { |
||||
$body .= "\t$name = $type($reg)\n"; |
||||
} |
||||
} |
||||
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { |
||||
$text .= "\t$call\n"; |
||||
} else { |
||||
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; |
||||
} |
||||
$text .= $body; |
||||
|
||||
if ($do_errno) { |
||||
$text .= "\tif e1 != 0 {\n"; |
||||
$text .= "\t\terr = e1\n"; |
||||
$text .= "\t}\n"; |
||||
} |
||||
$text .= "\treturn\n"; |
||||
$text .= "}\n"; |
||||
} |
||||
|
||||
if($errors) { |
||||
exit 1; |
||||
} |
||||
|
||||
print <<EOF; |
||||
// $cmdline |
||||
// Code generated by the command above; see README.md. DO NOT EDIT. |
||||
|
||||
// +build $tags |
||||
|
||||
package $package |
||||
|
||||
import ( |
||||
"syscall" |
||||
"unsafe" |
||||
) |
||||
EOF |
||||
|
||||
print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; |
||||
|
||||
my $vardecls = "\t" . join(",\n\t", @vars); |
||||
$vardecls .= " syscallFunc"; |
||||
|
||||
chomp($_=<<EOF); |
||||
|
||||
$dynimports |
||||
$linknames |
||||
var ( |
||||
$vardecls |
||||
) |
||||
|
||||
$text |
||||
EOF |
||||
print $_; |
||||
exit 0; |
@ -1,39 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
# Copyright 2009 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
# |
||||
# Generate system call table for Darwin from sys/syscall.h |
||||
|
||||
use strict; |
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { |
||||
print STDERR "GOARCH or GOOS not defined in environment\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
my $command = "mksysnum_darwin.pl " . join(' ', @ARGV); |
||||
|
||||
print <<EOF; |
||||
// $command |
||||
// Code generated by the command above; see README.md. DO NOT EDIT. |
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} |
||||
|
||||
package unix |
||||
|
||||
const ( |
||||
EOF |
||||
|
||||
while(<>){ |
||||
if(/^#define\s+SYS_(\w+)\s+([0-9]+)/){ |
||||
my $name = $1; |
||||
my $num = $2; |
||||
$name =~ y/a-z/A-Z/; |
||||
print " SYS_$name = $num;" |
||||
} |
||||
} |
||||
|
||||
print <<EOF; |
||||
) |
||||
EOF |
@ -1,50 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
# Copyright 2009 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
# |
||||
# Generate system call table for DragonFly from master list |
||||
# (for example, /usr/src/sys/kern/syscalls.master). |
||||
|
||||
use strict; |
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { |
||||
print STDERR "GOARCH or GOOS not defined in environment\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
my $command = "mksysnum_dragonfly.pl " . join(' ', @ARGV); |
||||
|
||||
print <<EOF; |
||||
// $command |
||||
// Code generated by the command above; see README.md. DO NOT EDIT. |
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} |
||||
|
||||
package unix |
||||
|
||||
const ( |
||||
EOF |
||||
|
||||
while(<>){ |
||||
if(/^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$/){ |
||||
my $num = $1; |
||||
my $proto = $2; |
||||
my $name = "SYS_$3"; |
||||
$name =~ y/a-z/A-Z/; |
||||
|
||||
# There are multiple entries for enosys and nosys, so comment them out. |
||||
if($name =~ /^SYS_E?NOSYS$/){ |
||||
$name = "// $name"; |
||||
} |
||||
if($name eq 'SYS_SYS_EXIT'){ |
||||
$name = 'SYS_EXIT'; |
||||
} |
||||
|
||||
print " $name = $num; // $proto\n"; |
||||
} |
||||
} |
||||
|
||||
print <<EOF; |
||||
) |
||||
EOF |
@ -1,50 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
# Copyright 2009 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
# |
||||
# Generate system call table for FreeBSD from master list |
||||
# (for example, /usr/src/sys/kern/syscalls.master). |
||||
|
||||
use strict; |
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { |
||||
print STDERR "GOARCH or GOOS not defined in environment\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
my $command = "mksysnum_freebsd.pl " . join(' ', @ARGV); |
||||
|
||||
print <<EOF; |
||||
// $command |
||||
// Code generated by the command above; see README.md. DO NOT EDIT. |
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} |
||||
|
||||
package unix |
||||
|
||||
const ( |
||||
EOF |
||||
|
||||
while(<>){ |
||||
if(/^([0-9]+)\s+\S+\s+STD\s+({ \S+\s+(\w+).*)$/){ |
||||
my $num = $1; |
||||
my $proto = $2; |
||||
my $name = "SYS_$3"; |
||||
$name =~ y/a-z/A-Z/; |
||||
|
||||
# There are multiple entries for enosys and nosys, so comment them out. |
||||
if($name =~ /^SYS_E?NOSYS$/){ |
||||
$name = "// $name"; |
||||
} |
||||
if($name eq 'SYS_SYS_EXIT'){ |
||||
$name = 'SYS_EXIT'; |
||||
} |
||||
|
||||
print " $name = $num; // $proto\n"; |
||||
} |
||||
} |
||||
|
||||
print <<EOF; |
||||
) |
||||
EOF |
@ -1,58 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
# Copyright 2009 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
# |
||||
# Generate system call table for OpenBSD from master list |
||||
# (for example, /usr/src/sys/kern/syscalls.master). |
||||
|
||||
use strict; |
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { |
||||
print STDERR "GOARCH or GOOS not defined in environment\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
my $command = "mksysnum_netbsd.pl " . join(' ', @ARGV); |
||||
|
||||
print <<EOF; |
||||
// $command |
||||
// Code generated by the command above; see README.md. DO NOT EDIT. |
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} |
||||
|
||||
package unix |
||||
|
||||
const ( |
||||
EOF |
||||
|
||||
my $line = ''; |
||||
while(<>){ |
||||
if($line =~ /^(.*)\\$/) { |
||||
# Handle continuation |
||||
$line = $1; |
||||
$_ =~ s/^\s+//; |
||||
$line .= $_; |
||||
} else { |
||||
# New line |
||||
$line = $_; |
||||
} |
||||
next if $line =~ /\\$/; |
||||
if($line =~ /^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$/) { |
||||
my $num = $1; |
||||
my $proto = $6; |
||||
my $compat = $8; |
||||
my $name = "$7_$9"; |
||||
|
||||
$name = "$7_$11" if $11 ne ''; |
||||
$name =~ y/a-z/A-Z/; |
||||
|
||||
if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') { |
||||
print " $name = $num; // $proto\n"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
print <<EOF; |
||||
) |
||||
EOF |
@ -1,50 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
# Copyright 2009 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
# |
||||
# Generate system call table for OpenBSD from master list |
||||
# (for example, /usr/src/sys/kern/syscalls.master). |
||||
|
||||
use strict; |
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { |
||||
print STDERR "GOARCH or GOOS not defined in environment\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
my $command = "mksysnum_openbsd.pl " . join(' ', @ARGV); |
||||
|
||||
print <<EOF; |
||||
// $command |
||||
// Code generated by the command above; see README.md. DO NOT EDIT. |
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} |
||||
|
||||
package unix |
||||
|
||||
const ( |
||||
EOF |
||||
|
||||
while(<>){ |
||||
if(/^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$/){ |
||||
my $num = $1; |
||||
my $proto = $3; |
||||
my $name = $4; |
||||
$name =~ y/a-z/A-Z/; |
||||
|
||||
# There are multiple entries for enosys and nosys, so comment them out. |
||||
if($name =~ /^SYS_E?NOSYS$/){ |
||||
$name = "// $name"; |
||||
} |
||||
if($name eq 'SYS_SYS_EXIT'){ |
||||
$name = 'SYS_EXIT'; |
||||
} |
||||
|
||||
print " $name = $num; // $proto\n"; |
||||
} |
||||
} |
||||
|
||||
print <<EOF; |
||||
) |
||||
EOF |
@ -0,0 +1,44 @@ |
||||
// 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 openbsd
|
||||
|
||||
package unix |
||||
|
||||
import ( |
||||
"syscall" |
||||
"unsafe" |
||||
) |
||||
|
||||
// Unveil implements the unveil syscall.
|
||||
// For more information see unveil(2).
|
||||
// Note that the special case of blocking further
|
||||
// unveil calls is handled by UnveilBlock.
|
||||
func Unveil(path string, flags string) error { |
||||
pathPtr, err := syscall.BytePtrFromString(path) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
flagsPtr, err := syscall.BytePtrFromString(flags) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
_, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(unsafe.Pointer(pathPtr)), uintptr(unsafe.Pointer(flagsPtr)), 0) |
||||
if e != 0 { |
||||
return e |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// UnveilBlock blocks future unveil calls.
|
||||
// For more information see unveil(2).
|
||||
func UnveilBlock() error { |
||||
// Both pointers must be nil.
|
||||
var pathUnsafe, flagsUnsafe unsafe.Pointer |
||||
_, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(pathUnsafe), uintptr(flagsUnsafe), 0) |
||||
if e != 0 { |
||||
return e |
||||
} |
||||
return nil |
||||
} |
@ -0,0 +1,547 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
|
||||
// Aix system calls.
|
||||
// This file is compiled as ordinary Go code,
|
||||
// but it is also input to mksyscall,
|
||||
// which parses the //sys lines and generates system call stubs.
|
||||
// Note that sometimes we use a lowercase //sys name and
|
||||
// wrap it in our own nicer implementation.
|
||||
|
||||
package unix |
||||
|
||||
import "unsafe" |
||||
|
||||
/* |
||||
* Wrapped |
||||
*/ |
||||
|
||||
//sys utimes(path string, times *[2]Timeval) (err error)
|
||||
func Utimes(path string, tv []Timeval) error { |
||||
if len(tv) != 2 { |
||||
return EINVAL |
||||
} |
||||
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) |
||||
} |
||||
|
||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
|
||||
func UtimesNano(path string, ts []Timespec) error { |
||||
if len(ts) != 2 { |
||||
return EINVAL |
||||
} |
||||
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) |
||||
} |
||||
|
||||
func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { |
||||
if ts == nil { |
||||
return utimensat(dirfd, path, nil, flags) |
||||
} |
||||
if len(ts) != 2 { |
||||
return EINVAL |
||||
} |
||||
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) |
||||
} |
||||
|
||||
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { |
||||
if sa.Port < 0 || sa.Port > 0xFFFF { |
||||
return nil, 0, EINVAL |
||||
} |
||||
sa.raw.Family = AF_INET |
||||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) |
||||
p[0] = byte(sa.Port >> 8) |
||||
p[1] = byte(sa.Port) |
||||
for i := 0; i < len(sa.Addr); i++ { |
||||
sa.raw.Addr[i] = sa.Addr[i] |
||||
} |
||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil |
||||
} |
||||
|
||||
func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { |
||||
if sa.Port < 0 || sa.Port > 0xFFFF { |
||||
return nil, 0, EINVAL |
||||
} |
||||
sa.raw.Family = AF_INET6 |
||||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) |
||||
p[0] = byte(sa.Port >> 8) |
||||
p[1] = byte(sa.Port) |
||||
sa.raw.Scope_id = sa.ZoneId |
||||
for i := 0; i < len(sa.Addr); i++ { |
||||
sa.raw.Addr[i] = sa.Addr[i] |
||||
} |
||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil |
||||
} |
||||
|
||||
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { |
||||
name := sa.Name |
||||
n := len(name) |
||||
if n > len(sa.raw.Path) { |
||||
return nil, 0, EINVAL |
||||
} |
||||
if n == len(sa.raw.Path) && name[0] != '@' { |
||||
return nil, 0, EINVAL |
||||
} |
||||
sa.raw.Family = AF_UNIX |
||||
for i := 0; i < n; i++ { |
||||
sa.raw.Path[i] = uint8(name[i]) |
||||
} |
||||
// length is family (uint16), name, NUL.
|
||||
sl := _Socklen(2) |
||||
if n > 0 { |
||||
sl += _Socklen(n) + 1 |
||||
} |
||||
if sa.raw.Path[0] == '@' { |
||||
sa.raw.Path[0] = 0 |
||||
// Don't count trailing NUL for abstract address.
|
||||
sl-- |
||||
} |
||||
|
||||
return unsafe.Pointer(&sa.raw), sl, nil |
||||
} |
||||
|
||||
func Getsockname(fd int) (sa Sockaddr, err error) { |
||||
var rsa RawSockaddrAny |
||||
var len _Socklen = SizeofSockaddrAny |
||||
if err = getsockname(fd, &rsa, &len); err != nil { |
||||
return |
||||
} |
||||
return anyToSockaddr(fd, &rsa) |
||||
} |
||||
|
||||
//sys getcwd(buf []byte) (err error)
|
||||
|
||||
const ImplementsGetwd = true |
||||
|
||||
func Getwd() (ret string, err error) { |
||||
for len := uint64(4096); ; len *= 2 { |
||||
b := make([]byte, len) |
||||
err := getcwd(b) |
||||
if err == nil { |
||||
i := 0 |
||||
for b[i] != 0 { |
||||
i++ |
||||
} |
||||
return string(b[0:i]), nil |
||||
} |
||||
if err != ERANGE { |
||||
return "", err |
||||
} |
||||
} |
||||
} |
||||
|
||||
func Getcwd(buf []byte) (n int, err error) { |
||||
err = getcwd(buf) |
||||
if err == nil { |
||||
i := 0 |
||||
for buf[i] != 0 { |
||||
i++ |
||||
} |
||||
n = i + 1 |
||||
} |
||||
return |
||||
} |
||||
|
||||
func Getgroups() (gids []int, err error) { |
||||
n, err := getgroups(0, nil) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
if n == 0 { |
||||
return nil, nil |
||||
} |
||||
|
||||
// Sanity check group count. Max is 16 on BSD.
|
||||
if n < 0 || n > 1000 { |
||||
return nil, EINVAL |
||||
} |
||||
|
||||
a := make([]_Gid_t, n) |
||||
n, err = getgroups(n, &a[0]) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
gids = make([]int, n) |
||||
for i, v := range a[0:n] { |
||||
gids[i] = int(v) |
||||
} |
||||
return |
||||
} |
||||
|
||||
func Setgroups(gids []int) (err error) { |
||||
if len(gids) == 0 { |
||||
return setgroups(0, nil) |
||||
} |
||||
|
||||
a := make([]_Gid_t, len(gids)) |
||||
for i, v := range gids { |
||||
a[i] = _Gid_t(v) |
||||
} |
||||
return setgroups(len(a), &a[0]) |
||||
} |
||||
|
||||
/* |
||||
* Socket |
||||
*/ |
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
|
||||
func Accept(fd int) (nfd int, sa Sockaddr, err error) { |
||||
var rsa RawSockaddrAny |
||||
var len _Socklen = SizeofSockaddrAny |
||||
nfd, err = accept(fd, &rsa, &len) |
||||
if nfd == -1 { |
||||
return |
||||
} |
||||
sa, err = anyToSockaddr(fd, &rsa) |
||||
if err != nil { |
||||
Close(nfd) |
||||
nfd = 0 |
||||
} |
||||
return |
||||
} |
||||
|
||||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
||||
// Recvmsg not implemented on AIX
|
||||
sa := new(SockaddrUnix) |
||||
return -1, -1, -1, sa, ENOSYS |
||||
} |
||||
|
||||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { |
||||
_, err = SendmsgN(fd, p, oob, to, flags) |
||||
return |
||||
} |
||||
|
||||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { |
||||
// SendmsgN not implemented on AIX
|
||||
return -1, ENOSYS |
||||
} |
||||
|
||||
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { |
||||
switch rsa.Addr.Family { |
||||
|
||||
case AF_UNIX: |
||||
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) |
||||
sa := new(SockaddrUnix) |
||||
|
||||
// Some versions of AIX have a bug in getsockname (see IV78655).
|
||||
// We can't rely on sa.Len being set correctly.
|
||||
n := SizeofSockaddrUnix - 3 // subtract leading Family, Len, terminating NUL.
|
||||
for i := 0; i < n; i++ { |
||||
if pp.Path[i] == 0 { |
||||
n = i |
||||
break |
||||
} |
||||
} |
||||
|
||||
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] |
||||
sa.Name = string(bytes) |
||||
return sa, nil |
||||
|
||||
case AF_INET: |
||||
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) |
||||
sa := new(SockaddrInet4) |
||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
||||
sa.Port = int(p[0])<<8 + int(p[1]) |
||||
for i := 0; i < len(sa.Addr); i++ { |
||||
sa.Addr[i] = pp.Addr[i] |
||||
} |
||||
return sa, nil |
||||
|
||||
case AF_INET6: |
||||
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) |
||||
sa := new(SockaddrInet6) |
||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
||||
sa.Port = int(p[0])<<8 + int(p[1]) |
||||
sa.ZoneId = pp.Scope_id |
||||
for i := 0; i < len(sa.Addr); i++ { |
||||
sa.Addr[i] = pp.Addr[i] |
||||
} |
||||
return sa, nil |
||||
} |
||||
return nil, EAFNOSUPPORT |
||||
} |
||||
|
||||
func Gettimeofday(tv *Timeval) (err error) { |
||||
err = gettimeofday(tv, nil) |
||||
return |
||||
} |
||||
|
||||
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
||||
if raceenabled { |
||||
raceReleaseMerge(unsafe.Pointer(&ioSync)) |
||||
} |
||||
return sendfile(outfd, infd, offset, count) |
||||
} |
||||
|
||||
// TODO
|
||||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
||||
return -1, ENOSYS |
||||
} |
||||
|
||||
//sys getdirent(fd int, buf []byte) (n int, err error)
|
||||
func ReadDirent(fd int, buf []byte) (n int, err error) { |
||||
return getdirent(fd, buf) |
||||
} |
||||
|
||||
//sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error)
|
||||
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { |
||||
var status _C_int |
||||
var r Pid_t |
||||
err = ERESTART |
||||
// AIX wait4 may return with ERESTART errno, while the processus is still
|
||||
// active.
|
||||
for err == ERESTART { |
||||
r, err = wait4(Pid_t(pid), &status, options, rusage) |
||||
} |
||||
wpid = int(r) |
||||
if wstatus != nil { |
||||
*wstatus = WaitStatus(status) |
||||
} |
||||
return |
||||
} |
||||
|
||||
/* |
||||
* Wait |
||||
*/ |
||||
|
||||
type WaitStatus uint32 |
||||
|
||||
func (w WaitStatus) Stopped() bool { return w&0x40 != 0 } |
||||
func (w WaitStatus) StopSignal() Signal { |
||||
if !w.Stopped() { |
||||
return -1 |
||||
} |
||||
return Signal(w>>8) & 0xFF |
||||
} |
||||
|
||||
func (w WaitStatus) Exited() bool { return w&0xFF == 0 } |
||||
func (w WaitStatus) ExitStatus() int { |
||||
if !w.Exited() { |
||||
return -1 |
||||
} |
||||
return int((w >> 8) & 0xFF) |
||||
} |
||||
|
||||
func (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 } |
||||
func (w WaitStatus) Signal() Signal { |
||||
if !w.Signaled() { |
||||
return -1 |
||||
} |
||||
return Signal(w>>16) & 0xFF |
||||
} |
||||
|
||||
func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 } |
||||
|
||||
func (w WaitStatus) CoreDump() bool { return w&0x200 != 0 } |
||||
|
||||
func (w WaitStatus) TrapCause() int { return -1 } |
||||
|
||||
//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 |
||||
} |
||||
|
||||
// fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX
|
||||
// There is no way to create a custom fcntl and to keep //sys fcntl easily,
|
||||
// Therefore, the programmer must call dup2 instead of fcntl in this case.
|
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
//sys FcntlInt(fd uintptr, cmd int, arg int) (r int,err error) = fcntl
|
||||
|
||||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
||||
//sys FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) = fcntl
|
||||
|
||||
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||
|
||||
/* |
||||
* Direct access |
||||
*/ |
||||
|
||||
//sys Acct(path string) (err error)
|
||||
//sys Chdir(path string) (err error)
|
||||
//sys Chroot(path string) (err error)
|
||||
//sys Close(fd int) (err error)
|
||||
//sys Dup(oldfd int) (fd int, err error)
|
||||
//sys Exit(code int)
|
||||
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
|
||||
//sys Fchdir(fd int) (err error)
|
||||
//sys Fchmod(fd int, mode uint32) (err error)
|
||||
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
|
||||
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
|
||||
//sys Fdatasync(fd int) (err error)
|
||||
//sys Fsync(fd int) (err error)
|
||||
// readdir_r
|
||||
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||
|
||||
//sys Getpgrp() (pid int)
|
||||
|
||||
//sysnb Getpid() (pid int)
|
||||
//sysnb Getppid() (ppid int)
|
||||
//sys Getpriority(which int, who int) (prio int, err error)
|
||||
//sysnb Getrusage(who int, rusage *Rusage) (err error)
|
||||
//sysnb Getsid(pid int) (sid int, err error)
|
||||
//sysnb Kill(pid int, sig Signal) (err error)
|
||||
//sys Klogctl(typ int, buf []byte) (n int, err error) = syslog
|
||||
//sys Mkdir(dirfd int, path string, mode uint32) (err error)
|
||||
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
|
||||
//sys Mkfifo(path string, mode uint32) (err error)
|
||||
//sys Mknod(path string, mode uint32, dev int) (err error)
|
||||
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
|
||||
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
|
||||
//sys Open(path string, mode int, perm uint32) (fd int, err error) = open64
|
||||
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
|
||||
//sys read(fd int, p []byte) (n int, err error)
|
||||
//sys Readlink(path string, buf []byte) (n int, err error)
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Setdomainname(p []byte) (err error)
|
||||
//sys Sethostname(p []byte) (err error)
|
||||
//sysnb Setpgid(pid int, pgid int) (err error)
|
||||
//sysnb Setsid() (pid int, err error)
|
||||
//sysnb Settimeofday(tv *Timeval) (err error)
|
||||
|
||||
//sys Setuid(uid int) (err error)
|
||||
//sys Setgid(uid int) (err error)
|
||||
|
||||
//sys Setpriority(which int, who int, prio int) (err error)
|
||||
//sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
|
||||
//sys Sync()
|
||||
//sysnb Times(tms *Tms) (ticks uintptr, err error)
|
||||
//sysnb Umask(mask int) (oldmask int)
|
||||
//sysnb Uname(buf *Utsname) (err error)
|
||||
//TODO umount
|
||||
// //sys Unmount(target string, flags int) (err error) = umount
|
||||
//sys Unlink(path string) (err error)
|
||||
//sys Unlinkat(dirfd int, path string, flags int) (err error)
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys write(fd int, p []byte) (n int, err error)
|
||||
//sys readlen(fd int, p *byte, np int) (n int, err error) = read
|
||||
//sys writelen(fd int, p *byte, np int) (n int, err error) = write
|
||||
|
||||
//sys Dup2(oldfd int, newfd int) (err error)
|
||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64
|
||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error)
|
||||
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat
|
||||
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
|
||||
//sys Ftruncate(fd int, length int64) (err error)
|
||||
//sysnb Getegid() (egid int)
|
||||
//sysnb Geteuid() (euid int)
|
||||
//sysnb Getgid() (gid int)
|
||||
//sysnb Getuid() (uid int)
|
||||
//sys Lchown(path string, uid int, gid int) (err error)
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Lstat(path string, stat *Stat_t) (err error)
|
||||
//sys Pause() (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
|
||||
//TODO Select
|
||||
// //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
|
||||
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setreuid(ruid int, euid 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 Stat(path string, stat *Stat_t) (err error)
|
||||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||
//sys Truncate(path string, length int64) (err error)
|
||||
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
|
||||
//sysnb setgroups(n int, list *_Gid_t) (err error)
|
||||
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
|
||||
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
|
||||
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
|
||||
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
||||
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
|
||||
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||
|
||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||
|
||||
var mapper = &mmapper{ |
||||
active: make(map[*byte][]byte), |
||||
mmap: mmap, |
||||
munmap: munmap, |
||||
} |
||||
|
||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { |
||||
return mapper.Mmap(fd, offset, length, prot, flags) |
||||
} |
||||
|
||||
func Munmap(b []byte) (err error) { |
||||
return mapper.Munmap(b) |
||||
} |
||||
|
||||
//sys Madvise(b []byte, advice int) (err error)
|
||||
//sys Mprotect(b []byte, prot int) (err error)
|
||||
//sys Mlock(b []byte) (err error)
|
||||
//sys Mlockall(flags int) (err error)
|
||||
//sys Msync(b []byte, flags int) (err error)
|
||||
//sys Munlock(b []byte) (err error)
|
||||
//sys Munlockall() (err error)
|
||||
|
||||
//sysnb pipe(p *[2]_C_int) (err error)
|
||||
|
||||
func Pipe(p []int) (err error) { |
||||
if len(p) != 2 { |
||||
return EINVAL |
||||
} |
||||
var pp [2]_C_int |
||||
err = pipe(&pp) |
||||
p[0] = int(pp[0]) |
||||
p[1] = int(pp[1]) |
||||
return |
||||
} |
||||
|
||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) { |
||||
if len(fds) == 0 { |
||||
return poll(nil, 0, timeout) |
||||
} |
||||
return poll(&fds[0], len(fds), timeout) |
||||
} |
||||
|
||||
//sys gettimeofday(tv *Timeval, tzp *Timezone) (err error)
|
||||
//sysnb Time(t *Time_t) (tt Time_t, err error)
|
||||
//sys Utime(path string, buf *Utimbuf) (err error)
|
@ -0,0 +1,34 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc
|
||||
|
||||
package unix |
||||
|
||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = getrlimit64
|
||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) = setrlimit64
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek64
|
||||
|
||||
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec { |
||||
return Timespec{Sec: int32(sec), Nsec: int32(nsec)} |
||||
} |
||||
|
||||
func setTimeval(sec, usec int64) Timeval { |
||||
return Timeval{Sec: int32(sec), Usec: int32(usec)} |
||||
} |
||||
|
||||
func (iov *Iovec) SetLen(length int) { |
||||
iov.Len = uint32(length) |
||||
} |
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) { |
||||
msghdr.Controllen = uint32(length) |
||||
} |
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) { |
||||
cmsg.Len = uint32(length) |
||||
} |
@ -0,0 +1,34 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc64
|
||||
|
||||
package unix |
||||
|
||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek
|
||||
|
||||
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) = mmap64
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec { |
||||
return Timespec{Sec: sec, Nsec: nsec} |
||||
} |
||||
|
||||
func setTimeval(sec, usec int64) Timeval { |
||||
return Timeval{Sec: int64(sec), Usec: int32(usec)} |
||||
} |
||||
|
||||
func (iov *Iovec) SetLen(length int) { |
||||
iov.Len = uint64(length) |
||||
} |
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) { |
||||
msghdr.Controllen = uint32(length) |
||||
} |
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) { |
||||
cmsg.Len = uint32(length) |
||||
} |
@ -0,0 +1,31 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin,go1.12
|
||||
|
||||
package unix |
||||
|
||||
import "unsafe" |
||||
|
||||
// Implemented in the runtime package (runtime/sys_darwin.go)
|
||||
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) |
||||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) |
||||
func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) |
||||
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) // 32-bit only
|
||||
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) |
||||
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) |
||||
|
||||
//go:linkname syscall_syscall syscall.syscall
|
||||
//go:linkname syscall_syscall6 syscall.syscall6
|
||||
//go:linkname syscall_syscall6X syscall.syscall6X
|
||||
//go:linkname syscall_syscall9 syscall.syscall9
|
||||
//go:linkname syscall_rawSyscall syscall.rawSyscall
|
||||
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
|
||||
|
||||
// Find the entry point for f. See comments in runtime/proc.go for the
|
||||
// function of the same name.
|
||||
//go:nosplit
|
||||
func funcPC(f func()) uintptr { |
||||
return **(**uintptr)(unsafe.Pointer(&f)) |
||||
} |
@ -0,0 +1,52 @@ |
||||
// 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 arm64,freebsd
|
||||
|
||||
package unix |
||||
|
||||
import ( |
||||
"syscall" |
||||
"unsafe" |
||||
) |
||||
|
||||
func setTimespec(sec, nsec int64) Timespec { |
||||
return Timespec{Sec: sec, Nsec: nsec} |
||||
} |
||||
|
||||
func setTimeval(sec, usec int64) Timeval { |
||||
return Timeval{Sec: sec, Usec: usec} |
||||
} |
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) { |
||||
k.Ident = uint64(fd) |
||||
k.Filter = int16(mode) |
||||
k.Flags = uint16(flags) |
||||
} |
||||
|
||||
func (iov *Iovec) SetLen(length int) { |
||||
iov.Len = uint64(length) |
||||
} |
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) { |
||||
msghdr.Controllen = uint32(length) |
||||
} |
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) { |
||||
cmsg.Len = uint32(length) |
||||
} |
||||
|
||||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
||||
var writtenOut uint64 = 0 |
||||
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) |
||||
|
||||
written = int(writtenOut) |
||||
|
||||
if e1 != 0 { |
||||
err = e1 |
||||
} |
||||
return |
||||
} |
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) |
@ -0,0 +1,14 @@ |
||||
// 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) |
@ -0,0 +1,16 @@ |
||||
// 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) |
@ -0,0 +1,30 @@ |
||||
// 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 |
||||
} |
@ -0,0 +1,20 @@ |
||||
// 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 |
||||
} |
@ -0,0 +1,213 @@ |
||||
// 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 riscv64,linux
|
||||
|
||||
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 Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||
//sys Fchown(fd int, uid int, gid int) (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, buf *Statfs_t) (err error)
|
||||
//sys Ftruncate(fd int, length int64) (err error)
|
||||
//sysnb Getegid() (egid int)
|
||||
//sysnb Geteuid() (euid int)
|
||||
//sysnb Getgid() (gid int)
|
||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||
//sysnb Getuid() (uid int)
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
|
||||
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { |
||||
var ts *Timespec |
||||
if timeout != nil { |
||||
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} |
||||
} |
||||
return Pselect(nfd, r, w, e, ts, nil) |
||||
} |
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
//sys Setfsgid(gid int) (err error)
|
||||
//sys Setfsuid(uid int) (err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
||||
//sys Shutdown(fd int, how int) (err error)
|
||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||
|
||||
func Stat(path string, stat *Stat_t) (err error) { |
||||
return Fstatat(AT_FDCWD, path, stat, 0) |
||||
} |
||||
|
||||
func Lchown(path string, uid int, gid int) (err error) { |
||||
return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW) |
||||
} |
||||
|
||||
func Lstat(path string, stat *Stat_t) (err error) { |
||||
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW) |
||||
} |
||||
|
||||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||
//sys Truncate(path string, length int64) (err error)
|
||||
|
||||
func Ustat(dev int, ubuf *Ustat_t) (err error) { |
||||
return ENOSYS |
||||
} |
||||
|
||||
//sys 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 bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
|
||||
//sysnb setgroups(n int, list *_Gid_t) (err error)
|
||||
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
|
||||
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
|
||||
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
|
||||
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
||||
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
|
||||
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
|
||||
|
||||
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec { |
||||
return Timespec{Sec: sec, Nsec: nsec} |
||||
} |
||||
|
||||
func setTimeval(sec, usec int64) Timeval { |
||||
return Timeval{Sec: sec, Usec: usec} |
||||
} |
||||
|
||||
func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) { |
||||
if tv == nil { |
||||
return utimensat(dirfd, path, nil, 0) |
||||
} |
||||
|
||||
ts := []Timespec{ |
||||
NsecToTimespec(TimevalToNsec(tv[0])), |
||||
NsecToTimespec(TimevalToNsec(tv[1])), |
||||
} |
||||
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) |
||||
} |
||||
|
||||
func Time(t *Time_t) (Time_t, error) { |
||||
var tv Timeval |
||||
err := Gettimeofday(&tv) |
||||
if err != nil { |
||||
return 0, err |
||||
} |
||||
if t != nil { |
||||
*t = Time_t(tv.Sec) |
||||
} |
||||
return Time_t(tv.Sec), nil |
||||
} |
||||
|
||||
func Utime(path string, buf *Utimbuf) error { |
||||
tv := []Timeval{ |
||||
{Sec: buf.Actime}, |
||||
{Sec: buf.Modtime}, |
||||
} |
||||
return Utimes(path, tv) |
||||
} |
||||
|
||||
func utimes(path string, tv *[2]Timeval) (err error) { |
||||
if tv == nil { |
||||
return utimensat(AT_FDCWD, path, nil, 0) |
||||
} |
||||
|
||||
ts := []Timespec{ |
||||
NsecToTimespec(TimevalToNsec(tv[0])), |
||||
NsecToTimespec(TimevalToNsec(tv[1])), |
||||
} |
||||
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) |
||||
} |
||||
|
||||
func Pipe(p []int) (err error) { |
||||
if len(p) != 2 { |
||||
return EINVAL |
||||
} |
||||
var pp [2]_C_int |
||||
err = pipe2(&pp, 0) |
||||
p[0] = int(pp[0]) |
||||
p[1] = int(pp[1]) |
||||
return |
||||
} |
||||
|
||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
||||
|
||||
func Pipe2(p []int, flags int) (err error) { |
||||
if len(p) != 2 { |
||||
return EINVAL |
||||
} |
||||
var pp [2]_C_int |
||||
err = pipe2(&pp, flags) |
||||
p[0] = int(pp[0]) |
||||
p[1] = int(pp[1]) |
||||
return |
||||
} |
||||
|
||||
func (r *PtraceRegs) PC() uint64 { return r.Pc } |
||||
|
||||
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } |
||||
|
||||
func (iov *Iovec) SetLen(length int) { |
||||
iov.Len = uint64(length) |
||||
} |
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) { |
||||
msghdr.Controllen = uint64(length) |
||||
} |
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) { |
||||
cmsg.Len = uint64(length) |
||||
} |
||||
|
||||
func InotifyInit() (fd int, err error) { |
||||
return InotifyInit1(0) |
||||
} |
||||
|
||||
func Dup2(oldfd int, newfd int) (err error) { |
||||
return Dup3(oldfd, newfd, 0) |
||||
} |
||||
|
||||
func Pause() error { |
||||
_, err := ppoll(nil, 0, nil, nil) |
||||
return err |
||||
} |
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) { |
||||
var ts *Timespec |
||||
if timeout >= 0 { |
||||
ts = new(Timespec) |
||||
*ts = NsecToTimespec(int64(timeout) * 1e6) |
||||
} |
||||
if len(fds) == 0 { |
||||
return ppoll(nil, 0, ts, nil) |
||||
} |
||||
return ppoll(&fds[0], len(fds), ts, nil) |
||||
} |
||||
|
||||
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { |
||||
return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0) |
||||
} |
@ -0,0 +1,33 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build arm64,netbsd
|
||||
|
||||
package unix |
||||
|
||||
func setTimespec(sec, nsec int64) Timespec { |
||||
return Timespec{Sec: sec, Nsec: nsec} |
||||
} |
||||
|
||||
func setTimeval(sec, usec int64) Timeval { |
||||
return Timeval{Sec: sec, Usec: int32(usec)} |
||||
} |
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) { |
||||
k.Ident = uint64(fd) |
||||
k.Filter = uint32(mode) |
||||
k.Flags = uint32(flags) |
||||
} |
||||
|
||||
func (iov *Iovec) SetLen(length int) { |
||||
iov.Len = uint64(length) |
||||
} |
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) { |
||||
msghdr.Controllen = uint32(length) |
||||
} |
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) { |
||||
cmsg.Len = uint32(length) |
||||
} |
@ -1,11 +0,0 @@ |
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly freebsd netbsd openbsd
|
||||
|
||||
package unix |
||||
|
||||
const ImplementsGetwd = false |
||||
|
||||
func Getwd() (string, error) { return "", ENOTSUP } |
@ -0,0 +1,24 @@ |
||||
// 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
|
||||
// +build ppc64le ppc64
|
||||
// +build !gccgo
|
||||
|
||||
package unix |
||||
|
||||
import "syscall" |
||||
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { |
||||
return syscall.Syscall(trap, a1, a2, a3) |
||||
} |
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) { |
||||
return syscall.Syscall6(trap, a1, a2, a3, a4, a5, a6) |
||||
} |
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { |
||||
return syscall.RawSyscall(trap, a1, a2, a3) |
||||
} |
||||
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) { |
||||
return syscall.RawSyscall6(trap, a1, a2, a3, a4, a5, a6) |
||||
} |
@ -0,0 +1,240 @@ |
||||
// 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 freebsd netbsd
|
||||
|
||||
package unix |
||||
|
||||
import ( |
||||
"strings" |
||||
"unsafe" |
||||
) |
||||
|
||||
// Derive extattr namespace and attribute name
|
||||
|
||||
func xattrnamespace(fullattr string) (ns int, attr string, err error) { |
||||
s := strings.IndexByte(fullattr, '.') |
||||
if s == -1 { |
||||
return -1, "", ENOATTR |
||||
} |
||||
|
||||
namespace := fullattr[0:s] |
||||
attr = fullattr[s+1:] |
||||
|
||||
switch namespace { |
||||
case "user": |
||||
return EXTATTR_NAMESPACE_USER, attr, nil |
||||
case "system": |
||||
return EXTATTR_NAMESPACE_SYSTEM, attr, nil |
||||
default: |
||||
return -1, "", ENOATTR |
||||
} |
||||
} |
||||
|
||||
func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) { |
||||
if len(dest) > idx { |
||||
return unsafe.Pointer(&dest[idx]) |
||||
} else { |
||||
return unsafe.Pointer(_zero) |
||||
} |
||||
} |
||||
|
||||
// FreeBSD and NetBSD implement their own syscalls to handle extended attributes
|
||||
|
||||
func Getxattr(file string, attr string, dest []byte) (sz int, err error) { |
||||
d := initxattrdest(dest, 0) |
||||
destsize := len(dest) |
||||
|
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return -1, err |
||||
} |
||||
|
||||
return ExtattrGetFile(file, nsid, a, uintptr(d), destsize) |
||||
} |
||||
|
||||
func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { |
||||
d := initxattrdest(dest, 0) |
||||
destsize := len(dest) |
||||
|
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return -1, err |
||||
} |
||||
|
||||
return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize) |
||||
} |
||||
|
||||
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) { |
||||
d := initxattrdest(dest, 0) |
||||
destsize := len(dest) |
||||
|
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return -1, err |
||||
} |
||||
|
||||
return ExtattrGetLink(link, nsid, a, uintptr(d), destsize) |
||||
} |
||||
|
||||
// flags are unused on FreeBSD
|
||||
|
||||
func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) { |
||||
var d unsafe.Pointer |
||||
if len(data) > 0 { |
||||
d = unsafe.Pointer(&data[0]) |
||||
} |
||||
datasiz := len(data) |
||||
|
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return |
||||
} |
||||
|
||||
_, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz) |
||||
return |
||||
} |
||||
|
||||
func Setxattr(file string, attr string, data []byte, flags int) (err error) { |
||||
var d unsafe.Pointer |
||||
if len(data) > 0 { |
||||
d = unsafe.Pointer(&data[0]) |
||||
} |
||||
datasiz := len(data) |
||||
|
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return |
||||
} |
||||
|
||||
_, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz) |
||||
return |
||||
} |
||||
|
||||
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) { |
||||
var d unsafe.Pointer |
||||
if len(data) > 0 { |
||||
d = unsafe.Pointer(&data[0]) |
||||
} |
||||
datasiz := len(data) |
||||
|
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return |
||||
} |
||||
|
||||
_, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz) |
||||
return |
||||
} |
||||
|
||||
func Removexattr(file string, attr string) (err error) { |
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return |
||||
} |
||||
|
||||
err = ExtattrDeleteFile(file, nsid, a) |
||||
return |
||||
} |
||||
|
||||
func Fremovexattr(fd int, attr string) (err error) { |
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return |
||||
} |
||||
|
||||
err = ExtattrDeleteFd(fd, nsid, a) |
||||
return |
||||
} |
||||
|
||||
func Lremovexattr(link string, attr string) (err error) { |
||||
nsid, a, err := xattrnamespace(attr) |
||||
if err != nil { |
||||
return |
||||
} |
||||
|
||||
err = ExtattrDeleteLink(link, nsid, a) |
||||
return |
||||
} |
||||
|
||||
func Listxattr(file string, dest []byte) (sz int, err error) { |
||||
d := initxattrdest(dest, 0) |
||||
destsiz := len(dest) |
||||
|
||||
// FreeBSD won't allow you to list xattrs from multiple namespaces
|
||||
s := 0 |
||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
||||
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) |
||||
|
||||
/* Errors accessing system attrs are ignored so that |
||||
* we can implement the Linux-like behavior of omitting errors that |
||||
* we don't have read permissions on |
||||
* |
||||
* Linux will still error if we ask for user attributes on a file that |
||||
* we don't have read permissions on, so don't ignore those errors |
||||
*/ |
||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
||||
continue |
||||
} else if e != nil { |
||||
return s, e |
||||
} |
||||
|
||||
s += stmp |
||||
destsiz -= s |
||||
if destsiz < 0 { |
||||
destsiz = 0 |
||||
} |
||||
d = initxattrdest(dest, s) |
||||
} |
||||
|
||||
return s, nil |
||||
} |
||||
|
||||
func Flistxattr(fd int, dest []byte) (sz int, err error) { |
||||
d := initxattrdest(dest, 0) |
||||
destsiz := len(dest) |
||||
|
||||
s := 0 |
||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
||||
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) |
||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
||||
continue |
||||
} else if e != nil { |
||||
return s, e |
||||
} |
||||
|
||||
s += stmp |
||||
destsiz -= s |
||||
if destsiz < 0 { |
||||
destsiz = 0 |
||||
} |
||||
d = initxattrdest(dest, s) |
||||
} |
||||
|
||||
return s, nil |
||||
} |
||||
|
||||
func Llistxattr(link string, dest []byte) (sz int, err error) { |
||||
d := initxattrdest(dest, 0) |
||||
destsiz := len(dest) |
||||
|
||||
s := 0 |
||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { |
||||
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) |
||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { |
||||
continue |
||||
} else if e != nil { |
||||
return s, e |
||||
} |
||||
|
||||
s += stmp |
||||
destsiz -= s |
||||
if destsiz < 0 { |
||||
destsiz = 0 |
||||
} |
||||
d = initxattrdest(dest, s) |
||||
} |
||||
|
||||
return s, nil |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue