| @@ -776,7 +776,8 @@ | |||||
| revision = "5a06fca2c336a4b2b2fcb45702e8c47621b2aa2c" | revision = "5a06fca2c336a4b2b2fcb45702e8c47621b2aa2c" | ||||
| [[projects]] | [[projects]] | ||||
| digest = "1:47495898c42062ace16d8046915b088e7c3846e77b997ec5a8a00ec552e179d5" | |||||
| branch = "master" | |||||
| digest = "1:030ca7763285f6cdec5684d7417faa2810d10a508b0220b1487cc876b5c00c35" | |||||
| name = "golang.org/x/sys" | name = "golang.org/x/sys" | ||||
| packages = [ | packages = [ | ||||
| "unix", | "unix", | ||||
| @@ -784,7 +785,7 @@ | |||||
| "windows/svc", | "windows/svc", | ||||
| ] | ] | ||||
| pruneopts = "NUT" | pruneopts = "NUT" | ||||
| revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8" | |||||
| revision = "2772b66316d2c587efeb188dcd5ebc6987656e84" | |||||
| [[projects]] | [[projects]] | ||||
| digest = "1:d2463fd72ee2636c3d9bbdb98fa4996a118f210ae3e5eaf62d281855bc0b4a83" | digest = "1:d2463fd72ee2636c3d9bbdb98fa4996a118f210ae3e5eaf62d281855bc0b4a83" | ||||
| @@ -19,7 +19,7 @@ ignored = ["google.golang.org/appengine*"] | |||||
| name = "golang.org/x/crypto" | name = "golang.org/x/crypto" | ||||
| [[constraint]] | [[constraint]] | ||||
| revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8" | |||||
| branch = "master" | |||||
| name = "golang.org/x/sys" | name = "golang.org/x/sys" | ||||
| [[constraint]] | [[constraint]] | ||||
| @@ -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 | |||||
| @@ -1,10 +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 !gccgo | |||||
| #include "textflag.h" | |||||
| TEXT ·use(SB),NOSPLIT,$0 | |||||
| RET | |||||
| @@ -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) | |||||
| @@ -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 @@ | |||||
| // 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 @@ | |||||
| // 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 @@ | |||||
| // 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 @@ | |||||
| // 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 @@ | |||||
| // 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 | |||||
| @@ -0,0 +1,54 @@ | |||||
| // Copyright 2016 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build linux | |||||
| // +build mips mipsle | |||||
| // +build !gccgo | |||||
| #include "textflag.h" | |||||
| // | |||||
| // System calls for mips, Linux | |||||
| // | |||||
| // Just jump to package syscall's implementation for all these functions. | |||||
| // The runtime may know about them. | |||||
| TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||||
| JMP syscall·Syscall(SB) | |||||
| TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||||
| JMP syscall·Syscall6(SB) | |||||
| TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||||
| JMP syscall·Syscall9(SB) | |||||
| 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) | |||||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||||
| 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 @@ | |||||
| // 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 | |||||
| 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 | |||||
| @@ -0,0 +1,29 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build !gccgo | |||||
| #include "textflag.h" | |||||
| // | |||||
| // System call support for ARM, OpenBSD | |||||
| // | |||||
| // Just jump to package syscall's implementation for all these functions. | |||||
| // The runtime may know about them. | |||||
| TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||||
| B syscall·Syscall(SB) | |||||
| TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||||
| B syscall·Syscall6(SB) | |||||
| TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||||
| B syscall·Syscall9(SB) | |||||
| TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||||
| B syscall·RawSyscall(SB) | |||||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||||
| B syscall·RawSyscall6(SB) | |||||
| @@ -10,8 +10,8 @@ | |||||
| // System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go | // System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go | ||||
| // | // | ||||
| TEXT ·sysvicall6(SB),NOSPLIT,$0-64 | |||||
| TEXT ·sysvicall6(SB),NOSPLIT,$0-88 | |||||
| JMP syscall·sysvicall6(SB) | JMP syscall·sysvicall6(SB) | ||||
| TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64 | |||||
| TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88 | |||||
| JMP syscall·rawSysvicall6(SB) | JMP syscall·rawSysvicall6(SB) | ||||
| @@ -0,0 +1,195 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build freebsd | |||||
| package unix | |||||
| import ( | |||||
| "errors" | |||||
| "fmt" | |||||
| ) | |||||
| // Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c | |||||
| const ( | |||||
| // This is the version of CapRights this package understands. See C implementation for parallels. | |||||
| capRightsGoVersion = CAP_RIGHTS_VERSION_00 | |||||
| capArSizeMin = CAP_RIGHTS_VERSION_00 + 2 | |||||
| capArSizeMax = capRightsGoVersion + 2 | |||||
| ) | |||||
| var ( | |||||
| bit2idx = []int{ | |||||
| -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, | |||||
| 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |||||
| } | |||||
| ) | |||||
| func capidxbit(right uint64) int { | |||||
| return int((right >> 57) & 0x1f) | |||||
| } | |||||
| func rightToIndex(right uint64) (int, error) { | |||||
| idx := capidxbit(right) | |||||
| if idx < 0 || idx >= len(bit2idx) { | |||||
| return -2, fmt.Errorf("index for right 0x%x out of range", right) | |||||
| } | |||||
| return bit2idx[idx], nil | |||||
| } | |||||
| func caprver(right uint64) int { | |||||
| return int(right >> 62) | |||||
| } | |||||
| func capver(rights *CapRights) int { | |||||
| return caprver(rights.Rights[0]) | |||||
| } | |||||
| func caparsize(rights *CapRights) int { | |||||
| return capver(rights) + 2 | |||||
| } | |||||
| // CapRightsSet sets the permissions in setrights in rights. | |||||
| func CapRightsSet(rights *CapRights, setrights []uint64) error { | |||||
| // This is essentially a copy of cap_rights_vset() | |||||
| if capver(rights) != CAP_RIGHTS_VERSION_00 { | |||||
| return fmt.Errorf("bad rights version %d", capver(rights)) | |||||
| } | |||||
| n := caparsize(rights) | |||||
| if n < capArSizeMin || n > capArSizeMax { | |||||
| return errors.New("bad rights size") | |||||
| } | |||||
| for _, right := range setrights { | |||||
| if caprver(right) != CAP_RIGHTS_VERSION_00 { | |||||
| return errors.New("bad right version") | |||||
| } | |||||
| i, err := rightToIndex(right) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| if i >= n { | |||||
| return errors.New("index overflow") | |||||
| } | |||||
| if capidxbit(rights.Rights[i]) != capidxbit(right) { | |||||
| return errors.New("index mismatch") | |||||
| } | |||||
| rights.Rights[i] |= right | |||||
| if capidxbit(rights.Rights[i]) != capidxbit(right) { | |||||
| return errors.New("index mismatch (after assign)") | |||||
| } | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // CapRightsClear clears the permissions in clearrights from rights. | |||||
| func CapRightsClear(rights *CapRights, clearrights []uint64) error { | |||||
| // This is essentially a copy of cap_rights_vclear() | |||||
| if capver(rights) != CAP_RIGHTS_VERSION_00 { | |||||
| return fmt.Errorf("bad rights version %d", capver(rights)) | |||||
| } | |||||
| n := caparsize(rights) | |||||
| if n < capArSizeMin || n > capArSizeMax { | |||||
| return errors.New("bad rights size") | |||||
| } | |||||
| for _, right := range clearrights { | |||||
| if caprver(right) != CAP_RIGHTS_VERSION_00 { | |||||
| return errors.New("bad right version") | |||||
| } | |||||
| i, err := rightToIndex(right) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| if i >= n { | |||||
| return errors.New("index overflow") | |||||
| } | |||||
| if capidxbit(rights.Rights[i]) != capidxbit(right) { | |||||
| return errors.New("index mismatch") | |||||
| } | |||||
| rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF) | |||||
| if capidxbit(rights.Rights[i]) != capidxbit(right) { | |||||
| return errors.New("index mismatch (after assign)") | |||||
| } | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // CapRightsIsSet checks whether all the permissions in setrights are present in rights. | |||||
| func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) { | |||||
| // This is essentially a copy of cap_rights_is_vset() | |||||
| if capver(rights) != CAP_RIGHTS_VERSION_00 { | |||||
| return false, fmt.Errorf("bad rights version %d", capver(rights)) | |||||
| } | |||||
| n := caparsize(rights) | |||||
| if n < capArSizeMin || n > capArSizeMax { | |||||
| return false, errors.New("bad rights size") | |||||
| } | |||||
| for _, right := range setrights { | |||||
| if caprver(right) != CAP_RIGHTS_VERSION_00 { | |||||
| return false, errors.New("bad right version") | |||||
| } | |||||
| i, err := rightToIndex(right) | |||||
| if err != nil { | |||||
| return false, err | |||||
| } | |||||
| if i >= n { | |||||
| return false, errors.New("index overflow") | |||||
| } | |||||
| if capidxbit(rights.Rights[i]) != capidxbit(right) { | |||||
| return false, errors.New("index mismatch") | |||||
| } | |||||
| if (rights.Rights[i] & right) != right { | |||||
| return false, nil | |||||
| } | |||||
| } | |||||
| return true, nil | |||||
| } | |||||
| func capright(idx uint64, bit uint64) uint64 { | |||||
| return ((1 << (57 + idx)) | bit) | |||||
| } | |||||
| // CapRightsInit returns a pointer to an initialised CapRights structure filled with rights. | |||||
| // See man cap_rights_init(3) and rights(4). | |||||
| func CapRightsInit(rights []uint64) (*CapRights, error) { | |||||
| var r CapRights | |||||
| r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0) | |||||
| r.Rights[1] = capright(1, 0) | |||||
| err := CapRightsSet(&r, rights) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| return &r, nil | |||||
| } | |||||
| // CapRightsLimit reduces the operations permitted on fd to at most those contained in rights. | |||||
| // The capability rights on fd can never be increased by CapRightsLimit. | |||||
| // See man cap_rights_limit(2) and rights(4). | |||||
| func CapRightsLimit(fd uintptr, rights *CapRights) error { | |||||
| return capRightsLimit(int(fd), rights) | |||||
| } | |||||
| // CapRightsGet returns a CapRights structure containing the operations permitted on fd. | |||||
| // See man cap_rights_get(3) and rights(4). | |||||
| func CapRightsGet(fd uintptr) (*CapRights, error) { | |||||
| r, err := CapRightsInit(nil) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| err = capRightsGet(capRightsGoVersion, int(fd), r) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| return r, nil | |||||
| } | |||||
| @@ -2,7 +2,7 @@ | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| package unix | package unix | ||||
| @@ -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) | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| // 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. | |||||
| // Functions to access/create device major and minor numbers matching the | |||||
| // encoding used in Darwin's sys/types.h header. | |||||
| package unix | |||||
| // Major returns the major component of a Darwin device number. | |||||
| func Major(dev uint64) uint32 { | |||||
| return uint32((dev >> 24) & 0xff) | |||||
| } | |||||
| // Minor returns the minor component of a Darwin device number. | |||||
| func Minor(dev uint64) uint32 { | |||||
| return uint32(dev & 0xffffff) | |||||
| } | |||||
| // Mkdev returns a Darwin device number generated from the given major and minor | |||||
| // components. | |||||
| func Mkdev(major, minor uint32) uint64 { | |||||
| return (uint64(major) << 24) | uint64(minor) | |||||
| } | |||||
| @@ -0,0 +1,30 @@ | |||||
| // 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. | |||||
| // Functions to access/create device major and minor numbers matching the | |||||
| // encoding used in Dragonfly's sys/types.h header. | |||||
| // | |||||
| // The information below is extracted and adapted from sys/types.h: | |||||
| // | |||||
| // Minor gives a cookie instead of an index since in order to avoid changing the | |||||
| // meanings of bits 0-15 or wasting time and space shifting bits 16-31 for | |||||
| // devices that don't use them. | |||||
| package unix | |||||
| // Major returns the major component of a DragonFlyBSD device number. | |||||
| func Major(dev uint64) uint32 { | |||||
| return uint32((dev >> 8) & 0xff) | |||||
| } | |||||
| // Minor returns the minor component of a DragonFlyBSD device number. | |||||
| func Minor(dev uint64) uint32 { | |||||
| return uint32(dev & 0xffff00ff) | |||||
| } | |||||
| // Mkdev returns a DragonFlyBSD device number generated from the given major and | |||||
| // minor components. | |||||
| func Mkdev(major, minor uint32) uint64 { | |||||
| return (uint64(major) << 8) | uint64(minor) | |||||
| } | |||||
| @@ -0,0 +1,30 @@ | |||||
| // 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. | |||||
| // Functions to access/create device major and minor numbers matching the | |||||
| // encoding used in FreeBSD's sys/types.h header. | |||||
| // | |||||
| // The information below is extracted and adapted from sys/types.h: | |||||
| // | |||||
| // Minor gives a cookie instead of an index since in order to avoid changing the | |||||
| // meanings of bits 0-15 or wasting time and space shifting bits 16-31 for | |||||
| // devices that don't use them. | |||||
| package unix | |||||
| // Major returns the major component of a FreeBSD device number. | |||||
| func Major(dev uint64) uint32 { | |||||
| return uint32((dev >> 8) & 0xff) | |||||
| } | |||||
| // Minor returns the minor component of a FreeBSD device number. | |||||
| func Minor(dev uint64) uint32 { | |||||
| return uint32(dev & 0xffff00ff) | |||||
| } | |||||
| // Mkdev returns a FreeBSD device number generated from the given major and | |||||
| // minor components. | |||||
| func Mkdev(major, minor uint32) uint64 { | |||||
| return (uint64(major) << 8) | uint64(minor) | |||||
| } | |||||
| @@ -0,0 +1,42 @@ | |||||
| // 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. | |||||
| // Functions to access/create device major and minor numbers matching the | |||||
| // encoding used by the Linux kernel and glibc. | |||||
| // | |||||
| // The information below is extracted and adapted from bits/sysmacros.h in the | |||||
| // glibc sources: | |||||
| // | |||||
| // dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's | |||||
| // default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major | |||||
| // number and m is a hex digit of the minor number. This is backward compatible | |||||
| // with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also | |||||
| // backward compatible with the Linux kernel, which for some architectures uses | |||||
| // 32-bit dev_t, encoded as mmmM MMmm. | |||||
| package unix | |||||
| // Major returns the major component of a Linux device number. | |||||
| func Major(dev uint64) uint32 { | |||||
| major := uint32((dev & 0x00000000000fff00) >> 8) | |||||
| major |= uint32((dev & 0xfffff00000000000) >> 32) | |||||
| return major | |||||
| } | |||||
| // Minor returns the minor component of a Linux device number. | |||||
| func Minor(dev uint64) uint32 { | |||||
| minor := uint32((dev & 0x00000000000000ff) >> 0) | |||||
| minor |= uint32((dev & 0x00000ffffff00000) >> 12) | |||||
| return minor | |||||
| } | |||||
| // Mkdev returns a Linux device number generated from the given major and minor | |||||
| // components. | |||||
| func Mkdev(major, minor uint32) uint64 { | |||||
| dev := (uint64(major) & 0x00000fff) << 8 | |||||
| dev |= (uint64(major) & 0xfffff000) << 32 | |||||
| dev |= (uint64(minor) & 0x000000ff) << 0 | |||||
| dev |= (uint64(minor) & 0xffffff00) << 12 | |||||
| return dev | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| // 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. | |||||
| // Functions to access/create device major and minor numbers matching the | |||||
| // encoding used in NetBSD's sys/types.h header. | |||||
| package unix | |||||
| // Major returns the major component of a NetBSD device number. | |||||
| func Major(dev uint64) uint32 { | |||||
| return uint32((dev & 0x000fff00) >> 8) | |||||
| } | |||||
| // Minor returns the minor component of a NetBSD device number. | |||||
| func Minor(dev uint64) uint32 { | |||||
| minor := uint32((dev & 0x000000ff) >> 0) | |||||
| minor |= uint32((dev & 0xfff00000) >> 12) | |||||
| return minor | |||||
| } | |||||
| // Mkdev returns a NetBSD device number generated from the given major and minor | |||||
| // components. | |||||
| func Mkdev(major, minor uint32) uint64 { | |||||
| dev := (uint64(major) << 8) & 0x000fff00 | |||||
| dev |= (uint64(minor) << 12) & 0xfff00000 | |||||
| dev |= (uint64(minor) << 0) & 0x000000ff | |||||
| return dev | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| // 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. | |||||
| // Functions to access/create device major and minor numbers matching the | |||||
| // encoding used in OpenBSD's sys/types.h header. | |||||
| package unix | |||||
| // Major returns the major component of an OpenBSD device number. | |||||
| func Major(dev uint64) uint32 { | |||||
| return uint32((dev & 0x0000ff00) >> 8) | |||||
| } | |||||
| // Minor returns the minor component of an OpenBSD device number. | |||||
| func Minor(dev uint64) uint32 { | |||||
| minor := uint32((dev & 0x000000ff) >> 0) | |||||
| minor |= uint32((dev & 0xffff0000) >> 8) | |||||
| return minor | |||||
| } | |||||
| // Mkdev returns an OpenBSD device number generated from the given major and minor | |||||
| // components. | |||||
| func Mkdev(major, minor uint32) uint64 { | |||||
| dev := (uint64(major) << 8) & 0x0000ff00 | |||||
| dev |= (uint64(minor) << 8) & 0xffff0000 | |||||
| dev |= (uint64(minor) << 0) & 0x000000ff | |||||
| return dev | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| // Copyright 2009 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris | |||||
| package unix | |||||
| import "syscall" | |||||
| // ParseDirent parses up to max directory entries in buf, | |||||
| // appending the names to names. It returns the number of | |||||
| // bytes consumed from buf, the number of entries added | |||||
| // to names, and the new names slice. | |||||
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||||
| return syscall.ParseDirent(buf, max, names) | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| // Copyright 2016 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // | |||||
| // +build ppc64 s390x mips mips64 | |||||
| package unix | |||||
| const isBigEndian = true | |||||
| @@ -0,0 +1,9 @@ | |||||
| // Copyright 2016 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // | |||||
| // +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le | |||||
| package unix | |||||
| const isBigEndian = false | |||||
| @@ -1,8 +1,8 @@ | |||||
| // Copyright 2010 The Go Authors. All rights reserved. | |||||
| // Copyright 2010 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // Unix environment variables. | // Unix environment variables. | ||||
| @@ -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) | |||||
| } | |||||
| @@ -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,227 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // Constants that were deprecated or moved to enums in the FreeBSD headers. Keep | |||||
| // them here for backwards compatibility. | |||||
| package unix | |||||
| const ( | |||||
| IFF_SMART = 0x20 | |||||
| IFT_1822 = 0x2 | |||||
| IFT_A12MPPSWITCH = 0x82 | |||||
| IFT_AAL2 = 0xbb | |||||
| IFT_AAL5 = 0x31 | |||||
| IFT_ADSL = 0x5e | |||||
| IFT_AFLANE8023 = 0x3b | |||||
| IFT_AFLANE8025 = 0x3c | |||||
| IFT_ARAP = 0x58 | |||||
| IFT_ARCNET = 0x23 | |||||
| IFT_ARCNETPLUS = 0x24 | |||||
| IFT_ASYNC = 0x54 | |||||
| IFT_ATM = 0x25 | |||||
| IFT_ATMDXI = 0x69 | |||||
| IFT_ATMFUNI = 0x6a | |||||
| IFT_ATMIMA = 0x6b | |||||
| IFT_ATMLOGICAL = 0x50 | |||||
| IFT_ATMRADIO = 0xbd | |||||
| IFT_ATMSUBINTERFACE = 0x86 | |||||
| IFT_ATMVCIENDPT = 0xc2 | |||||
| IFT_ATMVIRTUAL = 0x95 | |||||
| IFT_BGPPOLICYACCOUNTING = 0xa2 | |||||
| IFT_BSC = 0x53 | |||||
| IFT_CCTEMUL = 0x3d | |||||
| IFT_CEPT = 0x13 | |||||
| IFT_CES = 0x85 | |||||
| IFT_CHANNEL = 0x46 | |||||
| IFT_CNR = 0x55 | |||||
| IFT_COFFEE = 0x84 | |||||
| IFT_COMPOSITELINK = 0x9b | |||||
| IFT_DCN = 0x8d | |||||
| IFT_DIGITALPOWERLINE = 0x8a | |||||
| IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||||
| IFT_DLSW = 0x4a | |||||
| IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||||
| IFT_DOCSCABLEMACLAYER = 0x7f | |||||
| IFT_DOCSCABLEUPSTREAM = 0x81 | |||||
| IFT_DS0 = 0x51 | |||||
| IFT_DS0BUNDLE = 0x52 | |||||
| IFT_DS1FDL = 0xaa | |||||
| IFT_DS3 = 0x1e | |||||
| IFT_DTM = 0x8c | |||||
| IFT_DVBASILN = 0xac | |||||
| IFT_DVBASIOUT = 0xad | |||||
| IFT_DVBRCCDOWNSTREAM = 0x93 | |||||
| IFT_DVBRCCMACLAYER = 0x92 | |||||
| IFT_DVBRCCUPSTREAM = 0x94 | |||||
| IFT_ENC = 0xf4 | |||||
| IFT_EON = 0x19 | |||||
| IFT_EPLRS = 0x57 | |||||
| IFT_ESCON = 0x49 | |||||
| IFT_ETHER = 0x6 | |||||
| IFT_FAITH = 0xf2 | |||||
| IFT_FAST = 0x7d | |||||
| IFT_FASTETHER = 0x3e | |||||
| IFT_FASTETHERFX = 0x45 | |||||
| IFT_FDDI = 0xf | |||||
| IFT_FIBRECHANNEL = 0x38 | |||||
| IFT_FRAMERELAYINTERCONNECT = 0x3a | |||||
| IFT_FRAMERELAYMPI = 0x5c | |||||
| IFT_FRDLCIENDPT = 0xc1 | |||||
| IFT_FRELAY = 0x20 | |||||
| IFT_FRELAYDCE = 0x2c | |||||
| IFT_FRF16MFRBUNDLE = 0xa3 | |||||
| IFT_FRFORWARD = 0x9e | |||||
| IFT_G703AT2MB = 0x43 | |||||
| IFT_G703AT64K = 0x42 | |||||
| IFT_GIF = 0xf0 | |||||
| IFT_GIGABITETHERNET = 0x75 | |||||
| IFT_GR303IDT = 0xb2 | |||||
| IFT_GR303RDT = 0xb1 | |||||
| IFT_H323GATEKEEPER = 0xa4 | |||||
| IFT_H323PROXY = 0xa5 | |||||
| IFT_HDH1822 = 0x3 | |||||
| IFT_HDLC = 0x76 | |||||
| IFT_HDSL2 = 0xa8 | |||||
| IFT_HIPERLAN2 = 0xb7 | |||||
| IFT_HIPPI = 0x2f | |||||
| IFT_HIPPIINTERFACE = 0x39 | |||||
| IFT_HOSTPAD = 0x5a | |||||
| IFT_HSSI = 0x2e | |||||
| IFT_HY = 0xe | |||||
| IFT_IBM370PARCHAN = 0x48 | |||||
| IFT_IDSL = 0x9a | |||||
| IFT_IEEE80211 = 0x47 | |||||
| IFT_IEEE80212 = 0x37 | |||||
| IFT_IEEE8023ADLAG = 0xa1 | |||||
| IFT_IFGSN = 0x91 | |||||
| IFT_IMT = 0xbe | |||||
| IFT_INTERLEAVE = 0x7c | |||||
| IFT_IP = 0x7e | |||||
| IFT_IPFORWARD = 0x8e | |||||
| IFT_IPOVERATM = 0x72 | |||||
| IFT_IPOVERCDLC = 0x6d | |||||
| IFT_IPOVERCLAW = 0x6e | |||||
| IFT_IPSWITCH = 0x4e | |||||
| IFT_IPXIP = 0xf9 | |||||
| IFT_ISDN = 0x3f | |||||
| IFT_ISDNBASIC = 0x14 | |||||
| IFT_ISDNPRIMARY = 0x15 | |||||
| IFT_ISDNS = 0x4b | |||||
| IFT_ISDNU = 0x4c | |||||
| IFT_ISO88022LLC = 0x29 | |||||
| IFT_ISO88023 = 0x7 | |||||
| IFT_ISO88024 = 0x8 | |||||
| IFT_ISO88025 = 0x9 | |||||
| IFT_ISO88025CRFPINT = 0x62 | |||||
| IFT_ISO88025DTR = 0x56 | |||||
| IFT_ISO88025FIBER = 0x73 | |||||
| IFT_ISO88026 = 0xa | |||||
| IFT_ISUP = 0xb3 | |||||
| IFT_L3IPXVLAN = 0x89 | |||||
| IFT_LAPB = 0x10 | |||||
| IFT_LAPD = 0x4d | |||||
| IFT_LAPF = 0x77 | |||||
| IFT_LOCALTALK = 0x2a | |||||
| IFT_LOOP = 0x18 | |||||
| IFT_MEDIAMAILOVERIP = 0x8b | |||||
| IFT_MFSIGLINK = 0xa7 | |||||
| IFT_MIOX25 = 0x26 | |||||
| IFT_MODEM = 0x30 | |||||
| IFT_MPC = 0x71 | |||||
| IFT_MPLS = 0xa6 | |||||
| IFT_MPLSTUNNEL = 0x96 | |||||
| IFT_MSDSL = 0x8f | |||||
| IFT_MVL = 0xbf | |||||
| IFT_MYRINET = 0x63 | |||||
| IFT_NFAS = 0xaf | |||||
| IFT_NSIP = 0x1b | |||||
| IFT_OPTICALCHANNEL = 0xc3 | |||||
| IFT_OPTICALTRANSPORT = 0xc4 | |||||
| IFT_OTHER = 0x1 | |||||
| IFT_P10 = 0xc | |||||
| IFT_P80 = 0xd | |||||
| IFT_PARA = 0x22 | |||||
| IFT_PFLOG = 0xf6 | |||||
| IFT_PFSYNC = 0xf7 | |||||
| IFT_PLC = 0xae | |||||
| IFT_POS = 0xab | |||||
| IFT_PPPMULTILINKBUNDLE = 0x6c | |||||
| IFT_PROPBWAP2MP = 0xb8 | |||||
| IFT_PROPCNLS = 0x59 | |||||
| IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||||
| IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||||
| IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||||
| IFT_PROPMUX = 0x36 | |||||
| IFT_PROPWIRELESSP2P = 0x9d | |||||
| IFT_PTPSERIAL = 0x16 | |||||
| IFT_PVC = 0xf1 | |||||
| IFT_QLLC = 0x44 | |||||
| IFT_RADIOMAC = 0xbc | |||||
| IFT_RADSL = 0x5f | |||||
| IFT_REACHDSL = 0xc0 | |||||
| IFT_RFC1483 = 0x9f | |||||
| IFT_RS232 = 0x21 | |||||
| IFT_RSRB = 0x4f | |||||
| IFT_SDLC = 0x11 | |||||
| IFT_SDSL = 0x60 | |||||
| IFT_SHDSL = 0xa9 | |||||
| IFT_SIP = 0x1f | |||||
| IFT_SLIP = 0x1c | |||||
| IFT_SMDSDXI = 0x2b | |||||
| IFT_SMDSICIP = 0x34 | |||||
| IFT_SONET = 0x27 | |||||
| IFT_SONETOVERHEADCHANNEL = 0xb9 | |||||
| IFT_SONETPATH = 0x32 | |||||
| IFT_SONETVT = 0x33 | |||||
| IFT_SRP = 0x97 | |||||
| IFT_SS7SIGLINK = 0x9c | |||||
| IFT_STACKTOSTACK = 0x6f | |||||
| IFT_STARLAN = 0xb | |||||
| IFT_STF = 0xd7 | |||||
| IFT_T1 = 0x12 | |||||
| IFT_TDLC = 0x74 | |||||
| IFT_TERMPAD = 0x5b | |||||
| IFT_TR008 = 0xb0 | |||||
| IFT_TRANSPHDLC = 0x7b | |||||
| IFT_TUNNEL = 0x83 | |||||
| IFT_ULTRA = 0x1d | |||||
| IFT_USB = 0xa0 | |||||
| IFT_V11 = 0x40 | |||||
| IFT_V35 = 0x2d | |||||
| IFT_V36 = 0x41 | |||||
| IFT_V37 = 0x78 | |||||
| IFT_VDSL = 0x61 | |||||
| IFT_VIRTUALIPADDRESS = 0x70 | |||||
| IFT_VOICEEM = 0x64 | |||||
| IFT_VOICEENCAP = 0x67 | |||||
| IFT_VOICEFXO = 0x65 | |||||
| IFT_VOICEFXS = 0x66 | |||||
| IFT_VOICEOVERATM = 0x98 | |||||
| IFT_VOICEOVERFRAMERELAY = 0x99 | |||||
| IFT_VOICEOVERIP = 0x68 | |||||
| IFT_X213 = 0x5d | |||||
| IFT_X25 = 0x5 | |||||
| IFT_X25DDN = 0x4 | |||||
| IFT_X25HUNTGROUP = 0x7a | |||||
| IFT_X25MLP = 0x79 | |||||
| IFT_X25PLE = 0x28 | |||||
| IFT_XETHER = 0x1a | |||||
| IPPROTO_MAXID = 0x34 | |||||
| IPV6_FAITH = 0x1d | |||||
| IP_FAITH = 0x16 | |||||
| MAP_NORESERVE = 0x40 | |||||
| MAP_RENAME = 0x20 | |||||
| NET_RT_MAXID = 0x6 | |||||
| RTF_PRCLONING = 0x10000 | |||||
| RTM_OLDADD = 0x9 | |||||
| RTM_OLDDEL = 0xa | |||||
| SIOCADDRT = 0x8030720a | |||||
| SIOCALIFADDR = 0x8118691b | |||||
| SIOCDELRT = 0x8030720b | |||||
| SIOCDLIFADDR = 0x8118691d | |||||
| SIOCGLIFADDR = 0xc118691c | |||||
| SIOCGLIFPHYADDR = 0xc118694b | |||||
| SIOCSLIFPHYADDR = 0x8118694a | |||||
| ) | |||||
| @@ -0,0 +1,227 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // Constants that were deprecated or moved to enums in the FreeBSD headers. Keep | |||||
| // them here for backwards compatibility. | |||||
| package unix | |||||
| const ( | |||||
| IFF_SMART = 0x20 | |||||
| IFT_1822 = 0x2 | |||||
| IFT_A12MPPSWITCH = 0x82 | |||||
| IFT_AAL2 = 0xbb | |||||
| IFT_AAL5 = 0x31 | |||||
| IFT_ADSL = 0x5e | |||||
| IFT_AFLANE8023 = 0x3b | |||||
| IFT_AFLANE8025 = 0x3c | |||||
| IFT_ARAP = 0x58 | |||||
| IFT_ARCNET = 0x23 | |||||
| IFT_ARCNETPLUS = 0x24 | |||||
| IFT_ASYNC = 0x54 | |||||
| IFT_ATM = 0x25 | |||||
| IFT_ATMDXI = 0x69 | |||||
| IFT_ATMFUNI = 0x6a | |||||
| IFT_ATMIMA = 0x6b | |||||
| IFT_ATMLOGICAL = 0x50 | |||||
| IFT_ATMRADIO = 0xbd | |||||
| IFT_ATMSUBINTERFACE = 0x86 | |||||
| IFT_ATMVCIENDPT = 0xc2 | |||||
| IFT_ATMVIRTUAL = 0x95 | |||||
| IFT_BGPPOLICYACCOUNTING = 0xa2 | |||||
| IFT_BSC = 0x53 | |||||
| IFT_CCTEMUL = 0x3d | |||||
| IFT_CEPT = 0x13 | |||||
| IFT_CES = 0x85 | |||||
| IFT_CHANNEL = 0x46 | |||||
| IFT_CNR = 0x55 | |||||
| IFT_COFFEE = 0x84 | |||||
| IFT_COMPOSITELINK = 0x9b | |||||
| IFT_DCN = 0x8d | |||||
| IFT_DIGITALPOWERLINE = 0x8a | |||||
| IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||||
| IFT_DLSW = 0x4a | |||||
| IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||||
| IFT_DOCSCABLEMACLAYER = 0x7f | |||||
| IFT_DOCSCABLEUPSTREAM = 0x81 | |||||
| IFT_DS0 = 0x51 | |||||
| IFT_DS0BUNDLE = 0x52 | |||||
| IFT_DS1FDL = 0xaa | |||||
| IFT_DS3 = 0x1e | |||||
| IFT_DTM = 0x8c | |||||
| IFT_DVBASILN = 0xac | |||||
| IFT_DVBASIOUT = 0xad | |||||
| IFT_DVBRCCDOWNSTREAM = 0x93 | |||||
| IFT_DVBRCCMACLAYER = 0x92 | |||||
| IFT_DVBRCCUPSTREAM = 0x94 | |||||
| IFT_ENC = 0xf4 | |||||
| IFT_EON = 0x19 | |||||
| IFT_EPLRS = 0x57 | |||||
| IFT_ESCON = 0x49 | |||||
| IFT_ETHER = 0x6 | |||||
| IFT_FAITH = 0xf2 | |||||
| IFT_FAST = 0x7d | |||||
| IFT_FASTETHER = 0x3e | |||||
| IFT_FASTETHERFX = 0x45 | |||||
| IFT_FDDI = 0xf | |||||
| IFT_FIBRECHANNEL = 0x38 | |||||
| IFT_FRAMERELAYINTERCONNECT = 0x3a | |||||
| IFT_FRAMERELAYMPI = 0x5c | |||||
| IFT_FRDLCIENDPT = 0xc1 | |||||
| IFT_FRELAY = 0x20 | |||||
| IFT_FRELAYDCE = 0x2c | |||||
| IFT_FRF16MFRBUNDLE = 0xa3 | |||||
| IFT_FRFORWARD = 0x9e | |||||
| IFT_G703AT2MB = 0x43 | |||||
| IFT_G703AT64K = 0x42 | |||||
| IFT_GIF = 0xf0 | |||||
| IFT_GIGABITETHERNET = 0x75 | |||||
| IFT_GR303IDT = 0xb2 | |||||
| IFT_GR303RDT = 0xb1 | |||||
| IFT_H323GATEKEEPER = 0xa4 | |||||
| IFT_H323PROXY = 0xa5 | |||||
| IFT_HDH1822 = 0x3 | |||||
| IFT_HDLC = 0x76 | |||||
| IFT_HDSL2 = 0xa8 | |||||
| IFT_HIPERLAN2 = 0xb7 | |||||
| IFT_HIPPI = 0x2f | |||||
| IFT_HIPPIINTERFACE = 0x39 | |||||
| IFT_HOSTPAD = 0x5a | |||||
| IFT_HSSI = 0x2e | |||||
| IFT_HY = 0xe | |||||
| IFT_IBM370PARCHAN = 0x48 | |||||
| IFT_IDSL = 0x9a | |||||
| IFT_IEEE80211 = 0x47 | |||||
| IFT_IEEE80212 = 0x37 | |||||
| IFT_IEEE8023ADLAG = 0xa1 | |||||
| IFT_IFGSN = 0x91 | |||||
| IFT_IMT = 0xbe | |||||
| IFT_INTERLEAVE = 0x7c | |||||
| IFT_IP = 0x7e | |||||
| IFT_IPFORWARD = 0x8e | |||||
| IFT_IPOVERATM = 0x72 | |||||
| IFT_IPOVERCDLC = 0x6d | |||||
| IFT_IPOVERCLAW = 0x6e | |||||
| IFT_IPSWITCH = 0x4e | |||||
| IFT_IPXIP = 0xf9 | |||||
| IFT_ISDN = 0x3f | |||||
| IFT_ISDNBASIC = 0x14 | |||||
| IFT_ISDNPRIMARY = 0x15 | |||||
| IFT_ISDNS = 0x4b | |||||
| IFT_ISDNU = 0x4c | |||||
| IFT_ISO88022LLC = 0x29 | |||||
| IFT_ISO88023 = 0x7 | |||||
| IFT_ISO88024 = 0x8 | |||||
| IFT_ISO88025 = 0x9 | |||||
| IFT_ISO88025CRFPINT = 0x62 | |||||
| IFT_ISO88025DTR = 0x56 | |||||
| IFT_ISO88025FIBER = 0x73 | |||||
| IFT_ISO88026 = 0xa | |||||
| IFT_ISUP = 0xb3 | |||||
| IFT_L3IPXVLAN = 0x89 | |||||
| IFT_LAPB = 0x10 | |||||
| IFT_LAPD = 0x4d | |||||
| IFT_LAPF = 0x77 | |||||
| IFT_LOCALTALK = 0x2a | |||||
| IFT_LOOP = 0x18 | |||||
| IFT_MEDIAMAILOVERIP = 0x8b | |||||
| IFT_MFSIGLINK = 0xa7 | |||||
| IFT_MIOX25 = 0x26 | |||||
| IFT_MODEM = 0x30 | |||||
| IFT_MPC = 0x71 | |||||
| IFT_MPLS = 0xa6 | |||||
| IFT_MPLSTUNNEL = 0x96 | |||||
| IFT_MSDSL = 0x8f | |||||
| IFT_MVL = 0xbf | |||||
| IFT_MYRINET = 0x63 | |||||
| IFT_NFAS = 0xaf | |||||
| IFT_NSIP = 0x1b | |||||
| IFT_OPTICALCHANNEL = 0xc3 | |||||
| IFT_OPTICALTRANSPORT = 0xc4 | |||||
| IFT_OTHER = 0x1 | |||||
| IFT_P10 = 0xc | |||||
| IFT_P80 = 0xd | |||||
| IFT_PARA = 0x22 | |||||
| IFT_PFLOG = 0xf6 | |||||
| IFT_PFSYNC = 0xf7 | |||||
| IFT_PLC = 0xae | |||||
| IFT_POS = 0xab | |||||
| IFT_PPPMULTILINKBUNDLE = 0x6c | |||||
| IFT_PROPBWAP2MP = 0xb8 | |||||
| IFT_PROPCNLS = 0x59 | |||||
| IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||||
| IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||||
| IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||||
| IFT_PROPMUX = 0x36 | |||||
| IFT_PROPWIRELESSP2P = 0x9d | |||||
| IFT_PTPSERIAL = 0x16 | |||||
| IFT_PVC = 0xf1 | |||||
| IFT_QLLC = 0x44 | |||||
| IFT_RADIOMAC = 0xbc | |||||
| IFT_RADSL = 0x5f | |||||
| IFT_REACHDSL = 0xc0 | |||||
| IFT_RFC1483 = 0x9f | |||||
| IFT_RS232 = 0x21 | |||||
| IFT_RSRB = 0x4f | |||||
| IFT_SDLC = 0x11 | |||||
| IFT_SDSL = 0x60 | |||||
| IFT_SHDSL = 0xa9 | |||||
| IFT_SIP = 0x1f | |||||
| IFT_SLIP = 0x1c | |||||
| IFT_SMDSDXI = 0x2b | |||||
| IFT_SMDSICIP = 0x34 | |||||
| IFT_SONET = 0x27 | |||||
| IFT_SONETOVERHEADCHANNEL = 0xb9 | |||||
| IFT_SONETPATH = 0x32 | |||||
| IFT_SONETVT = 0x33 | |||||
| IFT_SRP = 0x97 | |||||
| IFT_SS7SIGLINK = 0x9c | |||||
| IFT_STACKTOSTACK = 0x6f | |||||
| IFT_STARLAN = 0xb | |||||
| IFT_STF = 0xd7 | |||||
| IFT_T1 = 0x12 | |||||
| IFT_TDLC = 0x74 | |||||
| IFT_TERMPAD = 0x5b | |||||
| IFT_TR008 = 0xb0 | |||||
| IFT_TRANSPHDLC = 0x7b | |||||
| IFT_TUNNEL = 0x83 | |||||
| IFT_ULTRA = 0x1d | |||||
| IFT_USB = 0xa0 | |||||
| IFT_V11 = 0x40 | |||||
| IFT_V35 = 0x2d | |||||
| IFT_V36 = 0x41 | |||||
| IFT_V37 = 0x78 | |||||
| IFT_VDSL = 0x61 | |||||
| IFT_VIRTUALIPADDRESS = 0x70 | |||||
| IFT_VOICEEM = 0x64 | |||||
| IFT_VOICEENCAP = 0x67 | |||||
| IFT_VOICEFXO = 0x65 | |||||
| IFT_VOICEFXS = 0x66 | |||||
| IFT_VOICEOVERATM = 0x98 | |||||
| IFT_VOICEOVERFRAMERELAY = 0x99 | |||||
| IFT_VOICEOVERIP = 0x68 | |||||
| IFT_X213 = 0x5d | |||||
| IFT_X25 = 0x5 | |||||
| IFT_X25DDN = 0x4 | |||||
| IFT_X25HUNTGROUP = 0x7a | |||||
| IFT_X25MLP = 0x79 | |||||
| IFT_X25PLE = 0x28 | |||||
| IFT_XETHER = 0x1a | |||||
| IPPROTO_MAXID = 0x34 | |||||
| IPV6_FAITH = 0x1d | |||||
| IP_FAITH = 0x16 | |||||
| MAP_NORESERVE = 0x40 | |||||
| MAP_RENAME = 0x20 | |||||
| NET_RT_MAXID = 0x6 | |||||
| RTF_PRCLONING = 0x10000 | |||||
| RTM_OLDADD = 0x9 | |||||
| RTM_OLDDEL = 0xa | |||||
| SIOCADDRT = 0x8040720a | |||||
| SIOCALIFADDR = 0x8118691b | |||||
| SIOCDELRT = 0x8040720b | |||||
| SIOCDLIFADDR = 0x8118691d | |||||
| SIOCGLIFADDR = 0xc118691c | |||||
| SIOCGLIFPHYADDR = 0xc118694b | |||||
| SIOCSLIFPHYADDR = 0x8118694a | |||||
| ) | |||||
| @@ -0,0 +1,226 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| package unix | |||||
| const ( | |||||
| IFT_1822 = 0x2 | |||||
| IFT_A12MPPSWITCH = 0x82 | |||||
| IFT_AAL2 = 0xbb | |||||
| IFT_AAL5 = 0x31 | |||||
| IFT_ADSL = 0x5e | |||||
| IFT_AFLANE8023 = 0x3b | |||||
| IFT_AFLANE8025 = 0x3c | |||||
| IFT_ARAP = 0x58 | |||||
| IFT_ARCNET = 0x23 | |||||
| IFT_ARCNETPLUS = 0x24 | |||||
| IFT_ASYNC = 0x54 | |||||
| IFT_ATM = 0x25 | |||||
| IFT_ATMDXI = 0x69 | |||||
| IFT_ATMFUNI = 0x6a | |||||
| IFT_ATMIMA = 0x6b | |||||
| IFT_ATMLOGICAL = 0x50 | |||||
| IFT_ATMRADIO = 0xbd | |||||
| IFT_ATMSUBINTERFACE = 0x86 | |||||
| IFT_ATMVCIENDPT = 0xc2 | |||||
| IFT_ATMVIRTUAL = 0x95 | |||||
| IFT_BGPPOLICYACCOUNTING = 0xa2 | |||||
| IFT_BSC = 0x53 | |||||
| IFT_CCTEMUL = 0x3d | |||||
| IFT_CEPT = 0x13 | |||||
| IFT_CES = 0x85 | |||||
| IFT_CHANNEL = 0x46 | |||||
| IFT_CNR = 0x55 | |||||
| IFT_COFFEE = 0x84 | |||||
| IFT_COMPOSITELINK = 0x9b | |||||
| IFT_DCN = 0x8d | |||||
| IFT_DIGITALPOWERLINE = 0x8a | |||||
| IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||||
| IFT_DLSW = 0x4a | |||||
| IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||||
| IFT_DOCSCABLEMACLAYER = 0x7f | |||||
| IFT_DOCSCABLEUPSTREAM = 0x81 | |||||
| IFT_DS0 = 0x51 | |||||
| IFT_DS0BUNDLE = 0x52 | |||||
| IFT_DS1FDL = 0xaa | |||||
| IFT_DS3 = 0x1e | |||||
| IFT_DTM = 0x8c | |||||
| IFT_DVBASILN = 0xac | |||||
| IFT_DVBASIOUT = 0xad | |||||
| IFT_DVBRCCDOWNSTREAM = 0x93 | |||||
| IFT_DVBRCCMACLAYER = 0x92 | |||||
| IFT_DVBRCCUPSTREAM = 0x94 | |||||
| IFT_ENC = 0xf4 | |||||
| IFT_EON = 0x19 | |||||
| IFT_EPLRS = 0x57 | |||||
| IFT_ESCON = 0x49 | |||||
| IFT_ETHER = 0x6 | |||||
| IFT_FAST = 0x7d | |||||
| IFT_FASTETHER = 0x3e | |||||
| IFT_FASTETHERFX = 0x45 | |||||
| IFT_FDDI = 0xf | |||||
| IFT_FIBRECHANNEL = 0x38 | |||||
| IFT_FRAMERELAYINTERCONNECT = 0x3a | |||||
| IFT_FRAMERELAYMPI = 0x5c | |||||
| IFT_FRDLCIENDPT = 0xc1 | |||||
| IFT_FRELAY = 0x20 | |||||
| IFT_FRELAYDCE = 0x2c | |||||
| IFT_FRF16MFRBUNDLE = 0xa3 | |||||
| IFT_FRFORWARD = 0x9e | |||||
| IFT_G703AT2MB = 0x43 | |||||
| IFT_G703AT64K = 0x42 | |||||
| IFT_GIF = 0xf0 | |||||
| IFT_GIGABITETHERNET = 0x75 | |||||
| IFT_GR303IDT = 0xb2 | |||||
| IFT_GR303RDT = 0xb1 | |||||
| IFT_H323GATEKEEPER = 0xa4 | |||||
| IFT_H323PROXY = 0xa5 | |||||
| IFT_HDH1822 = 0x3 | |||||
| IFT_HDLC = 0x76 | |||||
| IFT_HDSL2 = 0xa8 | |||||
| IFT_HIPERLAN2 = 0xb7 | |||||
| IFT_HIPPI = 0x2f | |||||
| IFT_HIPPIINTERFACE = 0x39 | |||||
| IFT_HOSTPAD = 0x5a | |||||
| IFT_HSSI = 0x2e | |||||
| IFT_HY = 0xe | |||||
| IFT_IBM370PARCHAN = 0x48 | |||||
| IFT_IDSL = 0x9a | |||||
| IFT_IEEE80211 = 0x47 | |||||
| IFT_IEEE80212 = 0x37 | |||||
| IFT_IEEE8023ADLAG = 0xa1 | |||||
| IFT_IFGSN = 0x91 | |||||
| IFT_IMT = 0xbe | |||||
| IFT_INTERLEAVE = 0x7c | |||||
| IFT_IP = 0x7e | |||||
| IFT_IPFORWARD = 0x8e | |||||
| IFT_IPOVERATM = 0x72 | |||||
| IFT_IPOVERCDLC = 0x6d | |||||
| IFT_IPOVERCLAW = 0x6e | |||||
| IFT_IPSWITCH = 0x4e | |||||
| IFT_ISDN = 0x3f | |||||
| IFT_ISDNBASIC = 0x14 | |||||
| IFT_ISDNPRIMARY = 0x15 | |||||
| IFT_ISDNS = 0x4b | |||||
| IFT_ISDNU = 0x4c | |||||
| IFT_ISO88022LLC = 0x29 | |||||
| IFT_ISO88023 = 0x7 | |||||
| IFT_ISO88024 = 0x8 | |||||
| IFT_ISO88025 = 0x9 | |||||
| IFT_ISO88025CRFPINT = 0x62 | |||||
| IFT_ISO88025DTR = 0x56 | |||||
| IFT_ISO88025FIBER = 0x73 | |||||
| IFT_ISO88026 = 0xa | |||||
| IFT_ISUP = 0xb3 | |||||
| IFT_L3IPXVLAN = 0x89 | |||||
| IFT_LAPB = 0x10 | |||||
| IFT_LAPD = 0x4d | |||||
| IFT_LAPF = 0x77 | |||||
| IFT_LOCALTALK = 0x2a | |||||
| IFT_LOOP = 0x18 | |||||
| IFT_MEDIAMAILOVERIP = 0x8b | |||||
| IFT_MFSIGLINK = 0xa7 | |||||
| IFT_MIOX25 = 0x26 | |||||
| IFT_MODEM = 0x30 | |||||
| IFT_MPC = 0x71 | |||||
| IFT_MPLS = 0xa6 | |||||
| IFT_MPLSTUNNEL = 0x96 | |||||
| IFT_MSDSL = 0x8f | |||||
| IFT_MVL = 0xbf | |||||
| IFT_MYRINET = 0x63 | |||||
| IFT_NFAS = 0xaf | |||||
| IFT_NSIP = 0x1b | |||||
| IFT_OPTICALCHANNEL = 0xc3 | |||||
| IFT_OPTICALTRANSPORT = 0xc4 | |||||
| IFT_OTHER = 0x1 | |||||
| IFT_P10 = 0xc | |||||
| IFT_P80 = 0xd | |||||
| IFT_PARA = 0x22 | |||||
| IFT_PFLOG = 0xf6 | |||||
| IFT_PFSYNC = 0xf7 | |||||
| IFT_PLC = 0xae | |||||
| IFT_POS = 0xab | |||||
| IFT_PPPMULTILINKBUNDLE = 0x6c | |||||
| IFT_PROPBWAP2MP = 0xb8 | |||||
| IFT_PROPCNLS = 0x59 | |||||
| IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||||
| IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||||
| IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||||
| IFT_PROPMUX = 0x36 | |||||
| IFT_PROPWIRELESSP2P = 0x9d | |||||
| IFT_PTPSERIAL = 0x16 | |||||
| IFT_PVC = 0xf1 | |||||
| IFT_QLLC = 0x44 | |||||
| IFT_RADIOMAC = 0xbc | |||||
| IFT_RADSL = 0x5f | |||||
| IFT_REACHDSL = 0xc0 | |||||
| IFT_RFC1483 = 0x9f | |||||
| IFT_RS232 = 0x21 | |||||
| IFT_RSRB = 0x4f | |||||
| IFT_SDLC = 0x11 | |||||
| IFT_SDSL = 0x60 | |||||
| IFT_SHDSL = 0xa9 | |||||
| IFT_SIP = 0x1f | |||||
| IFT_SLIP = 0x1c | |||||
| IFT_SMDSDXI = 0x2b | |||||
| IFT_SMDSICIP = 0x34 | |||||
| IFT_SONET = 0x27 | |||||
| IFT_SONETOVERHEADCHANNEL = 0xb9 | |||||
| IFT_SONETPATH = 0x32 | |||||
| IFT_SONETVT = 0x33 | |||||
| IFT_SRP = 0x97 | |||||
| IFT_SS7SIGLINK = 0x9c | |||||
| IFT_STACKTOSTACK = 0x6f | |||||
| IFT_STARLAN = 0xb | |||||
| IFT_STF = 0xd7 | |||||
| IFT_T1 = 0x12 | |||||
| IFT_TDLC = 0x74 | |||||
| IFT_TERMPAD = 0x5b | |||||
| IFT_TR008 = 0xb0 | |||||
| IFT_TRANSPHDLC = 0x7b | |||||
| IFT_TUNNEL = 0x83 | |||||
| IFT_ULTRA = 0x1d | |||||
| IFT_USB = 0xa0 | |||||
| IFT_V11 = 0x40 | |||||
| IFT_V35 = 0x2d | |||||
| IFT_V36 = 0x41 | |||||
| IFT_V37 = 0x78 | |||||
| IFT_VDSL = 0x61 | |||||
| IFT_VIRTUALIPADDRESS = 0x70 | |||||
| IFT_VOICEEM = 0x64 | |||||
| IFT_VOICEENCAP = 0x67 | |||||
| IFT_VOICEFXO = 0x65 | |||||
| IFT_VOICEFXS = 0x66 | |||||
| IFT_VOICEOVERATM = 0x98 | |||||
| IFT_VOICEOVERFRAMERELAY = 0x99 | |||||
| IFT_VOICEOVERIP = 0x68 | |||||
| IFT_X213 = 0x5d | |||||
| IFT_X25 = 0x5 | |||||
| IFT_X25DDN = 0x4 | |||||
| IFT_X25HUNTGROUP = 0x7a | |||||
| IFT_X25MLP = 0x79 | |||||
| IFT_X25PLE = 0x28 | |||||
| IFT_XETHER = 0x1a | |||||
| // missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go | |||||
| IFF_SMART = 0x20 | |||||
| IFT_FAITH = 0xf2 | |||||
| IFT_IPXIP = 0xf9 | |||||
| IPPROTO_MAXID = 0x34 | |||||
| IPV6_FAITH = 0x1d | |||||
| IP_FAITH = 0x16 | |||||
| MAP_NORESERVE = 0x40 | |||||
| MAP_RENAME = 0x20 | |||||
| NET_RT_MAXID = 0x6 | |||||
| RTF_PRCLONING = 0x10000 | |||||
| RTM_OLDADD = 0x9 | |||||
| RTM_OLDDEL = 0xa | |||||
| SIOCADDRT = 0x8030720a | |||||
| SIOCALIFADDR = 0x8118691b | |||||
| SIOCDELRT = 0x8030720b | |||||
| SIOCDLIFADDR = 0x8118691d | |||||
| SIOCGLIFADDR = 0xc118691c | |||||
| SIOCGLIFPHYADDR = 0xc118694b | |||||
| SIOCSLIFPHYADDR = 0x8118694a | |||||
| ) | |||||
| @@ -1,5 +1,3 @@ | |||||
| // +build linux darwin freebsd openbsd netbsd dragonfly | |||||
| // Copyright 2014 The Go Authors. All rights reserved. | // Copyright 2014 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| @@ -14,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))) | ||||
| @@ -1,4 +1,4 @@ | |||||
| // +build linux,386 linux,arm | |||||
| // +build linux,386 linux,arm linux,mips linux,mipsle | |||||
| // Copyright 2014 The Go Authors. All rights reserved. | // Copyright 2014 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| @@ -1,19 +1,30 @@ | |||||
| // Copyright 2015 The Go Authors. All rights reserved. | |||||
| // Copyright 2015 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build gccgo | // +build gccgo | ||||
| // +build !aix | |||||
| package unix | package unix | ||||
| import "syscall" | 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 +46,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) | ||||
| @@ -1,8 +1,9 @@ | |||||
| // Copyright 2015 The Go Authors. All rights reserved. | |||||
| // Copyright 2015 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build gccgo | // +build gccgo | ||||
| // +build !aix | |||||
| #include <errno.h> | #include <errno.h> | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| @@ -31,11 +32,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. | |||||
| extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline)); | |||||
| void | |||||
| use(void *p __attribute__ ((unused))) | |||||
| 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) | |||||
| { | { | ||||
| return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9); | |||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| // Copyright 2015 The Go Authors. All rights reserved. | |||||
| // Copyright 2015 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| @@ -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 | |||||
| } | |||||
| @@ -8,10 +8,11 @@ | |||||
| // modify the generated types. It is used to clean up | // modify the generated types. It is used to clean up | ||||
| // the sys API in an architecture specific manner. | // the sys API in an architecture specific manner. | ||||
| // | // | ||||
| // mkpost is run after cgo -godefs by mkall.sh. | |||||
| // mkpost is run after cgo -godefs; see README.md. | |||||
| package main | package main | ||||
| import ( | import ( | ||||
| "bytes" | |||||
| "fmt" | "fmt" | ||||
| "go/format" | "go/format" | ||||
| "io/ioutil" | "io/ioutil" | ||||
| @@ -21,42 +22,77 @@ import ( | |||||
| ) | ) | ||||
| func main() { | func main() { | ||||
| // Get the OS and architecture (using GOARCH_TARGET if it exists) | |||||
| goos := os.Getenv("GOOS") | |||||
| goarch := os.Getenv("GOARCH_TARGET") | |||||
| if goarch == "" { | |||||
| goarch = os.Getenv("GOARCH") | |||||
| } | |||||
| // Check that we are using the new build system if we should be. | |||||
| if goos == "linux" && goarch != "sparc64" { | |||||
| if os.Getenv("GOLANG_SYS_BUILD") != "docker" { | |||||
| os.Stderr.WriteString("In the new build system, mkpost should not be called directly.\n") | |||||
| os.Stderr.WriteString("See README.md\n") | |||||
| os.Exit(1) | |||||
| } | |||||
| } | |||||
| b, err := ioutil.ReadAll(os.Stdin) | b, err := ioutil.ReadAll(os.Stdin) | ||||
| if err != nil { | if err != nil { | ||||
| log.Fatal(err) | log.Fatal(err) | ||||
| } | } | ||||
| s := string(b) | |||||
| goarch := os.Getenv("GOARCH") | |||||
| goos := os.Getenv("GOOS") | |||||
| if goarch == "s390x" && goos == "linux" { | |||||
| // Export the types of PtraceRegs fields. | |||||
| re := regexp.MustCompile("ptrace(Psw|Fpregs|Per)") | |||||
| s = re.ReplaceAllString(s, "Ptrace$1") | |||||
| // Replace padding fields inserted by cgo with blank identifiers. | |||||
| re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*") | |||||
| s = re.ReplaceAllString(s, "_") | |||||
| // Replace other unwanted fields with blank identifiers. | |||||
| re = regexp.MustCompile("X_[A-Za-z0-9_]*") | |||||
| s = re.ReplaceAllString(s, "_") | |||||
| // Replace the control_regs union with a blank identifier for now. | |||||
| re = regexp.MustCompile("(Control_regs)\\s+\\[0\\]uint64") | |||||
| s = re.ReplaceAllString(s, "_ [0]uint64") | |||||
| } | |||||
| // 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 | |||||
| // nonempty Ptrace structs. | |||||
| ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`) | |||||
| b = ptraceRexexp.ReplaceAll(b, nil) | |||||
| // Replace the control_regs union with a blank identifier for now. | |||||
| controlRegsRegex := regexp.MustCompile(`(Control_regs)\s+\[0\]uint64`) | |||||
| b = controlRegsRegex.ReplaceAll(b, []byte("_ [0]uint64")) | |||||
| // Remove fields that are added by glibc | |||||
| // Note that this is unstable as the identifers are private. | |||||
| removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`) | |||||
| b = removeFieldsRegex.ReplaceAll(b, []byte("_")) | |||||
| // Convert [65]int8 to [65]byte in Utsname members to simplify | |||||
| // conversion to string; see golang.org/issue/20753 | |||||
| convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`) | |||||
| b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte")) | |||||
| // Remove spare fields (e.g. in Statx_t) | |||||
| spareFieldsRegex := regexp.MustCompile(`X__spare\S*`) | |||||
| b = spareFieldsRegex.ReplaceAll(b, []byte("_")) | |||||
| // Remove cgo padding fields | |||||
| removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`) | |||||
| 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 | |||||
| b = b[bytes.IndexByte(b, '\n')+1:] | |||||
| // Modify the command in the header to include: | |||||
| // mkpost, our own warning, and a build tag. | |||||
| replacement := fmt.Sprintf(`$1 | go run mkpost.go | |||||
| // Code generated by the command above; see README.md. DO NOT EDIT. | |||||
| // +build %s,%s`, goarch, goos) | |||||
| cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`) | |||||
| b = cgoCommandRegex.ReplaceAll(b, []byte(replacement)) | |||||
| // gofmt | // gofmt | ||||
| b, err = format.Source([]byte(s)) | |||||
| b, err = format.Source(b) | |||||
| if err != nil { | if err != nil { | ||||
| log.Fatal(err) | log.Fatal(err) | ||||
| } | } | ||||
| // Append this command to the header to show where the new file | |||||
| // came from. | |||||
| re := regexp.MustCompile("(cgo -godefs [a-zA-Z0-9_]+\\.go.*)") | |||||
| b = re.ReplaceAll(b, []byte("$1 | go run mkpost.go")) | |||||
| fmt.Printf("%s", b) | |||||
| os.Stdout.Write(b) | |||||
| } | } | ||||
| @@ -0,0 +1,166 @@ | |||||
| // Copyright 2016 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build openbsd | |||||
| // +build 386 amd64 arm | |||||
| package unix | |||||
| import ( | |||||
| "errors" | |||||
| "fmt" | |||||
| "strconv" | |||||
| "syscall" | |||||
| "unsafe" | |||||
| ) | |||||
| // Pledge implements the pledge syscall. | |||||
| // | |||||
| // The pledge syscall does not accept execpromises on OpenBSD releases | |||||
| // before 6.3. | |||||
| // | |||||
| // execpromises must be empty when Pledge is called on OpenBSD | |||||
| // releases predating 6.3, otherwise an error will be returned. | |||||
| // | |||||
| // For more information see pledge(2). | |||||
| func Pledge(promises, execpromises string) error { | |||||
| maj, min, err := majmin() | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| err = pledgeAvailable(maj, min, execpromises) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| pptr, err := syscall.BytePtrFromString(promises) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| // This variable will hold either a nil unsafe.Pointer or | |||||
| // an unsafe.Pointer to a string (execpromises). | |||||
| var expr unsafe.Pointer | |||||
| // If we're running on OpenBSD > 6.2, pass execpromises to the syscall. | |||||
| if maj > 6 || (maj == 6 && min > 2) { | |||||
| exptr, err := syscall.BytePtrFromString(execpromises) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| expr = unsafe.Pointer(exptr) | |||||
| } | |||||
| _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) | |||||
| if e != 0 { | |||||
| return e | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // PledgePromises implements the pledge syscall. | |||||
| // | |||||
| // This changes the promises and leaves the execpromises untouched. | |||||
| // | |||||
| // For more information see pledge(2). | |||||
| func PledgePromises(promises string) error { | |||||
| maj, min, err := majmin() | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| err = pledgeAvailable(maj, min, "") | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| // This variable holds the execpromises and is always nil. | |||||
| var expr unsafe.Pointer | |||||
| pptr, err := syscall.BytePtrFromString(promises) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) | |||||
| if e != 0 { | |||||
| return e | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // PledgeExecpromises implements the pledge syscall. | |||||
| // | |||||
| // This changes the execpromises and leaves the promises untouched. | |||||
| // | |||||
| // For more information see pledge(2). | |||||
| func PledgeExecpromises(execpromises string) error { | |||||
| maj, min, err := majmin() | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| err = pledgeAvailable(maj, min, execpromises) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| // This variable holds the promises and is always nil. | |||||
| var pptr unsafe.Pointer | |||||
| exptr, err := syscall.BytePtrFromString(execpromises) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), uintptr(unsafe.Pointer(exptr)), 0) | |||||
| if e != 0 { | |||||
| return e | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // majmin returns major and minor version number for an OpenBSD system. | |||||
| func majmin() (major int, minor int, err error) { | |||||
| var v Utsname | |||||
| err = Uname(&v) | |||||
| if err != nil { | |||||
| return | |||||
| } | |||||
| major, err = strconv.Atoi(string(v.Release[0])) | |||||
| if err != nil { | |||||
| err = errors.New("cannot parse major version number returned by uname") | |||||
| return | |||||
| } | |||||
| minor, err = strconv.Atoi(string(v.Release[2])) | |||||
| if err != nil { | |||||
| err = errors.New("cannot parse minor version number returned by uname") | |||||
| return | |||||
| } | |||||
| return | |||||
| } | |||||
| // pledgeAvailable checks for availability of the pledge(2) syscall | |||||
| // based on the running OpenBSD version. | |||||
| func pledgeAvailable(maj, min int, execpromises string) error { | |||||
| // If OpenBSD <= 5.9, pledge is not available. | |||||
| if (maj == 5 && min != 9) || maj < 5 { | |||||
| return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min) | |||||
| } | |||||
| // If OpenBSD <= 6.2 and execpromises is not empty, | |||||
| // return an error - execpromises is not available before 6.3 | |||||
| if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" { | |||||
| return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min) | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -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,15 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // For Unix, get the pagesize from the runtime. | |||||
| package unix | |||||
| import "syscall" | |||||
| func Getpagesize() int { | |||||
| return syscall.Getpagesize() | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| // Copyright 2012 The Go Authors. All rights reserved. | |||||
| // Copyright 2012 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| @@ -1,8 +1,8 @@ | |||||
| // Copyright 2012 The Go Authors. All rights reserved. | |||||
| // Copyright 2012 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly | |||||
| // +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly | |||||
| package unix | package unix | ||||
| @@ -1,4 +1,4 @@ | |||||
| // Copyright 2011 The Go Authors. All rights reserved. | |||||
| // Copyright 2011 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| @@ -1,8 +1,8 @@ | |||||
| // Copyright 2011 The Go Authors. All rights reserved. | |||||
| // Copyright 2011 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // Socket control messages | // Socket control messages | ||||
| @@ -12,10 +12,11 @@ import "unsafe" | |||||
| // Round the length of a raw sockaddr up to align it properly. | // Round the length of a raw sockaddr up to align it properly. | ||||
| func cmsgAlignOf(salen int) int { | func cmsgAlignOf(salen int) int { | ||||
| salign := sizeofPtr | |||||
| // NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels | |||||
| // still require 32-bit aligned access to network subsystem. | |||||
| if darwin64Bit || dragonfly64Bit { | |||||
| salign := SizeofPtr | |||||
| // NOTE: It seems like 64-bit Darwin, DragonFly BSD and | |||||
| // Solaris kernels still require 32-bit aligned access to | |||||
| // network subsystem. | |||||
| if darwin64Bit || dragonfly64Bit || solaris64Bit { | |||||
| salign = 4 | salign = 4 | ||||
| } | } | ||||
| return (salen + salign - 1) & ^(salign - 1) | return (salen + salign - 1) & ^(salign - 1) | ||||
| @@ -2,7 +2,7 @@ | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| package unix | package unix | ||||
| @@ -2,35 +2,36 @@ | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // Package unix contains an interface to the low-level operating system | // Package unix contains an interface to the low-level operating system | ||||
| // primitives. OS details vary depending on the underlying system, and | |||||
| // primitives. OS details vary depending on the underlying system, and | |||||
| // by default, godoc will display OS-specific documentation for the current | // by default, godoc will display OS-specific documentation for the current | ||||
| // system. If you want godoc to display OS documentation for another | |||||
| // system, set $GOOS and $GOARCH to the desired system. For example, if | |||||
| // system. If you want godoc to display OS documentation for another | |||||
| // system, set $GOOS and $GOARCH to the desired system. For example, if | |||||
| // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS | // 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 "unsafe" | |||||
| 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 s[i] == 0 { | |||||
| return nil, EINVAL | |||||
| } | |||||
| if strings.IndexByte(s, 0) != -1 { | |||||
| return nil, EINVAL | |||||
| } | } | ||||
| a := make([]byte, len(s)+1) | a := make([]byte, len(s)+1) | ||||
| copy(a, s) | copy(a, s) | ||||
| @@ -51,26 +52,3 @@ func BytePtrFromString(s string) (*byte, error) { | |||||
| // Single-word zero for use when we need a valid pointer to 0 bytes. | // Single-word zero for use when we need a valid pointer to 0 bytes. | ||||
| // See mkunix.pl. | // See mkunix.pl. | ||||
| var _zero uintptr | var _zero uintptr | ||||
| func (ts *Timespec) Unix() (sec int64, nsec int64) { | |||||
| return int64(ts.Sec), int64(ts.Nsec) | |||||
| } | |||||
| func (tv *Timeval) Unix() (sec int64, nsec int64) { | |||||
| return int64(tv.Sec), int64(tv.Usec) * 1000 | |||||
| } | |||||
| func (ts *Timespec) Nano() int64 { | |||||
| return int64(ts.Sec)*1e9 + int64(ts.Nsec) | |||||
| } | |||||
| func (tv *Timeval) Nano() int64 { | |||||
| return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 | |||||
| } | |||||
| func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } | |||||
| // use is a no-op, but the compiler cannot see that it is. | |||||
| // Calling use(p) ensures that p is kept live until that point. | |||||
| //go:noescape | |||||
| func use(p unsafe.Pointer) | |||||
| @@ -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 ( | |||||
| "syscall" | |||||
| "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 // substract 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 | |||||
| } | |||||
| // 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) | |||||
| func Flock(fd int, how int) (err error) { | |||||
| return syscall.Flock(fd, how) | |||||
| } | |||||
| /* | |||||
| * 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) | |||||
| } | |||||
| @@ -34,7 +34,7 @@ func Getgroups() (gids []int, err error) { | |||||
| return nil, nil | return nil, nil | ||||
| } | } | ||||
| // Sanity check group count. Max is 16 on BSD. | |||||
| // Sanity check group count. Max is 16 on BSD. | |||||
| if n < 0 || n > 1000 { | if n < 0 || n > 1000 { | ||||
| return nil, EINVAL | return nil, EINVAL | ||||
| } | } | ||||
| @@ -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) { | |||||
| 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) { | |||||
| 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) { | |||||
| var n byte | |||||
| vallen := _Socklen(1) | |||||
| err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) | |||||
| return 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 | |||||
| // 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 | |||||
| } | } | ||||
| //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 | |||||
| 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 | ||||
| } | } | ||||
| @@ -470,25 +441,11 @@ func Sysctl(name string) (string, error) { | |||||
| } | } | ||||
| func SysctlArgs(name string, args ...int) (string, error) { | func SysctlArgs(name string, args ...int) (string, error) { | ||||
| mib, err := sysctlmib(name, args...) | |||||
| buf, err := SysctlRaw(name, args...) | |||||
| if err != nil { | if err != nil { | ||||
| return "", err | return "", err | ||||
| } | } | ||||
| // Find size. | |||||
| n := uintptr(0) | |||||
| if err := sysctl(mib, nil, &n, nil, 0); err != nil { | |||||
| return "", err | |||||
| } | |||||
| if n == 0 { | |||||
| return "", nil | |||||
| } | |||||
| // Read into buffer of that size. | |||||
| buf := make([]byte, n) | |||||
| if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { | |||||
| return "", err | |||||
| } | |||||
| n := len(buf) | |||||
| // Throw away terminating NUL. | // Throw away terminating NUL. | ||||
| if n > 0 && buf[n-1] == '\x00' { | if n > 0 && buf[n-1] == '\x00' { | ||||
| @@ -575,13 +532,24 @@ func Utimes(path string, tv []Timeval) error { | |||||
| func UtimesNano(path string, ts []Timespec) error { | func UtimesNano(path string, ts []Timespec) error { | ||||
| if ts == nil { | if ts == nil { | ||||
| err := utimensat(AT_FDCWD, path, nil, 0) | |||||
| if err != ENOSYS { | |||||
| return err | |||||
| } | |||||
| return utimes(path, nil) | return utimes(path, nil) | ||||
| } | } | ||||
| // TODO: The BSDs can do utimensat with SYS_UTIMENSAT but it | |||||
| // isn't supported by darwin so this uses utimes instead | |||||
| if len(ts) != 2 { | if len(ts) != 2 { | ||||
| return EINVAL | return EINVAL | ||||
| } | } | ||||
| // 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 { | |||||
| return err | |||||
| } | |||||
| // Not as efficient as it could be because Timespec and | // Not as efficient as it could be because Timespec and | ||||
| // Timeval have different types in the different OSes | // Timeval have different types in the different OSes | ||||
| tv := [2]Timeval{ | tv := [2]Timeval{ | ||||
| @@ -591,6 +559,20 @@ func UtimesNano(path string, ts []Timespec) error { | |||||
| return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) | return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[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 | |||||
| } | |||||
| err := setattrlistTimes(path, ts, flags) | |||||
| if err != ENOSYS { | |||||
| return err | |||||
| } | |||||
| return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) | |||||
| } | |||||
| //sys futimes(fd int, timeval *[2]Timeval) (err error) | //sys futimes(fd int, timeval *[2]Timeval) (err error) | ||||
| func Futimes(fd int, tv []Timeval) error { | func Futimes(fd int, tv []Timeval) error { | ||||
| @@ -605,12 +587,18 @@ func Futimes(fd int, tv []Timeval) 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) | ||||
| //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) | |||||
| } | |||||
| // TODO: wrap | // TODO: wrap | ||||
| // Acct(name nil-string) (err error) | // Acct(name nil-string) (err error) | ||||
| // Gethostuuid(uuid *byte, timeout *Timespec) (err error) | // Gethostuuid(uuid *byte, timeout *Timespec) (err error) | ||||
| // Madvise(addr *byte, len int, behav int) (err error) | |||||
| // Mprotect(addr *byte, len int, prot int) (err error) | |||||
| // Msync(addr *byte, len int, flags int) (err error) | |||||
| // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) | // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) | ||||
| var mapper = &mmapper{ | var mapper = &mmapper{ | ||||
| @@ -626,3 +614,11 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e | |||||
| func Munmap(b []byte) (err error) { | func Munmap(b []byte) (err error) { | ||||
| return mapper.Munmap(b) | return mapper.Munmap(b) | ||||
| } | } | ||||
| //sys Madvise(b []byte, behav int) (err error) | |||||
| //sys Mlock(b []byte) (err error) | |||||
| //sys Mlockall(flags int) (err error) | |||||
| //sys Mprotect(b []byte, prot int) (err error) | |||||
| //sys Msync(b []byte, flags int) (err error) | |||||
| //sys Munlock(b []byte) (err error) | |||||
| //sys Munlockall() (err error) | |||||
| @@ -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) { | |||||
| 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 | ||||
| @@ -54,7 +55,7 @@ func nametomib(name string) (mib []_C_int, err error) { | |||||
| // NOTE(rsc): It seems strange to set the buffer to have | // NOTE(rsc): It seems strange to set the buffer to have | ||||
| // size CTL_MAXNAME+2 but use only CTL_MAXNAME | // size CTL_MAXNAME+2 but use only CTL_MAXNAME | ||||
| // as the size. I don't know why the +2 is here, but the | |||||
| // as the size. I don't know why the +2 is here, but the | |||||
| // kernel uses +2 for its own implementation of this function. | // kernel uses +2 for its own implementation of this function. | ||||
| // I am scared that if we don't include the +2 here, the kernel | // I am scared that if we don't include the +2 here, the kernel | ||||
| // will silently write 2 words farther than we specify | // will silently write 2 words farther than we specify | ||||
| @@ -76,34 +77,6 @@ func nametomib(name string) (mib []_C_int, err error) { | |||||
| return buf[0 : n/siz], nil | return buf[0 : n/siz], nil | ||||
| } | } | ||||
| // ParseDirent parses up to max directory entries in buf, | |||||
| // appending the names to names. It returns the number | |||||
| // bytes consumed from buf, the number of entries added | |||||
| // to names, and the new names slice. | |||||
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||||
| origlen := len(buf) | |||||
| for max != 0 && len(buf) > 0 { | |||||
| dirent := (*Dirent)(unsafe.Pointer(&buf[0])) | |||||
| if dirent.Reclen == 0 { | |||||
| buf = nil | |||||
| break | |||||
| } | |||||
| buf = buf[dirent.Reclen:] | |||||
| if dirent.Ino == 0 { // File absent in directory. | |||||
| continue | |||||
| } | |||||
| bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) | |||||
| var name = string(bytes[0:dirent.Namlen]) | |||||
| if name == "." || name == ".." { // Useless names | |||||
| continue | |||||
| } | |||||
| max-- | |||||
| count++ | |||||
| names = append(names, name) | |||||
| } | |||||
| return origlen - len(buf), count, names | |||||
| } | |||||
| //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) } | ||||
| @@ -125,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 | ||||
| @@ -144,7 +117,6 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) ( | |||||
| uintptr(options), | uintptr(options), | ||||
| 0, | 0, | ||||
| ) | ) | ||||
| use(unsafe.Pointer(_p0)) | |||||
| if e1 != 0 { | if e1 != 0 { | ||||
| return nil, e1 | return nil, e1 | ||||
| } | } | ||||
| @@ -162,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]) | ||||
| @@ -197,7 +169,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | ||||
| } | } | ||||
| r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags)) | r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags)) | ||||
| use(unsafe.Pointer(_p0)) | |||||
| n = int(r0) | n = int(r0) | ||||
| if e1 != 0 { | if e1 != 0 { | ||||
| err = e1 | err = e1 | ||||
| @@ -205,6 +176,148 @@ 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 fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) | |||||
| func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { | |||||
| return fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0) | |||||
| } | |||||
| //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 fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) | |||||
| func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) { | |||||
| return fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0) | |||||
| } | |||||
| //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 fremovexattr(fd int, attr string, options int) (err error) | |||||
| func Fremovexattr(fd int, attr string) (err error) { | |||||
| return fremovexattr(fd, attr, 0) | |||||
| } | |||||
| //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) | |||||
| } | |||||
| //sys flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) | |||||
| func Flistxattr(fd int, dest []byte) (sz int, err error) { | |||||
| return flistxattr(fd, xattrPointer(dest), len(dest), 0) | |||||
| } | |||||
| 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 { | |||||
| // Darwin doesn't support SYS_UTIMENSAT | |||||
| return ENOSYS | |||||
| } | |||||
| /* | /* | ||||
| * Wrapped | * Wrapped | ||||
| */ | */ | ||||
| @@ -213,6 +326,91 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) } | func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) } | ||||
| //sys ioctl(fd int, req uint, arg uintptr) (err error) | |||||
| // 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 | ||||
| */ | */ | ||||
| @@ -228,13 +426,17 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||||
| //sys Dup2(from int, to int) (err error) | //sys Dup2(from int, to int) (err error) | ||||
| //sys Exchangedata(path1 string, path2 string, options int) (err error) | //sys Exchangedata(path1 string, path2 string, options 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 Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) | |||||
| //sys Flock(fd int, how int) (err error) | //sys Flock(fd int, how int) (err error) | ||||
| //sys Fpathconf(fd int, name int) (val int, err error) | //sys Fpathconf(fd int, name int) (val int, err error) | ||||
| //sys Fstat(fd int, stat *Stat_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) | ||||
| @@ -256,23 +458,23 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||||
| //sys Kqueue() (fd int, err error) | //sys Kqueue() (fd int, err error) | ||||
| //sys Lchown(path string, uid int, gid int) (err error) | //sys Lchown(path string, uid int, gid int) (err error) | ||||
| //sys Link(path string, link string) (err error) | //sys Link(path string, link string) (err error) | ||||
| //sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) | |||||
| //sys Listen(s int, backlog int) (err error) | //sys Listen(s int, backlog 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 Mkdir(path string, mode uint32) (err error) | //sys Mkdir(path string, mode uint32) (err error) | ||||
| //sys Mkdirat(dirfd int, path string, mode uint32) (err error) | |||||
| //sys Mkfifo(path string, mode uint32) (err error) | //sys Mkfifo(path string, mode uint32) (err error) | ||||
| //sys Mknod(path string, mode uint32, dev int) (err error) | //sys Mknod(path string, mode uint32, dev int) (err error) | ||||
| //sys Mlock(b []byte) (err error) | |||||
| //sys Mlockall(flags int) (err error) | |||||
| //sys Mprotect(b []byte, prot int) (err error) | |||||
| //sys Munlock(b []byte) (err error) | |||||
| //sys Munlockall() (err error) | |||||
| //sys Open(path string, mode int, perm uint32) (fd int, err error) | //sys Open(path string, mode int, perm uint32) (fd int, err error) | ||||
| //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) | |||||
| //sys Pathconf(path string, name int) (val int, err error) | //sys Pathconf(path string, name int) (val int, err error) | ||||
| //sys Pread(fd int, p []byte, offset int64) (n int, err error) | //sys Pread(fd int, p []byte, offset int64) (n int, err error) | ||||
| //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) | //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) | ||||
| //sys read(fd int, p []byte) (n int, err error) | //sys read(fd int, p []byte) (n int, err error) | ||||
| //sys Readlink(path string, buf []byte) (n int, err error) | //sys Readlink(path string, buf []byte) (n int, err error) | ||||
| //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) | |||||
| //sys Rename(from string, to string) (err error) | //sys Rename(from string, to string) (err error) | ||||
| //sys Renameat(fromfd int, from string, tofd int, to string) (err error) | |||||
| //sys Revoke(path string) (err error) | //sys Revoke(path 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) = SYS_LSEEK | //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK | ||||
| @@ -293,11 +495,13 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||||
| //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 | //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 | ||||
| //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 | //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 | ||||
| //sys Symlink(path string, link string) (err error) | //sys Symlink(path string, link string) (err error) | ||||
| //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) | |||||
| //sys Sync() (err error) | //sys Sync() (err error) | ||||
| //sys Truncate(path string, length int64) (err error) | //sys Truncate(path string, length int64) (err error) | ||||
| //sys Umask(newmask int) (oldmask int) | //sys Umask(newmask int) (oldmask int) | ||||
| //sys Undelete(path string) (err error) | //sys Undelete(path string) (err error) | ||||
| //sys Unlink(path string) (err error) | //sys Unlink(path string) (err error) | ||||
| //sys Unlinkat(dirfd int, path string, flags int) (err error) | |||||
| //sys Unmount(path string, flags int) (err error) | //sys Unmount(path string, flags int) (err error) | ||||
| //sys write(fd int, p []byte) (n int, err error) | //sys write(fd int, p []byte) (n int, err error) | ||||
| //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) | ||||
| @@ -337,9 +541,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||||
| // Add_profil | // Add_profil | ||||
| // Kdebug_trace | // Kdebug_trace | ||||
| // Sigreturn | // Sigreturn | ||||
| // Mmap | |||||
| // Mlock | |||||
| // Munlock | |||||
| // Atsocket | // Atsocket | ||||
| // Kqueue_from_portset_np | // Kqueue_from_portset_np | ||||
| // Kqueue_portset | // Kqueue_portset | ||||
| @@ -349,18 +550,9 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||||
| // Searchfs | // Searchfs | ||||
| // Delete | // Delete | ||||
| // Copyfile | // Copyfile | ||||
| // Poll | |||||
| // Watchevent | // Watchevent | ||||
| // Waitevent | // Waitevent | ||||
| // Modwatch | // Modwatch | ||||
| // Getxattr | |||||
| // Fgetxattr | |||||
| // Setxattr | |||||
| // Fsetxattr | |||||
| // Removexattr | |||||
| // Fremovexattr | |||||
| // Listxattr | |||||
| // Flistxattr | |||||
| // Fsctl | // Fsctl | ||||
| // Initgroups | // Initgroups | ||||
| // Posix_spawn | // Posix_spawn | ||||
| @@ -432,8 +624,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||||
| // Lio_listio | // Lio_listio | ||||
| // __pthread_cond_wait | // __pthread_cond_wait | ||||
| // Iopolicysys | // Iopolicysys | ||||
| // Mlockall | |||||
| // Munlockall | |||||
| // __pthread_kill | // __pthread_kill | ||||
| // __pthread_sigmask | // __pthread_sigmask | ||||
| // __sigwait | // __sigwait | ||||
| @@ -487,7 +677,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||||
| // Sendmsg_nocancel | // Sendmsg_nocancel | ||||
| // Recvfrom_nocancel | // Recvfrom_nocancel | ||||
| // Accept_nocancel | // Accept_nocancel | ||||
| // Msync_nocancel | |||||
| // Fcntl_nocancel | // Fcntl_nocancel | ||||
| // Select_nocancel | // Select_nocancel | ||||
| // Fsync_nocancel | // Fsync_nocancel | ||||
| @@ -11,27 +11,18 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int32(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: int32(sec), Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int32(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: int32(sec), Usec: int32(usec)} | |||||
| } | } | ||||
| //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) | //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) | ||||
| func Gettimeofday(tv *Timeval) (err error) { | func Gettimeofday(tv *Timeval) (err error) { | ||||
| // The tv passed to gettimeofday must be non-nil | // The tv passed to gettimeofday must be non-nil | ||||
| // but is otherwise unused. The answers come back | |||||
| // but is otherwise unused. The answers come back | |||||
| // in the two registers. | // in the two registers. | ||||
| sec, usec, err := gettimeofday(tv) | sec, usec, err := gettimeofday(tv) | ||||
| tv.Sec = int32(sec) | tv.Sec = int32(sec) | ||||
| @@ -11,29 +11,18 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) | |||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: int32(usec)} | |||||
| } | } | ||||
| //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) | //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) | ||||
| func Gettimeofday(tv *Timeval) (err error) { | func Gettimeofday(tv *Timeval) (err error) { | ||||
| // The tv passed to gettimeofday must be non-nil | // The tv passed to gettimeofday must be non-nil | ||||
| // but is otherwise unused. The answers come back | |||||
| // but is otherwise unused. The answers come back | |||||
| // in the two registers. | // in the two registers. | ||||
| sec, usec, err := gettimeofday(tv) | sec, usec, err := gettimeofday(tv) | ||||
| tv.Sec = sec | tv.Sec = sec | ||||
| @@ -9,27 +9,18 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int32(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: int32(sec), Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int32(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: int32(sec), Usec: int32(usec)} | |||||
| } | } | ||||
| //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) | //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) | ||||
| func Gettimeofday(tv *Timeval) (err error) { | func Gettimeofday(tv *Timeval) (err error) { | ||||
| // The tv passed to gettimeofday must be non-nil | // The tv passed to gettimeofday must be non-nil | ||||
| // but is otherwise unused. The answers come back | |||||
| // but is otherwise unused. The answers come back | |||||
| // in the two registers. | // in the two registers. | ||||
| sec, usec, err := gettimeofday(tv) | sec, usec, err := gettimeofday(tv) | ||||
| tv.Sec = int32(sec) | tv.Sec = int32(sec) | ||||
| @@ -69,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 | |||||
| @@ -11,27 +11,18 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 16384 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: int32(usec)} | |||||
| } | } | ||||
| //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) | //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) | ||||
| func Gettimeofday(tv *Timeval) (err error) { | func Gettimeofday(tv *Timeval) (err error) { | ||||
| // The tv passed to gettimeofday must be non-nil | // The tv passed to gettimeofday must be non-nil | ||||
| // but is otherwise unused. The answers come back | |||||
| // but is otherwise unused. The answers come back | |||||
| // in the two registers. | // in the two registers. | ||||
| sec, usec, err := gettimeofday(tv) | sec, usec, err := gettimeofday(tv) | ||||
| tv.Sec = sec | tv.Sec = sec | ||||
| @@ -1,8 +1,8 @@ | |||||
| // Copyright 2009,2010 The Go Authors. All rights reserved. | |||||
| // Copyright 2009 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // FreeBSD system calls. | |||||
| // DragonFly BSD system calls. | |||||
| // This file is compiled as ordinary Go code, | // This file is compiled as ordinary Go code, | ||||
| // but it is also input to mksyscall, | // but it is also input to mksyscall, | ||||
| // which parses the //sys lines and generates system call stubs. | // which parses the //sys lines and generates system call stubs. | ||||
| @@ -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 | ||||
| @@ -34,7 +35,7 @@ func nametomib(name string) (mib []_C_int, err error) { | |||||
| // NOTE(rsc): It seems strange to set the buffer to have | // NOTE(rsc): It seems strange to set the buffer to have | ||||
| // size CTL_MAXNAME+2 but use only CTL_MAXNAME | // size CTL_MAXNAME+2 but use only CTL_MAXNAME | ||||
| // as the size. I don't know why the +2 is here, but the | |||||
| // as the size. I don't know why the +2 is here, but the | |||||
| // kernel uses +2 for its own implementation of this function. | // kernel uses +2 for its own implementation of this function. | ||||
| // I am scared that if we don't include the +2 here, the kernel | // I am scared that if we don't include the +2 here, the kernel | ||||
| // will silently write 2 words farther than we specify | // will silently write 2 words farther than we specify | ||||
| @@ -56,31 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) { | |||||
| return buf[0 : n/siz], nil | return buf[0 : n/siz], nil | ||||
| } | } | ||||
| // ParseDirent parses up to max directory entries in buf, | |||||
| // appending the names to names. It returns the number | |||||
| // bytes consumed from buf, the number of entries added | |||||
| // to names, and the new names slice. | |||||
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||||
| origlen := len(buf) | |||||
| for max != 0 && len(buf) > 0 { | |||||
| dirent := (*Dirent)(unsafe.Pointer(&buf[0])) | |||||
| reclen := int(16+dirent.Namlen+1+7) & ^7 | |||||
| buf = buf[reclen:] | |||||
| if dirent.Fileno == 0 { // File absent in directory. | |||||
| continue | |||||
| } | |||||
| bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) | |||||
| var name = string(bytes[0:dirent.Namlen]) | |||||
| if name == "." || name == ".." { // Useless names | |||||
| continue | |||||
| } | |||||
| max-- | |||||
| count++ | |||||
| names = append(names, name) | |||||
| } | |||||
| return origlen - len(buf), count, names | |||||
| } | |||||
| //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) { | ||||
| @@ -101,6 +77,41 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { | |||||
| return extpwrite(fd, p, 0, offset) | return extpwrite(fd, p, 0, offset) | ||||
| } | } | ||||
| func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { | |||||
| var rsa RawSockaddrAny | |||||
| var len _Socklen = SizeofSockaddrAny | |||||
| nfd, err = accept4(fd, &rsa, &len, flags) | |||||
| if err != nil { | |||||
| return | |||||
| } | |||||
| if len > SizeofSockaddrAny { | |||||
| panic("RawSockaddrAny too small") | |||||
| } | |||||
| sa, err = anyToSockaddr(fd, &rsa) | |||||
| if err != nil { | |||||
| Close(nfd) | |||||
| nfd = 0 | |||||
| } | |||||
| 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 | ||||
| @@ -109,7 +120,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | ||||
| } | } | ||||
| r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | ||||
| use(unsafe.Pointer(_p0)) | |||||
| n = int(r0) | n = int(r0) | ||||
| if e1 != 0 { | if e1 != 0 { | ||||
| err = e1 | err = e1 | ||||
| @@ -117,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 | ||||
| */ | */ | ||||
| @@ -134,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) | ||||
| @@ -166,11 +285,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| //sys Mkdir(path string, mode uint32) (err error) | //sys Mkdir(path string, mode uint32) (err error) | ||||
| //sys Mkfifo(path string, mode uint32) (err error) | //sys Mkfifo(path string, mode uint32) (err error) | ||||
| //sys Mknod(path string, mode uint32, dev int) (err error) | //sys Mknod(path string, mode uint32, dev int) (err error) | ||||
| //sys Mlock(b []byte) (err error) | |||||
| //sys Mlockall(flags int) (err error) | |||||
| //sys Mprotect(b []byte, prot int) (err error) | |||||
| //sys Munlock(b []byte) (err error) | |||||
| //sys Munlockall() (err error) | |||||
| //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | ||||
| //sys Open(path string, mode int, perm uint32) (fd int, err error) | //sys Open(path string, mode int, perm uint32) (fd int, err error) | ||||
| //sys Pathconf(path string, name int) (val int, err error) | //sys Pathconf(path string, name int) (val int, err error) | ||||
| @@ -209,6 +323,8 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| //sys munmap(addr uintptr, length uintptr) (err error) | //sys munmap(addr uintptr, length uintptr) (err error) | ||||
| //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | ||||
| //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | ||||
| //sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) | |||||
| //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||||
| /* | /* | ||||
| * Unimplemented | * Unimplemented | ||||
| @@ -220,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 | ||||
| @@ -243,7 +358,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| // Add_profil | // Add_profil | ||||
| // Kdebug_trace | // Kdebug_trace | ||||
| // Sigreturn | // Sigreturn | ||||
| // Mmap | |||||
| // Atsocket | // Atsocket | ||||
| // Kqueue_from_portset_np | // Kqueue_from_portset_np | ||||
| // Kqueue_portset | // Kqueue_portset | ||||
| @@ -253,7 +367,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| // Searchfs | // Searchfs | ||||
| // Delete | // Delete | ||||
| // Copyfile | // Copyfile | ||||
| // Poll | |||||
| // Watchevent | // Watchevent | ||||
| // Waitevent | // Waitevent | ||||
| // Modwatch | // Modwatch | ||||
| @@ -388,7 +501,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| // Sendmsg_nocancel | // Sendmsg_nocancel | ||||
| // Recvfrom_nocancel | // Recvfrom_nocancel | ||||
| // Accept_nocancel | // Accept_nocancel | ||||
| // Msync_nocancel | |||||
| // Fcntl_nocancel | // Fcntl_nocancel | ||||
| // Select_nocancel | // Select_nocancel | ||||
| // Fsync_nocancel | // Fsync_nocancel | ||||
| @@ -400,7 +512,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| // Pread_nocancel | // Pread_nocancel | ||||
| // Pwrite_nocancel | // Pwrite_nocancel | ||||
| // Waitid_nocancel | // Waitid_nocancel | ||||
| // Poll_nocancel | |||||
| // Msgsnd_nocancel | // Msgsnd_nocancel | ||||
| // Msgrcv_nocancel | // Msgrcv_nocancel | ||||
| // Sem_wait_nocancel | // Sem_wait_nocancel | ||||
| @@ -11,21 +11,12 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -12,8 +12,36 @@ | |||||
| package unix | package unix | ||||
| import "unsafe" | |||||
| import ( | |||||
| "sync" | |||||
| "unsafe" | |||||
| ) | |||||
| const ( | |||||
| SYS_FSTAT_FREEBSD12 = 551 // { int fstat(int fd, _Out_ struct stat *sb); } | |||||
| SYS_FSTATAT_FREEBSD12 = 552 // { int fstatat(int fd, _In_z_ char *path, \ | |||||
| SYS_GETDIRENTRIES_FREEBSD12 = 554 // { ssize_t getdirentries(int fd, \ | |||||
| SYS_STATFS_FREEBSD12 = 555 // { int statfs(_In_z_ char *path, \ | |||||
| SYS_FSTATFS_FREEBSD12 = 556 // { int fstatfs(int fd, \ | |||||
| SYS_GETFSSTAT_FREEBSD12 = 557 // { int getfsstat( \ | |||||
| SYS_MKNODAT_FREEBSD12 = 559 // { int mknodat(int fd, _In_z_ char *path, \ | |||||
| ) | |||||
| // See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html. | |||||
| var ( | |||||
| osreldateOnce sync.Once | |||||
| osreldate uint32 | |||||
| ) | |||||
| // INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h | |||||
| const _ino64First = 1200031 | |||||
| func supportsABI(ver uint32) bool { | |||||
| osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") }) | |||||
| return osreldate >= ver | |||||
| } | |||||
| // 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,7 +60,7 @@ func nametomib(name string) (mib []_C_int, err error) { | |||||
| // NOTE(rsc): It seems strange to set the buffer to have | // NOTE(rsc): It seems strange to set the buffer to have | ||||
| // size CTL_MAXNAME+2 but use only CTL_MAXNAME | // size CTL_MAXNAME+2 but use only CTL_MAXNAME | ||||
| // as the size. I don't know why the +2 is here, but the | |||||
| // as the size. I don't know why the +2 is here, but the | |||||
| // kernel uses +2 for its own implementation of this function. | // kernel uses +2 for its own implementation of this function. | ||||
| // I am scared that if we don't include the +2 here, the kernel | // I am scared that if we don't include the +2 here, the kernel | ||||
| // will silently write 2 words farther than we specify | // will silently write 2 words farther than we specify | ||||
| @@ -54,42 +82,21 @@ func nametomib(name string) (mib []_C_int, err error) { | |||||
| return buf[0 : n/siz], nil | return buf[0 : n/siz], nil | ||||
| } | } | ||||
| // ParseDirent parses up to max directory entries in buf, | |||||
| // appending the names to names. It returns the number | |||||
| // bytes consumed from buf, the number of entries added | |||||
| // to names, and the new names slice. | |||||
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||||
| origlen := len(buf) | |||||
| for max != 0 && len(buf) > 0 { | |||||
| dirent := (*Dirent)(unsafe.Pointer(&buf[0])) | |||||
| if dirent.Reclen == 0 { | |||||
| buf = nil | |||||
| break | |||||
| } | |||||
| buf = buf[dirent.Reclen:] | |||||
| if dirent.Fileno == 0 { // File absent in directory. | |||||
| continue | |||||
| } | |||||
| bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) | |||||
| var name = string(bytes[0:dirent.Namlen]) | |||||
| if name == "." || name == ".." { // Useless names | |||||
| continue | |||||
| } | |||||
| max-- | |||||
| count++ | |||||
| names = append(names, name) | |||||
| } | |||||
| return origlen - len(buf), count, names | |||||
| func Pipe(p []int) (err error) { | |||||
| return Pipe2(p, 0) | |||||
| } | } | ||||
| //sysnb pipe() (r int, w int, err error) | |||||
| //sysnb pipe2(p *[2]_C_int, flags int) (err error) | |||||
| func Pipe(p []int) (err error) { | |||||
| func Pipe2(p []int, flags int) error { | |||||
| if len(p) != 2 { | if len(p) != 2 { | ||||
| return EINVAL | return EINVAL | ||||
| } | } | ||||
| p[0], p[1], err = pipe() | |||||
| return | |||||
| var pp [2]_C_int | |||||
| err := pipe2(&pp, flags) | |||||
| p[0] = int(pp[0]) | |||||
| p[1] = int(pp[1]) | |||||
| return err | |||||
| } | } | ||||
| func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { | func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { | ||||
| @@ -113,7 +120,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 | ||||
| @@ -121,252 +128,376 @@ 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 bufsize uintptr | |||||
| var ( | |||||
| _p0 unsafe.Pointer | |||||
| bufsize uintptr | |||||
| oldBuf []statfs_freebsd11_t | |||||
| needsConvert bool | |||||
| ) | |||||
| if len(buf) > 0 { | if len(buf) > 0 { | ||||
| _p0 = unsafe.Pointer(&buf[0]) | |||||
| bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | |||||
| if supportsABI(_ino64First) { | |||||
| _p0 = unsafe.Pointer(&buf[0]) | |||||
| bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | |||||
| } else { | |||||
| n := len(buf) | |||||
| oldBuf = make([]statfs_freebsd11_t, n) | |||||
| _p0 = unsafe.Pointer(&oldBuf[0]) | |||||
| bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n) | |||||
| needsConvert = true | |||||
| } | |||||
| } | |||||
| var sysno uintptr = SYS_GETFSSTAT | |||||
| if supportsABI(_ino64First) { | |||||
| sysno = SYS_GETFSSTAT_FREEBSD12 | |||||
| } | } | ||||
| r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | |||||
| use(unsafe.Pointer(_p0)) | |||||
| r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags)) | |||||
| n = int(r0) | n = int(r0) | ||||
| if e1 != 0 { | if e1 != 0 { | ||||
| err = e1 | err = e1 | ||||
| } | } | ||||
| if e1 == 0 && needsConvert { | |||||
| for i := range oldBuf { | |||||
| buf[i].convertFrom(&oldBuf[i]) | |||||
| } | |||||
| } | |||||
| return | return | ||||
| } | } | ||||
| // Derive extattr namespace and attribute name | |||||
| func xattrnamespace(fullattr string) (ns int, attr string, err error) { | |||||
| s := -1 | |||||
| for idx, val := range fullattr { | |||||
| if val == '.' { | |||||
| s = idx | |||||
| break | |||||
| } | |||||
| } | |||||
| func setattrlistTimes(path string, times []Timespec, flags int) error { | |||||
| // used on Darwin for UtimesNano | |||||
| return ENOSYS | |||||
| } | |||||
| if s == -1 { | |||||
| return -1, "", ENOATTR | |||||
| } | |||||
| //sys ioctl(fd int, req uint, arg uintptr) (err error) | |||||
| namespace := fullattr[0:s] | |||||
| attr = fullattr[s+1:] | |||||
| // ioctl itself should not be exposed directly, but additional get/set | |||||
| // functions for specific types are permissible. | |||||
| switch namespace { | |||||
| case "user": | |||||
| return EXTATTR_NAMESPACE_USER, attr, nil | |||||
| case "system": | |||||
| return EXTATTR_NAMESPACE_SYSTEM, attr, nil | |||||
| default: | |||||
| return -1, "", ENOATTR | |||||
| } | |||||
| // 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 initxattrdest(dest []byte, idx int) (d unsafe.Pointer) { | |||||
| if len(dest) > idx { | |||||
| return unsafe.Pointer(&dest[idx]) | |||||
| } else { | |||||
| return unsafe.Pointer(_zero) | |||||
| } | |||||
| func ioctlSetWinsize(fd int, req uint, value *Winsize) error { | |||||
| return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||||
| } | } | ||||
| // FreeBSD implements its own syscalls to handle extended attributes | |||||
| func ioctlSetTermios(fd int, req uint, value *Termios) error { | |||||
| return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||||
| } | |||||
| func Getxattr(file string, attr string, dest []byte) (sz int, err error) { | |||||
| d := initxattrdest(dest, 0) | |||||
| destsize := len(dest) | |||||
| // 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 | |||||
| } | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| if err != nil { | |||||
| return -1, err | |||||
| } | |||||
| func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||||
| var value Winsize | |||||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||||
| return &value, err | |||||
| } | |||||
| return ExtattrGetFile(file, nsid, a, uintptr(d), destsize) | |||||
| func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||||
| var value Termios | |||||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||||
| return &value, err | |||||
| } | } | ||||
| func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { | |||||
| d := initxattrdest(dest, 0) | |||||
| destsize := len(dest) | |||||
| 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 | |||||
| } | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| if err != nil { | |||||
| return -1, 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 | |||||
| } | } | ||||
| return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize) | |||||
| } | |||||
| 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 | |||||
| } | |||||
| func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) { | |||||
| d := initxattrdest(dest, 0) | |||||
| destsize := len(dest) | |||||
| 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 | |||||
| } | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| if err != nil { | |||||
| return -1, 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 ExtattrGetLink(link, nsid, a, uintptr(d), destsize) | |||||
| return nil | |||||
| } | } | ||||
| // flags are unused on FreeBSD | |||||
| func Stat(path string, st *Stat_t) (err error) { | |||||
| var oldStat stat_freebsd11_t | |||||
| if supportsABI(_ino64First) { | |||||
| return fstatat_freebsd12(AT_FDCWD, path, st, 0) | |||||
| } | |||||
| err = stat(path, &oldStat) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) { | |||||
| d := unsafe.Pointer(&data[0]) | |||||
| datasiz := len(data) | |||||
| st.convertFrom(&oldStat) | |||||
| return nil | |||||
| } | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| func Lstat(path string, st *Stat_t) (err error) { | |||||
| var oldStat stat_freebsd11_t | |||||
| if supportsABI(_ino64First) { | |||||
| return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW) | |||||
| } | |||||
| err = lstat(path, &oldStat) | |||||
| if err != nil { | if err != nil { | ||||
| return | |||||
| return err | |||||
| } | } | ||||
| _, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz) | |||||
| return | |||||
| st.convertFrom(&oldStat) | |||||
| return nil | |||||
| } | } | ||||
| func Setxattr(file string, attr string, data []byte, flags int) (err error) { | |||||
| d := unsafe.Pointer(&data[0]) | |||||
| datasiz := len(data) | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| func Fstat(fd int, st *Stat_t) (err error) { | |||||
| var oldStat stat_freebsd11_t | |||||
| if supportsABI(_ino64First) { | |||||
| return fstat_freebsd12(fd, st) | |||||
| } | |||||
| err = fstat(fd, &oldStat) | |||||
| if err != nil { | if err != nil { | ||||
| return | |||||
| return err | |||||
| } | } | ||||
| _, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz) | |||||
| return | |||||
| st.convertFrom(&oldStat) | |||||
| return nil | |||||
| } | } | ||||
| func Lsetxattr(link string, attr string, data []byte, flags int) (err error) { | |||||
| d := unsafe.Pointer(&data[0]) | |||||
| datasiz := len(data) | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) { | |||||
| var oldStat stat_freebsd11_t | |||||
| if supportsABI(_ino64First) { | |||||
| return fstatat_freebsd12(fd, path, st, flags) | |||||
| } | |||||
| err = fstatat(fd, path, &oldStat, flags) | |||||
| if err != nil { | if err != nil { | ||||
| return | |||||
| return err | |||||
| } | } | ||||
| _, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz) | |||||
| return | |||||
| st.convertFrom(&oldStat) | |||||
| return nil | |||||
| } | } | ||||
| func Removexattr(file string, attr string) (err error) { | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| func Statfs(path string, st *Statfs_t) (err error) { | |||||
| var oldStatfs statfs_freebsd11_t | |||||
| if supportsABI(_ino64First) { | |||||
| return statfs_freebsd12(path, st) | |||||
| } | |||||
| err = statfs(path, &oldStatfs) | |||||
| if err != nil { | if err != nil { | ||||
| return | |||||
| return err | |||||
| } | } | ||||
| err = ExtattrDeleteFile(file, nsid, a) | |||||
| return | |||||
| st.convertFrom(&oldStatfs) | |||||
| return nil | |||||
| } | } | ||||
| func Fremovexattr(fd int, attr string) (err error) { | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| func Fstatfs(fd int, st *Statfs_t) (err error) { | |||||
| var oldStatfs statfs_freebsd11_t | |||||
| if supportsABI(_ino64First) { | |||||
| return fstatfs_freebsd12(fd, st) | |||||
| } | |||||
| err = fstatfs(fd, &oldStatfs) | |||||
| if err != nil { | if err != nil { | ||||
| return | |||||
| return err | |||||
| } | } | ||||
| err = ExtattrDeleteFd(fd, nsid, a) | |||||
| return | |||||
| st.convertFrom(&oldStatfs) | |||||
| return nil | |||||
| } | } | ||||
| func Lremovexattr(link string, attr string) (err error) { | |||||
| nsid, a, err := xattrnamespace(attr) | |||||
| if err != nil { | |||||
| return | |||||
| func Getdents(fd int, buf []byte) (n int, err error) { | |||||
| return Getdirentries(fd, buf, nil) | |||||
| } | |||||
| func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { | |||||
| if supportsABI(_ino64First) { | |||||
| return getdirentries_freebsd12(fd, buf, basep) | |||||
| } | } | ||||
| err = ExtattrDeleteLink(link, nsid, a) | |||||
| // The old syscall entries are smaller than the new. Use 1/4 of the original | |||||
| // buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c). | |||||
| oldBufLen := roundup(len(buf)/4, _dirblksiz) | |||||
| oldBuf := make([]byte, oldBufLen) | |||||
| n, err = getdirentries(fd, oldBuf, basep) | |||||
| if err == nil && n > 0 { | |||||
| n = convertFromDirents11(buf, oldBuf[:n]) | |||||
| } | |||||
| return | 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 | |||||
| var e error | |||||
| 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 { | |||||
| e = nil | |||||
| continue | |||||
| } else if e != nil { | |||||
| return s, e | |||||
| } | |||||
| s += stmp | |||||
| destsiz -= s | |||||
| if destsiz < 0 { | |||||
| destsiz = 0 | |||||
| } | |||||
| d = initxattrdest(dest, s) | |||||
| func Mknod(path string, mode uint32, dev uint64) (err error) { | |||||
| var oldDev int | |||||
| if supportsABI(_ino64First) { | |||||
| return mknodat_freebsd12(AT_FDCWD, path, mode, dev) | |||||
| } | } | ||||
| oldDev = int(dev) | |||||
| return mknod(path, mode, oldDev) | |||||
| } | |||||
| return s, e | |||||
| func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) { | |||||
| var oldDev int | |||||
| if supportsABI(_ino64First) { | |||||
| return mknodat_freebsd12(fd, path, mode, dev) | |||||
| } | |||||
| oldDev = int(dev) | |||||
| return mknodat(fd, path, mode, oldDev) | |||||
| } | } | ||||
| func Flistxattr(fd int, dest []byte) (sz int, err error) { | |||||
| d := initxattrdest(dest, 0) | |||||
| destsiz := len(dest) | |||||
| // round x to the nearest multiple of y, larger or equal to x. | |||||
| // | |||||
| // from /usr/include/sys/param.h Macros for counting and rounding. | |||||
| // #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | |||||
| func roundup(x, y int) int { | |||||
| return ((x + y - 1) / y) * y | |||||
| } | |||||
| s := 0 | |||||
| var e error | |||||
| 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 { | |||||
| e = nil | |||||
| continue | |||||
| } else if e != nil { | |||||
| return s, e | |||||
| } | |||||
| func (s *Stat_t) convertFrom(old *stat_freebsd11_t) { | |||||
| *s = Stat_t{ | |||||
| Dev: uint64(old.Dev), | |||||
| Ino: uint64(old.Ino), | |||||
| Nlink: uint64(old.Nlink), | |||||
| Mode: old.Mode, | |||||
| Uid: old.Uid, | |||||
| Gid: old.Gid, | |||||
| Rdev: uint64(old.Rdev), | |||||
| Atim: old.Atim, | |||||
| Mtim: old.Mtim, | |||||
| Ctim: old.Ctim, | |||||
| Birthtim: old.Birthtim, | |||||
| Size: old.Size, | |||||
| Blocks: old.Blocks, | |||||
| Blksize: old.Blksize, | |||||
| Flags: old.Flags, | |||||
| Gen: uint64(old.Gen), | |||||
| } | |||||
| } | |||||
| s += stmp | |||||
| destsiz -= s | |||||
| if destsiz < 0 { | |||||
| destsiz = 0 | |||||
| } | |||||
| d = initxattrdest(dest, s) | |||||
| func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) { | |||||
| *s = Statfs_t{ | |||||
| Version: _statfsVersion, | |||||
| Type: old.Type, | |||||
| Flags: old.Flags, | |||||
| Bsize: old.Bsize, | |||||
| Iosize: old.Iosize, | |||||
| Blocks: old.Blocks, | |||||
| Bfree: old.Bfree, | |||||
| Bavail: old.Bavail, | |||||
| Files: old.Files, | |||||
| Ffree: old.Ffree, | |||||
| Syncwrites: old.Syncwrites, | |||||
| Asyncwrites: old.Asyncwrites, | |||||
| Syncreads: old.Syncreads, | |||||
| Asyncreads: old.Asyncreads, | |||||
| // Spare | |||||
| Namemax: old.Namemax, | |||||
| Owner: old.Owner, | |||||
| Fsid: old.Fsid, | |||||
| // Charspare | |||||
| // Fstypename | |||||
| // Mntfromname | |||||
| // Mntonname | |||||
| } | } | ||||
| return s, e | |||||
| sl := old.Fstypename[:] | |||||
| n := clen(*(*[]byte)(unsafe.Pointer(&sl))) | |||||
| copy(s.Fstypename[:], old.Fstypename[:n]) | |||||
| sl = old.Mntfromname[:] | |||||
| n = clen(*(*[]byte)(unsafe.Pointer(&sl))) | |||||
| copy(s.Mntfromname[:], old.Mntfromname[:n]) | |||||
| sl = old.Mntonname[:] | |||||
| n = clen(*(*[]byte)(unsafe.Pointer(&sl))) | |||||
| copy(s.Mntonname[:], old.Mntonname[:n]) | |||||
| } | } | ||||
| func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| d := initxattrdest(dest, 0) | |||||
| destsiz := len(dest) | |||||
| func convertFromDirents11(buf []byte, old []byte) int { | |||||
| const ( | |||||
| fixedSize = int(unsafe.Offsetof(Dirent{}.Name)) | |||||
| oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name)) | |||||
| ) | |||||
| dstPos := 0 | |||||
| srcPos := 0 | |||||
| for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) { | |||||
| dstDirent := (*Dirent)(unsafe.Pointer(&buf[dstPos])) | |||||
| srcDirent := (*dirent_freebsd11)(unsafe.Pointer(&old[srcPos])) | |||||
| s := 0 | |||||
| var e error | |||||
| 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 { | |||||
| e = nil | |||||
| continue | |||||
| } else if e != nil { | |||||
| return s, e | |||||
| reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8) | |||||
| if dstPos+reclen > len(buf) { | |||||
| break | |||||
| } | } | ||||
| s += stmp | |||||
| destsiz -= s | |||||
| if destsiz < 0 { | |||||
| destsiz = 0 | |||||
| dstDirent.Fileno = uint64(srcDirent.Fileno) | |||||
| dstDirent.Off = 0 | |||||
| dstDirent.Reclen = uint16(reclen) | |||||
| dstDirent.Type = srcDirent.Type | |||||
| dstDirent.Pad0 = 0 | |||||
| dstDirent.Namlen = uint16(srcDirent.Namlen) | |||||
| dstDirent.Pad1 = 0 | |||||
| copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen]) | |||||
| padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen] | |||||
| for i := range padding { | |||||
| padding[i] = 0 | |||||
| } | } | ||||
| d = initxattrdest(dest, s) | |||||
| dstPos += int(dstDirent.Reclen) | |||||
| srcPos += int(srcDirent.Reclen) | |||||
| } | } | ||||
| return s, e | |||||
| return dstPos | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -374,6 +505,9 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| */ | */ | ||||
| //sys Access(path string, mode uint32) (err error) | //sys Access(path string, mode uint32) (err error) | ||||
| //sys Adjtime(delta *Timeval, olddelta *Timeval) (err error) | //sys Adjtime(delta *Timeval, olddelta *Timeval) (err error) | ||||
| //sys CapEnter() (err error) | |||||
| //sys capRightsGet(version int, fd int, rightsp *CapRights) (err error) = SYS___CAP_RIGHTS_GET | |||||
| //sys capRightsLimit(fd int, rightsp *CapRights) (err error) | |||||
| //sys Chdir(path string) (err error) | //sys Chdir(path string) (err error) | ||||
| //sys Chflags(path string, flags int) (err error) | //sys Chflags(path string, flags int) (err error) | ||||
| //sys Chmod(path string, mode uint32) (err error) | //sys Chmod(path string, mode uint32) (err error) | ||||
| @@ -396,17 +530,25 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| //sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) | //sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) | ||||
| //sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) | //sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) | ||||
| //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE | //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE | ||||
| //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 Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) | |||||
| //sys Flock(fd int, how int) (err error) | //sys Flock(fd int, how int) (err error) | ||||
| //sys Fpathconf(fd int, name int) (val int, err error) | //sys Fpathconf(fd int, name int) (val int, err error) | ||||
| //sys Fstat(fd int, stat *Stat_t) (err error) | |||||
| //sys Fstatfs(fd int, stat *Statfs_t) (err error) | |||||
| //sys fstat(fd int, stat *stat_freebsd11_t) (err error) | |||||
| //sys fstat_freebsd12(fd int, stat *Stat_t) (err error) | |||||
| //sys fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) | |||||
| //sys fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) | |||||
| //sys fstatfs(fd int, stat *statfs_freebsd11_t) (err error) | |||||
| //sys fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) | |||||
| //sys Fsync(fd int) (err error) | //sys Fsync(fd int) (err error) | ||||
| //sys Ftruncate(fd int, length int64) (err error) | //sys Ftruncate(fd int, length int64) (err error) | ||||
| //sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) | |||||
| //sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) | |||||
| //sys getdirentries_freebsd12(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) | ||||
| //sysnb Geteuid() (uid int) | //sysnb Geteuid() (uid int) | ||||
| @@ -426,24 +568,26 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| //sys Kqueue() (fd int, err error) | //sys Kqueue() (fd int, err error) | ||||
| //sys Lchown(path string, uid int, gid int) (err error) | //sys Lchown(path string, uid int, gid int) (err error) | ||||
| //sys Link(path string, link string) (err error) | //sys Link(path string, link string) (err error) | ||||
| //sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) | |||||
| //sys Listen(s int, backlog int) (err error) | //sys Listen(s int, backlog int) (err error) | ||||
| //sys Lstat(path string, stat *Stat_t) (err error) | |||||
| //sys lstat(path string, stat *stat_freebsd11_t) (err error) | |||||
| //sys Mkdir(path string, mode uint32) (err error) | //sys Mkdir(path string, mode uint32) (err error) | ||||
| //sys Mkdirat(dirfd int, path string, mode uint32) (err error) | |||||
| //sys Mkfifo(path string, mode uint32) (err error) | //sys Mkfifo(path string, mode uint32) (err error) | ||||
| //sys Mknod(path string, mode uint32, dev int) (err error) | |||||
| //sys Mlock(b []byte) (err error) | |||||
| //sys Mlockall(flags int) (err error) | |||||
| //sys Mprotect(b []byte, prot int) (err error) | |||||
| //sys Munlock(b []byte) (err error) | |||||
| //sys Munlockall() (err error) | |||||
| //sys mknod(path string, mode uint32, dev int) (err error) | |||||
| //sys mknodat(fd int, path string, mode uint32, dev int) (err error) | |||||
| //sys mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) | |||||
| //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | ||||
| //sys Open(path string, mode int, perm uint32) (fd int, err error) | //sys Open(path string, mode int, perm uint32) (fd int, err error) | ||||
| //sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) | |||||
| //sys Pathconf(path string, name int) (val int, err error) | //sys Pathconf(path string, name int) (val int, err error) | ||||
| //sys Pread(fd int, p []byte, offset int64) (n int, err error) | //sys Pread(fd int, p []byte, offset int64) (n int, err error) | ||||
| //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) | //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) | ||||
| //sys read(fd int, p []byte) (n int, err error) | //sys read(fd int, p []byte) (n int, err error) | ||||
| //sys Readlink(path string, buf []byte) (n int, err error) | //sys Readlink(path string, buf []byte) (n int, err error) | ||||
| //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) | |||||
| //sys Rename(from string, to string) (err error) | //sys Rename(from string, to string) (err error) | ||||
| //sys Renameat(fromfd int, from string, tofd int, to string) (err error) | |||||
| //sys Revoke(path string) (err error) | //sys Revoke(path 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) = SYS_LSEEK | //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK | ||||
| @@ -462,14 +606,17 @@ func Llistxattr(link string, dest []byte) (sz 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) | ||||
| //sys Stat(path string, stat *Stat_t) (err error) | |||||
| //sys Statfs(path string, stat *Statfs_t) (err error) | |||||
| //sys stat(path string, stat *stat_freebsd11_t) (err error) | |||||
| //sys statfs(path string, stat *statfs_freebsd11_t) (err error) | |||||
| //sys statfs_freebsd12(path string, stat *Statfs_t) (err error) | |||||
| //sys Symlink(path string, link string) (err error) | //sys Symlink(path string, link string) (err error) | ||||
| //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) | |||||
| //sys Sync() (err error) | //sys Sync() (err error) | ||||
| //sys Truncate(path string, length int64) (err error) | //sys Truncate(path string, length int64) (err error) | ||||
| //sys Umask(newmask int) (oldmask int) | //sys Umask(newmask int) (oldmask int) | ||||
| //sys Undelete(path string) (err error) | //sys Undelete(path string) (err error) | ||||
| //sys Unlink(path string) (err error) | //sys Unlink(path string) (err error) | ||||
| //sys Unlinkat(dirfd int, path string, flags int) (err error) | |||||
| //sys Unmount(path string, flags int) (err error) | //sys Unmount(path string, flags int) (err error) | ||||
| //sys write(fd int, p []byte) (n int, err error) | //sys write(fd int, p []byte) (n int, err error) | ||||
| //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) | ||||
| @@ -477,6 +624,7 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | ||||
| //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | ||||
| //sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) | //sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) | ||||
| //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||||
| /* | /* | ||||
| * Unimplemented | * Unimplemented | ||||
| @@ -510,30 +658,19 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| // Add_profil | // Add_profil | ||||
| // Kdebug_trace | // Kdebug_trace | ||||
| // Sigreturn | // Sigreturn | ||||
| // Mmap | |||||
| // Mlock | |||||
| // Munlock | |||||
| // Atsocket | // Atsocket | ||||
| // Kqueue_from_portset_np | // Kqueue_from_portset_np | ||||
| // Kqueue_portset | // Kqueue_portset | ||||
| // Getattrlist | // Getattrlist | ||||
| // Setattrlist | // Setattrlist | ||||
| // Getdents | |||||
| // Getdirentriesattr | // Getdirentriesattr | ||||
| // Searchfs | // Searchfs | ||||
| // Delete | // Delete | ||||
| // Copyfile | // Copyfile | ||||
| // Poll | |||||
| // Watchevent | // Watchevent | ||||
| // Waitevent | // Waitevent | ||||
| // Modwatch | // Modwatch | ||||
| // Getxattr | |||||
| // Fgetxattr | |||||
| // Setxattr | |||||
| // Fsetxattr | |||||
| // Removexattr | |||||
| // Fremovexattr | |||||
| // Listxattr | |||||
| // Flistxattr | |||||
| // Fsctl | // Fsctl | ||||
| // Initgroups | // Initgroups | ||||
| // Posix_spawn | // Posix_spawn | ||||
| @@ -605,8 +742,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| // Lio_listio | // Lio_listio | ||||
| // __pthread_cond_wait | // __pthread_cond_wait | ||||
| // Iopolicysys | // Iopolicysys | ||||
| // Mlockall | |||||
| // Munlockall | |||||
| // __pthread_kill | // __pthread_kill | ||||
| // __pthread_sigmask | // __pthread_sigmask | ||||
| // __sigwait | // __sigwait | ||||
| @@ -659,7 +794,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||||
| // Sendmsg_nocancel | // Sendmsg_nocancel | ||||
| // Recvfrom_nocancel | // Recvfrom_nocancel | ||||
| // Accept_nocancel | // Accept_nocancel | ||||
| // Msync_nocancel | |||||
| // Fcntl_nocancel | // Fcntl_nocancel | ||||
| // Select_nocancel | // Select_nocancel | ||||
| // Fsync_nocancel | // Fsync_nocancel | ||||
| @@ -11,21 +11,12 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int32(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: int32(sec), Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int32(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: int32(sec), Usec: int32(usec)} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -11,21 +11,12 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -11,21 +11,12 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return ts.Sec*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = nsec / 1e9 | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: int32(usec)} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -10,25 +10,15 @@ | |||||
| package unix | package unix | ||||
| import ( | import ( | ||||
| "syscall" | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int32(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: int32(sec), Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Sec = int32(nsec / 1e9) | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: int32(sec), Usec: int32(usec)} | |||||
| } | } | ||||
| //sysnb pipe(p *[2]_C_int) (err error) | //sysnb pipe(p *[2]_C_int) (err error) | ||||
| @@ -60,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 | ||||
| @@ -86,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) { | ||||
| @@ -165,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 { | ||||
| @@ -177,17 +166,17 @@ 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 | ||||
| // the 6-argument calls like sendto and recvfrom. Instead the | |||||
| // the 6-argument calls like sendto and recvfrom. Instead the | |||||
| // arguments to the underlying system call are the number below | // arguments to the underlying system call are the number below | ||||
| // and a pointer to an array of uintptr. We hide the pointer in the | |||||
| // and a pointer to an array of uintptr. We hide the pointer in the | |||||
| // socketcall assembly to avoid allocation on every system call. | // socketcall assembly to avoid allocation on every system call. | ||||
| const ( | const ( | ||||
| @@ -214,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 { | ||||
| @@ -6,13 +6,13 @@ | |||||
| package unix | package unix | ||||
| import "syscall" | |||||
| //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) | ||||
| @@ -30,7 +30,15 @@ import "syscall" | |||||
| //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) | ||||
| @@ -41,10 +49,16 @@ import "syscall" | |||||
| //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) | ||||
| @@ -63,8 +77,7 @@ import "syscall" | |||||
| //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) | ||||
| //go:noescape | |||||
| func gettimeofday(tv *Timeval) (err syscall.Errno) | |||||
| //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) | ||||
| @@ -74,8 +87,6 @@ func Gettimeofday(tv *Timeval) (err error) { | |||||
| return nil | return nil | ||||
| } | } | ||||
| func Getpagesize() int { return 4096 } | |||||
| func Time(t *Time_t) (tt Time_t, err error) { | func Time(t *Time_t) (tt Time_t, err error) { | ||||
| var tv Timeval | var tv Timeval | ||||
| errno := gettimeofday(&tv) | errno := gettimeofday(&tv) | ||||
| @@ -89,20 +100,14 @@ 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 TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Sec = nsec / 1e9 | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| //sysnb pipe(p *[2]_C_int) (err error) | //sysnb pipe(p *[2]_C_int) (err error) | ||||
| @@ -155,3 +160,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||||
| } | } | ||||
| return poll(&fds[0], len(fds), timeout) | return poll(&fds[0], len(fds), timeout) | ||||
| } | } | ||||
| //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) | |||||
| func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { | |||||
| cmdlineLen := len(cmdline) | |||||
| if cmdlineLen > 0 { | |||||
| // Account for the additional NULL byte added by | |||||
| // BytePtrFromString in kexecFileLoad. The kexec_file_load | |||||
| // syscall expects a NULL-terminated string. | |||||
| cmdlineLen++ | |||||
| } | |||||
| return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) | |||||
| } | |||||
| @@ -0,0 +1,13 @@ | |||||
| // Copyright 2016 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build amd64,linux | |||||
| // +build !gccgo | |||||
| package unix | |||||
| import "syscall" | |||||
| //go:noescape | |||||
| func gettimeofday(tv *Timeval) (err syscall.Errno) | |||||
| @@ -11,21 +11,12 @@ import ( | |||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int32(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: int32(sec), Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Sec = int32(nsec / 1e9) | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: int32(sec), Usec: int32(usec)} | |||||
| } | } | ||||
| func Pipe(p []int) (err error) { | func Pipe(p []int) (err error) { | ||||
| @@ -84,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 | ||||
| @@ -94,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 | ||||
| @@ -105,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 | ||||
| @@ -131,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,9 +6,17 @@ | |||||
| package unix | package unix | ||||
| const _SYS_dup = SYS_DUP3 | |||||
| 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,7 +31,15 @@ const _SYS_dup = SYS_DUP3 | |||||
| //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) = SYS_PSELECT6 | |||||
| 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) | ||||
| @@ -50,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) | ||||
| @@ -68,23 +89,26 @@ func Lstat(path string, stat *Stat_t) (err error) { | |||||
| //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) | ||||
| func Getpagesize() int { return 65536 } | |||||
| //sysnb Gettimeofday(tv *Timeval) (err error) | //sysnb Gettimeofday(tv *Timeval) (err error) | ||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Sec = nsec / 1e9 | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| return | |||||
| func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) { | |||||
| if tv == nil { | |||||
| return utimensat(dirfd, path, nil, 0) | |||||
| } | |||||
| ts := []Timespec{ | |||||
| NsecToTimespec(TimevalToNsec(tv[0])), | |||||
| NsecToTimespec(TimevalToNsec(tv[1])), | |||||
| } | |||||
| return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) | |||||
| } | } | ||||
| func Time(t *Time_t) (Time_t, error) { | func Time(t *Time_t) (Time_t, error) { | ||||
| @@ -107,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 | ||||
| @@ -155,30 +191,11 @@ func Dup2(oldfd int, newfd int) (err error) { | |||||
| return Dup3(oldfd, newfd, 0) | return Dup3(oldfd, newfd, 0) | ||||
| } | } | ||||
| func Pause() (err error) { | |||||
| _, _, e1 := Syscall6(SYS_PPOLL, 0, 0, 0, 0, 0, 0) | |||||
| if e1 != 0 { | |||||
| err = errnoErr(e1) | |||||
| } | |||||
| return | |||||
| func Pause() error { | |||||
| _, err := ppoll(nil, 0, nil, nil) | |||||
| return err | |||||
| } | } | ||||
| // 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 { | ||||
| @@ -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 | |||||
| } | |||||
| @@ -7,15 +7,12 @@ | |||||
| package unix | package unix | ||||
| // Linux introduced getdents64 syscall for N64 ABI only in 3.10 | |||||
| // (May 21 2013, rev dec33abaafc89bcbd78f85fad0513170415a26d5), | |||||
| // to support older kernels, we have to use getdents for mips64. | |||||
| // Also note that struct dirent is different for these two. | |||||
| // Lookup linux_dirent{,64} in kernel source code for details. | |||||
| const _SYS_getdents = SYS_GETDENTS | |||||
| //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) | ||||
| @@ -29,7 +26,15 @@ const _SYS_getdents = SYS_GETDENTS | |||||
| //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) = SYS_PSELECT6 | |||||
| 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) | ||||
| @@ -43,6 +48,7 @@ const _SYS_getdents = SYS_GETDENTS | |||||
| //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,8 +67,7 @@ const _SYS_getdents = SYS_GETDENTS | |||||
| //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) | ||||
| func Getpagesize() int { return 65536 } | |||||
| //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) { | ||||
| @@ -78,20 +83,14 @@ 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 TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Sec = nsec / 1e9 | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| func Pipe(p []int) (err error) { | func Pipe(p []int) (err error) { | ||||
| @@ -189,9 +188,9 @@ func fillStat_t(s *Stat_t, st *stat_t) { | |||||
| s.Blocks = st.Blocks | s.Blocks = st.Blocks | ||||
| } | } | ||||
| func (r *PtraceRegs) PC() uint64 { return r.Regs[64] } | |||||
| func (r *PtraceRegs) PC() uint64 { return r.Epc } | |||||
| func (r *PtraceRegs) SetPC(pc uint64) { r.Regs[64] = pc } | |||||
| func (r *PtraceRegs) SetPC(pc uint64) { r.Epc = pc } | |||||
| func (iov *Iovec) SetLen(length int) { | func (iov *Iovec) SetLen(length int) { | ||||
| iov.Len = uint64(length) | iov.Len = uint64(length) | ||||
| @@ -0,0 +1,233 @@ | |||||
| // Copyright 2016 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build linux | |||||
| // +build mips mipsle | |||||
| package unix | |||||
| import ( | |||||
| "syscall" | |||||
| "unsafe" | |||||
| ) | |||||
| 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) | |||||
| //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 Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 | |||||
| //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 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 Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT | |||||
| //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 | |||||
| //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 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 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 Ustat(dev int, ubuf *Ustat_t) (err error) | |||||
| //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) | |||||
| //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) | |||||
| //sys 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) | |||||
| //sysnb InotifyInit() (fd int, err error) | |||||
| //sys Ioperm(from int, num int, on 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 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 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 Pause() (err error) | |||||
| func Fstatfs(fd int, buf *Statfs_t) (err error) { | |||||
| _, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) | |||||
| if e != 0 { | |||||
| err = errnoErr(e) | |||||
| } | |||||
| return | |||||
| } | |||||
| func Statfs(path string, buf *Statfs_t) (err error) { | |||||
| p, err := BytePtrFromString(path) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| _, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(p)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) | |||||
| if e != 0 { | |||||
| err = errnoErr(e) | |||||
| } | |||||
| return | |||||
| } | |||||
| func Seek(fd int, offset int64, whence int) (off int64, err error) { | |||||
| _, _, e := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offset>>32), uintptr(offset), uintptr(unsafe.Pointer(&off)), uintptr(whence), 0) | |||||
| if e != 0 { | |||||
| err = errnoErr(e) | |||||
| } | |||||
| return | |||||
| } | |||||
| 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)} | |||||
| } | |||||
| //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 | |||||
| } | |||||
| //sysnb pipe() (p1 int, p2 int, err error) | |||||
| func Pipe(p []int) (err error) { | |||||
| if len(p) != 2 { | |||||
| return EINVAL | |||||
| } | |||||
| p[0], p[1], err = pipe() | |||||
| return | |||||
| } | |||||
| //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) | |||||
| func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { | |||||
| page := uintptr(offset / 4096) | |||||
| if offset != int64(page)*4096 { | |||||
| return 0, EINVAL | |||||
| } | |||||
| return mmap2(addr, length, prot, flags, fd, page) | |||||
| } | |||||
| const rlimInf32 = ^uint32(0) | |||||
| const rlimInf64 = ^uint64(0) | |||||
| type rlimit32 struct { | |||||
| Cur uint32 | |||||
| Max uint32 | |||||
| } | |||||
| //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT | |||||
| func Getrlimit(resource int, rlim *Rlimit) (err error) { | |||||
| err = prlimit(0, resource, nil, rlim) | |||||
| if err != ENOSYS { | |||||
| return err | |||||
| } | |||||
| rl := rlimit32{} | |||||
| err = getrlimit(resource, &rl) | |||||
| if err != nil { | |||||
| return | |||||
| } | |||||
| if rl.Cur == rlimInf32 { | |||||
| rlim.Cur = rlimInf64 | |||||
| } else { | |||||
| rlim.Cur = uint64(rl.Cur) | |||||
| } | |||||
| if rl.Max == rlimInf32 { | |||||
| rlim.Max = rlimInf64 | |||||
| } else { | |||||
| rlim.Max = uint64(rl.Max) | |||||
| } | |||||
| return | |||||
| } | |||||
| //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT | |||||
| func Setrlimit(resource int, rlim *Rlimit) (err error) { | |||||
| err = prlimit(0, resource, rlim, nil) | |||||
| if err != ENOSYS { | |||||
| return err | |||||
| } | |||||
| rl := rlimit32{} | |||||
| if rlim.Cur == rlimInf64 { | |||||
| rl.Cur = rlimInf32 | |||||
| } else if rlim.Cur < uint64(rlimInf32) { | |||||
| rl.Cur = uint32(rlim.Cur) | |||||
| } else { | |||||
| return EINVAL | |||||
| } | |||||
| if rlim.Max == rlimInf64 { | |||||
| rl.Max = rlimInf32 | |||||
| } else if rlim.Max < uint64(rlimInf32) { | |||||
| rl.Max = uint32(rlim.Max) | |||||
| } else { | |||||
| return EINVAL | |||||
| } | |||||
| return setrlimit(resource, &rl) | |||||
| } | |||||
| func (r *PtraceRegs) PC() uint64 { return r.Epc } | |||||
| func (r *PtraceRegs) SetPC(pc uint64) { r.Epc = pc } | |||||
| 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) | |||||
| } | |||||
| //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) | |||||
| } | |||||
| @@ -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) | ||||
| @@ -28,7 +31,7 @@ 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) | |||||
| //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT | |||||
| //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) | ||||
| @@ -41,8 +44,8 @@ package unix | |||||
| //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) | //sys Stat(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_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,26 +64,18 @@ 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) | ||||
| func Getpagesize() int { return 65536 } | |||||
| //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 TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Sec = nsec / 1e9 | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| func (r *PtraceRegs) PC() uint64 { return r.Nip } | func (r *PtraceRegs) PC() uint64 { return r.Nip } | ||||
| @@ -133,3 +128,24 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||||
| } | } | ||||
| return poll(&fds[0], len(fds), timeout) | return poll(&fds[0], len(fds), timeout) | ||||
| } | } | ||||
| //sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2 | |||||
| func SyncFileRange(fd int, off int64, n int64, flags int) error { | |||||
| // The sync_file_range and sync_file_range2 syscalls differ only in the | |||||
| // order of their arguments. | |||||
| return syncFileRange2(fd, flags, off, n) | |||||
| } | |||||
| //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) | |||||
| func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { | |||||
| cmdlineLen := len(cmdline) | |||||
| if cmdlineLen > 0 { | |||||
| // Account for the additional NULL byte added by | |||||
| // BytePtrFromString in kexecFileLoad. The kexec_file_load | |||||
| // syscall expects a NULL-terminated string. | |||||
| cmdlineLen++ | |||||
| } | |||||
| return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) | |||||
| } | |||||
| @@ -0,0 +1,209 @@ | |||||
| // 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) | |||||
| } | |||||
| @@ -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,11 +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) | ||||
| func Getpagesize() int { return 4096 } | |||||
| //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) { | ||||
| @@ -63,20 +65,14 @@ 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 TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Sec = nsec / 1e9 | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| //sysnb pipe2(p *[2]_C_int, flags int) (err error) | //sysnb pipe2(p *[2]_C_int, flags int) (err error) | ||||
| @@ -132,7 +128,6 @@ func (cmsg *Cmsghdr) SetLen(length int) { | |||||
| 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) { | ||||
| mmap_args := [6]uintptr{addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)} | mmap_args := [6]uintptr{addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)} | ||||
| r0, _, e1 := Syscall(SYS_MMAP, uintptr(unsafe.Pointer(&mmap_args[0])), 0, 0) | r0, _, e1 := Syscall(SYS_MMAP, uintptr(unsafe.Pointer(&mmap_args[0])), 0, 0) | ||||
| use(unsafe.Pointer(&mmap_args[0])) | |||||
| xaddr = uintptr(r0) | xaddr = uintptr(r0) | ||||
| if e1 != 0 { | if e1 != 0 { | ||||
| err = errnoErr(e1) | err = errnoErr(e1) | ||||
| @@ -327,3 +322,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||||
| } | } | ||||
| return poll(&fds[0], len(fds), timeout) | return poll(&fds[0], len(fds), timeout) | ||||
| } | } | ||||
| //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) | |||||
| func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { | |||||
| cmdlineLen := len(cmdline) | |||||
| if cmdlineLen > 0 { | |||||
| // Account for the additional NULL byte added by | |||||
| // BytePtrFromString in kexecFileLoad. The kexec_file_load | |||||
| // syscall expects a NULL-terminated string. | |||||
| cmdlineLen++ | |||||
| } | |||||
| return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) | |||||
| } | |||||
| @@ -0,0 +1,146 @@ | |||||
| // Copyright 2009 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build sparc64,linux | |||||
| package unix | |||||
| //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 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) = SYS_FSTATAT64 | |||||
| //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) | |||||
| //sysnb InotifyInit() (fd int, err error) | |||||
| //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) = 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 | |||||
| //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | |||||
| //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) | |||||
| //sys Stat(path string, stat *Stat_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 Truncate(path string, length int64) (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 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) | |||||
| func Ioperm(from int, num int, on int) (err error) { | |||||
| return ENOSYS | |||||
| } | |||||
| func Iopl(level int) (err error) { | |||||
| return ENOSYS | |||||
| } | |||||
| //sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) | |||||
| //sysnb Gettimeofday(tv *Timeval) (err error) | |||||
| func Time(t *Time_t) (tt Time_t, err 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 | |||||
| } | |||||
| //sys Utime(path string, buf *Utimbuf) (err error) | |||||
| //sys utimes(path string, times *[2]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: int32(usec)} | |||||
| } | |||||
| func (r *PtraceRegs) PC() uint64 { return r.Tpc } | |||||
| func (r *PtraceRegs) SetPC(pc uint64) { r.Tpc = 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) | |||||
| } | |||||
| //sysnb pipe(p *[2]_C_int) (err error) | |||||
| func Pipe(p []int) (err error) { | |||||
| if len(p) != 2 { | |||||
| return EINVAL | |||||
| } | |||||
| var pp [2]_C_int | |||||
| err = pipe(&pp) | |||||
| p[0] = int(pp[0]) | |||||
| p[1] = int(pp[1]) | |||||
| return | |||||
| } | |||||
| //sysnb pipe2(p *[2]_C_int, flags int) (err error) | |||||
| func Pipe2(p []int, flags int) (err error) { | |||||
| if len(p) != 2 { | |||||
| return EINVAL | |||||
| } | |||||
| var pp [2]_C_int | |||||
| err = pipe2(&pp, flags) | |||||
| p[0] = int(pp[0]) | |||||
| p[1] = int(pp[1]) | |||||
| return | |||||
| } | |||||
| //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) | |||||
| } | |||||
| @@ -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) { | |||||
| } | } | ||||
| 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,32 +93,21 @@ func nametomib(name string) (mib []_C_int, err error) { | |||||
| return mib, nil | return mib, nil | ||||
| } | } | ||||
| // ParseDirent parses up to max directory entries in buf, | |||||
| // appending the names to names. It returns the number | |||||
| // bytes consumed from buf, the number of entries added | |||||
| // to names, and the new names slice. | |||||
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||||
| origlen := len(buf) | |||||
| for max != 0 && len(buf) > 0 { | |||||
| dirent := (*Dirent)(unsafe.Pointer(&buf[0])) | |||||
| if dirent.Reclen == 0 { | |||||
| buf = nil | |||||
| break | |||||
| } | |||||
| buf = buf[dirent.Reclen:] | |||||
| if dirent.Fileno == 0 { // File absent in directory. | |||||
| continue | |||||
| } | |||||
| bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) | |||||
| var name = string(bytes[0:dirent.Namlen]) | |||||
| if name == "." || name == ".." { // Useless names | |||||
| continue | |||||
| } | |||||
| max-- | |||||
| count++ | |||||
| names = append(names, name) | |||||
| func SysctlClockinfo(name string) (*Clockinfo, error) { | |||||
| mib, err := sysctlmib(name) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| n := uintptr(SizeofClockinfo) | |||||
| var ci Clockinfo | |||||
| if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil { | |||||
| return nil, err | |||||
| } | |||||
| if n != SizeofClockinfo { | |||||
| return nil, EIO | |||||
| } | } | ||||
| return origlen - len(buf), count, names | |||||
| return &ci, nil | |||||
| } | } | ||||
| //sysnb pipe() (fd1 int, fd2 int, err error) | //sysnb pipe() (fd1 int, fd2 int, err error) | ||||
| @@ -135,11 +124,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 | ||||
| */ | */ | ||||
| @@ -154,13 +250,29 @@ 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 ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) | |||||
| //sys ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) | |||||
| //sys ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) | |||||
| //sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) | |||||
| //sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) | |||||
| //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) | ||||
| @@ -186,11 +298,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e | |||||
| //sys Mkdir(path string, mode uint32) (err error) | //sys Mkdir(path string, mode uint32) (err error) | ||||
| //sys Mkfifo(path string, mode uint32) (err error) | //sys Mkfifo(path string, mode uint32) (err error) | ||||
| //sys Mknod(path string, mode uint32, dev int) (err error) | //sys Mknod(path string, mode uint32, dev int) (err error) | ||||
| //sys Mlock(b []byte) (err error) | |||||
| //sys Mlockall(flags int) (err error) | |||||
| //sys Mprotect(b []byte, prot int) (err error) | |||||
| //sys Munlock(b []byte) (err error) | |||||
| //sys Munlockall() (err error) | |||||
| //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | ||||
| //sys Open(path string, mode int, perm uint32) (fd int, err error) | //sys Open(path string, mode int, perm uint32) (fd int, err error) | ||||
| //sys Pathconf(path string, name int) (val int, err error) | //sys Pathconf(path string, name int) (val int, err error) | ||||
| @@ -226,6 +333,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e | |||||
| //sys munmap(addr uintptr, length uintptr) (err error) | //sys munmap(addr uintptr, length uintptr) (err error) | ||||
| //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | ||||
| //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | ||||
| //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||||
| /* | /* | ||||
| * Unimplemented | * Unimplemented | ||||
| @@ -245,7 +353,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 | ||||
| @@ -404,7 +511,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 | ||||
| @@ -442,7 +548,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e | |||||
| // ntp_adjtime | // ntp_adjtime | ||||
| // pmc_control | // pmc_control | ||||
| // pmc_get_info | // pmc_get_info | ||||
| // poll | |||||
| // pollts | // pollts | ||||
| // preadv | // preadv | ||||
| // profil | // profil | ||||
| @@ -6,21 +6,12 @@ | |||||
| package unix | package unix | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int64(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: int32(usec)} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -6,21 +6,12 @@ | |||||
| package unix | package unix | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int64(nsec / 1e9) | |||||
| ts.Nsec = int64(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: int32(usec)} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -6,21 +6,12 @@ | |||||
| package unix | package unix | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int64(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: int32(usec)} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -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 } | |||||
| @@ -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,53 +34,30 @@ 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) { | ||||
| // Perform lookup via a binary search | |||||
| left := 0 | |||||
| right := len(sysctlMib) - 1 | |||||
| for { | |||||
| 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 | |||||
| } | |||||
| i := sort.Search(len(sysctlMib), func(i int) bool { | |||||
| return sysctlMib[i].ctlname >= name | |||||
| }) | |||||
| if i < len(sysctlMib) && sysctlMib[i].ctlname == name { | |||||
| return sysctlMib[i].ctloid, nil | |||||
| } | } | ||||
| return nil, EINVAL | return nil, EINVAL | ||||
| } | } | ||||
| // ParseDirent parses up to max directory entries in buf, | |||||
| // appending the names to names. It returns the number | |||||
| // bytes consumed from buf, the number of entries added | |||||
| // to names, and the new names slice. | |||||
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||||
| origlen := len(buf) | |||||
| for max != 0 && len(buf) > 0 { | |||||
| dirent := (*Dirent)(unsafe.Pointer(&buf[0])) | |||||
| if dirent.Reclen == 0 { | |||||
| buf = nil | |||||
| break | |||||
| } | |||||
| buf = buf[dirent.Reclen:] | |||||
| if dirent.Fileno == 0 { // File absent in directory. | |||||
| continue | |||||
| } | |||||
| bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) | |||||
| var name = string(bytes[0:dirent.Namlen]) | |||||
| if name == "." || name == ".." { // Useless names | |||||
| continue | |||||
| } | |||||
| max-- | |||||
| count++ | |||||
| names = append(names, name) | |||||
| func SysctlUvmexp(name string) (*Uvmexp, error) { | |||||
| mib, err := sysctlmib(name) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | } | ||||
| return origlen - len(buf), count, names | |||||
| n := uintptr(SizeofUvmexp) | |||||
| var u Uvmexp | |||||
| if err := sysctl(mib, (*byte)(unsafe.Pointer(&u)), &n, nil, 0); err != nil { | |||||
| return nil, err | |||||
| } | |||||
| if n != SizeofUvmexp { | |||||
| return nil, EIO | |||||
| } | |||||
| return &u, nil | |||||
| } | } | ||||
| //sysnb pipe(p *[2]_C_int) (err error) | //sysnb pipe(p *[2]_C_int) (err error) | ||||
| @@ -98,6 +77,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 | ||||
| @@ -111,7 +107,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | ||||
| } | } | ||||
| r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | ||||
| use(unsafe.Pointer(_p0)) | |||||
| n = int(r0) | n = int(r0) | ||||
| if e1 != 0 { | if e1 != 0 { | ||||
| err = e1 | err = e1 | ||||
| @@ -119,6 +114,105 @@ 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 | |||||
| } | |||||
| //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) | |||||
| func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { | |||||
| if len(fds) == 0 { | |||||
| return ppoll(nil, 0, timeout, sigmask) | |||||
| } | |||||
| return ppoll(&fds[0], len(fds), timeout, sigmask) | |||||
| } | |||||
| 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 | ||||
| */ | */ | ||||
| @@ -133,13 +227,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) | ||||
| @@ -152,6 +249,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) | ||||
| @@ -166,13 +264,9 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| //sys Mkdir(path string, mode uint32) (err error) | //sys Mkdir(path string, mode uint32) (err error) | ||||
| //sys Mkfifo(path string, mode uint32) (err error) | //sys Mkfifo(path string, mode uint32) (err error) | ||||
| //sys Mknod(path string, mode uint32, dev int) (err error) | //sys Mknod(path string, mode uint32, dev int) (err error) | ||||
| //sys Mlock(b []byte) (err error) | |||||
| //sys Mlockall(flags int) (err error) | |||||
| //sys Mprotect(b []byte, prot int) (err error) | |||||
| //sys Munlock(b []byte) (err error) | |||||
| //sys Munlockall() (err error) | |||||
| //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | ||||
| //sys Open(path string, mode int, perm uint32) (fd int, err error) | //sys Open(path string, mode int, perm uint32) (fd int, err error) | ||||
| //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) | |||||
| //sys Pathconf(path string, name int) (val int, err error) | //sys Pathconf(path string, name int) (val int, err error) | ||||
| //sys Pread(fd int, p []byte, offset int64) (n int, err error) | //sys Pread(fd int, p []byte, offset int64) (n int, err error) | ||||
| //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) | //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) | ||||
| @@ -194,6 +288,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) | ||||
| @@ -210,6 +305,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| //sys munmap(addr uintptr, length uintptr) (err error) | //sys munmap(addr uintptr, length uintptr) (err error) | ||||
| //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ | ||||
| //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE | ||||
| //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||||
| /* | /* | ||||
| * Unimplemented | * Unimplemented | ||||
| @@ -241,9 +337,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 | ||||
| @@ -263,8 +357,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| // msgsnd | // msgsnd | ||||
| // nfssvc | // nfssvc | ||||
| // nnpfspioctl | // nnpfspioctl | ||||
| // openat | |||||
| // poll | |||||
| // preadv | // preadv | ||||
| // profil | // profil | ||||
| // pwritev | // pwritev | ||||
| @@ -279,7 +371,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 | ||||
| @@ -299,6 +390,5 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
| // thrsleep | // thrsleep | ||||
| // thrwakeup | // thrwakeup | ||||
| // unlinkat | // unlinkat | ||||
| // utimensat | |||||
| // vfork | // vfork | ||||
| // writev | // writev | ||||
| @@ -6,21 +6,12 @@ | |||||
| package unix | package unix | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = int64(nsec / 1e9) | |||||
| ts.Nsec = int32(nsec % 1e9) | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: int32(nsec)} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = int32(nsec % 1e9 / 1e3) | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: int32(usec)} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -40,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/386 the syscall is called sysctl instead of __sysctl. | |||||
| const SYS___SYSCTL = SYS_SYSCTL | |||||
| @@ -6,21 +6,12 @@ | |||||
| package unix | package unix | ||||
| func Getpagesize() int { return 4096 } | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| tv.Sec = nsec / 1e9 | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| func SetKevent(k *Kevent_t, fd, mode, flags int) { | func SetKevent(k *Kevent_t, fd, mode, flags int) { | ||||
| @@ -40,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 | |||||
| @@ -0,0 +1,37 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build arm,openbsd | |||||
| package unix | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: int32(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 = uint32(fd) | |||||
| k.Filter = int16(mode) | |||||
| k.Flags = uint16(flags) | |||||
| } | |||||
| 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) | |||||
| } | |||||
| // SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions | |||||
| // of openbsd/arm the syscall is called sysctl instead of __sysctl. | |||||
| const SYS___SYSCTL = SYS_SYSCTL | |||||
| @@ -13,7 +13,6 @@ | |||||
| package unix | package unix | ||||
| import ( | import ( | ||||
| "sync/atomic" | |||||
| "syscall" | "syscall" | ||||
| "unsafe" | "unsafe" | ||||
| ) | ) | ||||
| @@ -24,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 | ||||
| @@ -35,55 +35,20 @@ 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) | |||||
| } | |||||
| // ParseDirent parses up to max directory entries in buf, | |||||
| // appending the names to names. It returns the number | |||||
| // bytes consumed from buf, the number of entries added | |||||
| // to names, and the new names slice. | |||||
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||||
| origlen := len(buf) | |||||
| for max != 0 && len(buf) > 0 { | |||||
| dirent := (*Dirent)(unsafe.Pointer(&buf[0])) | |||||
| if dirent.Reclen == 0 { | |||||
| buf = nil | |||||
| break | |||||
| } | |||||
| buf = buf[dirent.Reclen:] | |||||
| if dirent.Ino == 0 { // File absent in directory. | |||||
| continue | |||||
| } | |||||
| bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) | |||||
| var name = string(bytes[0:clen(bytes[:])]) | |||||
| if name == "." || name == ".." { // Useless names | |||||
| continue | |||||
| } | |||||
| max-- | |||||
| count++ | |||||
| names = append(names, name) | |||||
| } | |||||
| return origlen - len(buf), count, names | |||||
| } | |||||
| func pipe() (r uintptr, w uintptr, err uintptr) | |||||
| //sysnb pipe(p *[2]_C_int) (n int, err error) | |||||
| func Pipe(p []int) (err error) { | func Pipe(p []int) (err error) { | ||||
| if len(p) != 2 { | if len(p) != 2 { | ||||
| return EINVAL | return EINVAL | ||||
| } | } | ||||
| r0, w0, e1 := pipe() | |||||
| if e1 != 0 { | |||||
| err = syscall.Errno(e1) | |||||
| var pp [2]_C_int | |||||
| n, err := pipe(&pp) | |||||
| if n != 0 { | |||||
| return err | |||||
| } | } | ||||
| p[0], p[1] = int(r0), int(w0) | |||||
| return | |||||
| p[0] = int(pp[0]) | |||||
| p[1] = int(pp[1]) | |||||
| return nil | |||||
| } | } | ||||
| func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { | func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { | ||||
| @@ -147,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 | ||||
| @@ -177,7 +154,7 @@ func Getwd() (wd string, err error) { | |||||
| func Getgroups() (gids []int, err error) { | func Getgroups() (gids []int, err error) { | ||||
| n, err := getgroups(0, nil) | n, err := getgroups(0, nil) | ||||
| // Check for error and sanity check group count. Newer versions of | |||||
| // Check for error and sanity check group count. Newer versions of | |||||
| // Solaris allow up to 1024 (NGROUPS_MAX). | // Solaris allow up to 1024 (NGROUPS_MAX). | ||||
| if n < 0 || n > 1024 { | if n < 0 || n > 1024 { | ||||
| if err != nil { | if err != nil { | ||||
| @@ -269,24 +246,34 @@ func (w WaitStatus) StopSignal() syscall.Signal { | |||||
| func (w WaitStatus) TrapCause() int { return -1 } | func (w WaitStatus) TrapCause() int { return -1 } | ||||
| func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr) | |||||
| //sys wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error) | |||||
| func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { | |||||
| r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage) | |||||
| if e1 != 0 { | |||||
| err = syscall.Errno(e1) | |||||
| func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) { | |||||
| var status _C_int | |||||
| rpid, err := wait4(int32(pid), &status, options, rusage) | |||||
| wpid := int(rpid) | |||||
| if wpid == -1 { | |||||
| return wpid, err | |||||
| } | |||||
| if wstatus != nil { | |||||
| *wstatus = WaitStatus(status) | |||||
| } | } | ||||
| return int(r0), err | |||||
| return wpid, nil | |||||
| } | } | ||||
| func gethostname() (name string, err uintptr) | |||||
| //sys gethostname(buf []byte) (n int, err error) | |||||
| func Gethostname() (name string, err error) { | func Gethostname() (name string, err error) { | ||||
| name, e1 := gethostname() | |||||
| if e1 != 0 { | |||||
| err = syscall.Errno(e1) | |||||
| var buf [MaxHostNameLen]byte | |||||
| n, err := gethostname(buf[:]) | |||||
| if n != 0 { | |||||
| return "", err | |||||
| } | } | ||||
| return name, err | |||||
| n = clen(buf[:]) | |||||
| if n < 1 { | |||||
| return "", EFAULT | |||||
| } | |||||
| return string(buf[:n]), nil | |||||
| } | } | ||||
| //sys utimes(path string, times *[2]Timeval) (err error) | //sys utimes(path string, times *[2]Timeval) (err error) | ||||
| @@ -325,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) | ||||
| @@ -351,7 +348,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) error { | |||||
| } | } | ||||
| // Solaris doesn't have an futimes function because it allows NULL to be | // Solaris doesn't have an futimes function because it allows NULL to be | ||||
| // specified as the path for futimesat. However, Go doesn't like | |||||
| // specified as the path for futimesat. However, Go doesn't like | |||||
| // NULL-style string interfaces, so this simple wrapper is provided. | // NULL-style string interfaces, so this simple wrapper is provided. | ||||
| func Futimes(fd int, tv []Timeval) error { | func Futimes(fd int, tv []Timeval) error { | ||||
| if tv == nil { | if tv == nil { | ||||
| @@ -363,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)) | ||||
| @@ -414,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 | ||||
| @@ -422,7 +419,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||||
| return | return | ||||
| } | } | ||||
| //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.recvmsg | |||||
| //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg | |||||
| func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { | func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { | ||||
| var msg Msghdr | var msg Msghdr | ||||
| @@ -441,7 +438,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from | |||||
| iov.Base = &dummy | iov.Base = &dummy | ||||
| iov.SetLen(1) | iov.SetLen(1) | ||||
| } | } | ||||
| msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) | |||||
| msg.Accrightslen = int32(len(oob)) | |||||
| } | } | ||||
| msg.Iov = &iov | msg.Iov = &iov | ||||
| msg.Iovlen = 1 | msg.Iovlen = 1 | ||||
| @@ -451,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 | ||||
| } | } | ||||
| @@ -461,7 +458,7 @@ func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { | |||||
| return | return | ||||
| } | } | ||||
| //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.sendmsg | |||||
| //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg | |||||
| func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { | func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { | ||||
| var ptr unsafe.Pointer | var ptr unsafe.Pointer | ||||
| @@ -487,7 +484,7 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) | |||||
| iov.Base = &dummy | iov.Base = &dummy | ||||
| iov.SetLen(1) | iov.SetLen(1) | ||||
| } | } | ||||
| msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) | |||||
| msg.Accrightslen = int32(len(oob)) | |||||
| } | } | ||||
| msg.Iov = &iov | msg.Iov = &iov | ||||
| msg.Iovlen = 1 | msg.Iovlen = 1 | ||||
| @@ -515,52 +512,79 @@ func Acct(path string) (err error) { | |||||
| return acct(pathp) | return acct(pathp) | ||||
| } | } | ||||
| //sys __makedev(version int, major uint, minor uint) (val uint64) | |||||
| func Mkdev(major, minor uint32) uint64 { | |||||
| return __makedev(NEWDEV, uint(major), uint(minor)) | |||||
| } | |||||
| //sys __major(version int, dev uint64) (val uint) | |||||
| func Major(dev uint64) uint32 { | |||||
| return uint32(__major(NEWDEV, dev)) | |||||
| } | |||||
| //sys __minor(version int, dev uint64) (val uint) | |||||
| func Minor(dev uint64) uint32 { | |||||
| return uint32(__minor(NEWDEV, dev)) | |||||
| } | |||||
| /* | /* | ||||
| * Expose the ioctl function | * Expose the ioctl function | ||||
| */ | */ | ||||
| //sys ioctl(fd int, req int, arg uintptr) (err error) | |||||
| //sys ioctl(fd int, req uint, arg uintptr) (err error) | |||||
| func IoctlSetInt(fd int, req int, value int) (err error) { | |||||
| func IoctlSetInt(fd int, req uint, value int) (err error) { | |||||
| return ioctl(fd, req, uintptr(value)) | return ioctl(fd, req, uintptr(value)) | ||||
| } | } | ||||
| func IoctlSetWinsize(fd int, req int, value *Winsize) (err error) { | |||||
| func ioctlSetWinsize(fd int, req uint, value *Winsize) (err error) { | |||||
| return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | ||||
| } | } | ||||
| func IoctlSetTermios(fd int, req int, value *Termios) (err error) { | |||||
| func ioctlSetTermios(fd int, req uint, value *Termios) (err error) { | |||||
| return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | ||||
| } | } | ||||
| func IoctlSetTermio(fd int, req int, value *Termio) (err error) { | |||||
| func IoctlSetTermio(fd int, req uint, value *Termio) (err error) { | |||||
| return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | ||||
| } | } | ||||
| func IoctlGetInt(fd int, req int) (int, error) { | |||||
| func IoctlGetInt(fd int, req uint) (int, error) { | |||||
| var value int | var value int | ||||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | ||||
| return value, err | return value, err | ||||
| } | } | ||||
| func IoctlGetWinsize(fd int, req int) (*Winsize, error) { | |||||
| func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||||
| var value Winsize | var value Winsize | ||||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | ||||
| return &value, err | return &value, err | ||||
| } | } | ||||
| func IoctlGetTermios(fd int, req int) (*Termios, error) { | |||||
| func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||||
| var value Termios | var value Termios | ||||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | ||||
| return &value, err | return &value, err | ||||
| } | } | ||||
| func IoctlGetTermio(fd int, req int) (*Termio, error) { | |||||
| func IoctlGetTermio(fd int, req uint) (*Termio, error) { | |||||
| var value Termio | var value Termio | ||||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | ||||
| return &value, err | return &value, err | ||||
| } | } | ||||
| //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) | |||||
| } | |||||
| /* | /* | ||||
| * Exposed directly | * Exposed directly | ||||
| */ | */ | ||||
| @@ -575,14 +599,18 @@ func IoctlGetTermio(fd int, req int) (*Termio, 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 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 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) | ||||
| //sysnb Getpid() (pid int) | //sysnb Getpid() (pid int) | ||||
| @@ -599,7 +627,7 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { | |||||
| //sys Kill(pid int, signum syscall.Signal) (err error) | //sys Kill(pid int, signum syscall.Signal) (err error) | ||||
| //sys Lchown(path string, uid int, gid int) (err error) | //sys Lchown(path string, uid int, gid int) (err error) | ||||
| //sys Link(path string, link string) (err error) | //sys Link(path string, link string) (err error) | ||||
| //sys Listen(s int, backlog int) (err error) = libsocket.listen | |||||
| //sys Listen(s int, backlog int) (err error) = libsocket.__xnet_llisten | |||||
| //sys Lstat(path string, stat *Stat_t) (err error) | //sys Lstat(path string, stat *Stat_t) (err error) | ||||
| //sys Madvise(b []byte, advice int) (err error) | //sys Madvise(b []byte, advice int) (err error) | ||||
| //sys Mkdir(path string, mode uint32) (err error) | //sys Mkdir(path string, mode uint32) (err error) | ||||
| @@ -611,6 +639,7 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { | |||||
| //sys Mlock(b []byte) (err error) | //sys Mlock(b []byte) (err error) | ||||
| //sys Mlockall(flags int) (err error) | //sys Mlockall(flags int) (err error) | ||||
| //sys Mprotect(b []byte, prot int) (err error) | //sys Mprotect(b []byte, prot int) (err error) | ||||
| //sys Msync(b []byte, flags int) (err error) | |||||
| //sys Munlock(b []byte) (err error) | //sys Munlock(b []byte) (err error) | ||||
| //sys Munlockall() (err error) | //sys Munlockall() (err error) | ||||
| //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | ||||
| @@ -626,6 +655,7 @@ func IoctlGetTermio(fd int, req int) (*Termio, 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) | ||||
| @@ -639,6 +669,7 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { | |||||
| //sysnb Setuid(uid int) (err error) | //sysnb Setuid(uid int) (err error) | ||||
| //sys Shutdown(s int, how int) (err error) = libsocket.shutdown | //sys Shutdown(s int, how int) (err error) = libsocket.shutdown | ||||
| //sys Stat(path string, stat *Stat_t) (err error) | //sys Stat(path string, stat *Stat_t) (err error) | ||||
| //sys Statvfs(path string, vfsstat *Statvfs_t) (err error) | |||||
| //sys Symlink(path string, link string) (err error) | //sys Symlink(path string, link string) (err error) | ||||
| //sys Sync() (err error) | //sys Sync() (err error) | ||||
| //sysnb Times(tms *Tms) (ticks uintptr, err error) | //sysnb Times(tms *Tms) (ticks uintptr, err error) | ||||
| @@ -652,15 +683,16 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { | |||||
| //sys Unlinkat(dirfd int, path string, flags int) (err error) | //sys Unlinkat(dirfd int, path string, flags int) (err error) | ||||
| //sys Ustat(dev int, ubuf *Ustat_t) (err error) | //sys Ustat(dev int, ubuf *Ustat_t) (err error) | ||||
| //sys Utime(path string, buf *Utimbuf) (err error) | //sys Utime(path string, buf *Utimbuf) (err error) | ||||
| //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind | |||||
| //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.connect | |||||
| //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_bind | |||||
| //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 sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.sendto | |||||
| //sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.socket | |||||
| //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.socketpair | |||||
| //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 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 | |||||
| //sys write(fd int, p []byte) (n int, err error) | //sys write(fd int, p []byte) (n int, err error) | ||||
| //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.getsockopt | |||||
| //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt | |||||
| //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername | //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername | ||||
| //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt | //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt | ||||
| //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom | //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom | ||||
| @@ -696,18 +728,3 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e | |||||
| func Munmap(b []byte) (err error) { | func Munmap(b []byte) (err error) { | ||||
| return mapper.Munmap(b) | return mapper.Munmap(b) | ||||
| } | } | ||||
| //sys sysconf(name int) (n int64, err error) | |||||
| // pageSize caches the value of Getpagesize, since it can't change | |||||
| // once the system is booted. | |||||
| var pageSize int64 // accessed atomically | |||||
| func Getpagesize() int { | |||||
| n := atomic.LoadInt64(&pageSize) | |||||
| if n == 0 { | |||||
| n, _ = sysconf(_SC_PAGESIZE) | |||||
| atomic.StoreInt64(&pageSize, n) | |||||
| } | |||||
| return int(n) | |||||
| } | |||||
| @@ -6,19 +6,12 @@ | |||||
| package unix | package unix | ||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| func NsecToTimespec(nsec int64) (ts Timespec) { | |||||
| ts.Sec = nsec / 1e9 | |||||
| ts.Nsec = nsec % 1e9 | |||||
| return | |||||
| func setTimespec(sec, nsec int64) Timespec { | |||||
| return Timespec{Sec: sec, Nsec: nsec} | |||||
| } | } | ||||
| func NsecToTimeval(nsec int64) (tv Timeval) { | |||||
| nsec += 999 // round up to microsecond | |||||
| tv.Usec = nsec % 1e9 / 1e3 | |||||
| tv.Sec = int64(nsec / 1e9) | |||||
| return | |||||
| func setTimeval(sec, usec int64) Timeval { | |||||
| return Timeval{Sec: sec, Usec: usec} | |||||
| } | } | ||||
| func (iov *Iovec) SetLen(length int) { | func (iov *Iovec) SetLen(length int) { | ||||
| @@ -28,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") | |||||
| } | |||||
| @@ -2,12 +2,14 @@ | |||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // +build darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| package unix | package unix | ||||
| import ( | import ( | ||||
| "bytes" | |||||
| "runtime" | "runtime" | ||||
| "sort" | |||||
| "sync" | "sync" | ||||
| "syscall" | "syscall" | ||||
| "unsafe" | "unsafe" | ||||
| @@ -20,9 +22,10 @@ var ( | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 | |||||
| dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8 | |||||
| netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 | |||||
| darwin64Bit = runtime.GOOS == "darwin" && SizeofPtr == 8 | |||||
| dragonfly64Bit = runtime.GOOS == "dragonfly" && SizeofPtr == 8 | |||||
| netbsd32Bit = runtime.GOOS == "netbsd" && SizeofPtr == 4 | |||||
| solaris64Bit = runtime.GOOS == "solaris" && SizeofPtr == 8 | |||||
| ) | ) | ||||
| // Do the interface allocations only once for common | // Do the interface allocations only once for common | ||||
| @@ -49,10 +52,36 @@ func errnoErr(e syscall.Errno) error { | |||||
| return e | return e | ||||
| } | } | ||||
| func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| // 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. | ||||
| @@ -142,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 | ||||
| @@ -159,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 | ||||
| @@ -186,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) { | ||||
| @@ -196,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 | ||||
| @@ -203,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 | ||||
| } | } | ||||
| @@ -295,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) | |||||
| } | |||||
| @@ -0,0 +1,15 @@ | |||||
| // Copyright 2016 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| // +build !gccgo | |||||
| package unix | |||||
| import "syscall" | |||||
| func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||||
| @@ -0,0 +1,82 @@ | |||||
| // Copyright 2017 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||||
| package unix | |||||
| import "time" | |||||
| // TimespecToNsec converts a Timespec value into a number of | |||||
| // nanoseconds since the Unix epoch. | |||||
| func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } | |||||
| // NsecToTimespec takes a number of nanoseconds since the Unix epoch | |||||
| // and returns the corresponding Timespec value. | |||||
| func NsecToTimespec(nsec int64) Timespec { | |||||
| sec := nsec / 1e9 | |||||
| nsec = nsec % 1e9 | |||||
| if nsec < 0 { | |||||
| nsec += 1e9 | |||||
| sec-- | |||||
| } | |||||
| 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 | |||||
| // since the Unix epoch. | |||||
| func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } | |||||
| // NsecToTimeval takes a number of nanoseconds since the Unix epoch | |||||
| // and returns the corresponding Timeval value. | |||||
| func NsecToTimeval(nsec int64) Timeval { | |||||
| nsec += 999 // round up to microsecond | |||||
| usec := nsec % 1e9 / 1e3 | |||||
| sec := nsec / 1e9 | |||||
| if usec < 0 { | |||||
| usec += 1e6 | |||||
| sec-- | |||||
| } | |||||
| return setTimeval(sec, usec) | |||||
| } | |||||
| // Unix returns ts as the number of seconds and nanoseconds elapsed since the | |||||
| // Unix epoch. | |||||
| func (ts *Timespec) Unix() (sec int64, nsec int64) { | |||||
| return int64(ts.Sec), int64(ts.Nsec) | |||||
| } | |||||
| // Unix returns tv as the number of seconds and nanoseconds elapsed since the | |||||
| // Unix epoch. | |||||
| func (tv *Timeval) Unix() (sec int64, nsec int64) { | |||||
| return int64(tv.Sec), int64(tv.Usec) * 1000 | |||||
| } | |||||
| // Nano returns ts as the number of nanoseconds elapsed since the Unix epoch. | |||||
| func (ts *Timespec) Nano() int64 { | |||||
| return int64(ts.Sec)*1e9 + int64(ts.Nsec) | |||||
| } | |||||
| // Nano returns tv as the number of nanoseconds elapsed since the Unix epoch. | |||||
| func (tv *Timeval) Nano() int64 { | |||||
| return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 | |||||
| } | |||||
| @@ -0,0 +1,236 @@ | |||||
| // Copyright 2018 The Go Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style | |||||
| // license that can be found in the LICENSE file. | |||||
| // +build ignore | |||||
| // +build aix | |||||
| /* | |||||
| Input to cgo -godefs. See also mkerrors.sh and mkall.sh | |||||
| */ | |||||
| // +godefs map struct_in_addr [4]byte /* in_addr */ | |||||
| // +godefs map struct_in6_addr [16]byte /* in6_addr */ | |||||
| package unix | |||||
| /* | |||||
| #include <sys/types.h> | |||||
| #include <sys/time.h> | |||||
| #include <sys/limits.h> | |||||
| #include <sys/un.h> | |||||
| #include <utime.h> | |||||
| #include <sys/utsname.h> | |||||
| #include <sys/poll.h> | |||||
| #include <sys/resource.h> | |||||
| #include <sys/stat.h> | |||||
| #include <sys/statfs.h> | |||||
| #include <sys/termio.h> | |||||
| #include <sys/ioctl.h> | |||||
| #include <termios.h> | |||||
| #include <net/if.h> | |||||
| #include <net/if_dl.h> | |||||
| #include <netinet/in.h> | |||||
| #include <netinet/icmp6.h> | |||||
| #include <dirent.h> | |||||
| #include <fcntl.h> | |||||
| enum { | |||||
| sizeofPtr = sizeof(void*), | |||||
| }; | |||||
| union sockaddr_all { | |||||
| struct sockaddr s1; // this one gets used for fields | |||||
| struct sockaddr_in s2; // these pad it out | |||||
| struct sockaddr_in6 s3; | |||||
| struct sockaddr_un s4; | |||||
| struct sockaddr_dl s5; | |||||
| }; | |||||
| struct sockaddr_any { | |||||
| struct sockaddr addr; | |||||
| char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; | |||||
| }; | |||||
| */ | |||||
| import "C" | |||||
| // Machine characteristics | |||||
| const ( | |||||
| SizeofPtr = C.sizeofPtr | |||||
| SizeofShort = C.sizeof_short | |||||
| SizeofInt = C.sizeof_int | |||||
| SizeofLong = C.sizeof_long | |||||
| SizeofLongLong = C.sizeof_longlong | |||||
| PathMax = C.PATH_MAX | |||||
| ) | |||||
| // Basic types | |||||
| type ( | |||||
| _C_short C.short | |||||
| _C_int C.int | |||||
| _C_long C.long | |||||
| _C_long_long C.longlong | |||||
| ) | |||||
| type off64 C.off64_t | |||||
| type off C.off_t | |||||
| type Mode_t C.mode_t | |||||
| // Time | |||||
| type Timespec C.struct_timespec | |||||
| type StTimespec C.struct_st_timespec | |||||
| type Timeval C.struct_timeval | |||||
| type Timeval32 C.struct_timeval32 | |||||
| type Timex C.struct_timex | |||||
| type Time_t C.time_t | |||||
| type Tms C.struct_tms | |||||
| type Utimbuf C.struct_utimbuf | |||||
| type Timezone C.struct_timezone | |||||
| // Processes | |||||
| type Rusage C.struct_rusage | |||||
| type Rlimit C.struct_rlimit64 | |||||
| type Pid_t C.pid_t | |||||
| type _Gid_t C.gid_t | |||||
| type dev_t C.dev_t | |||||
| // Files | |||||
| type Stat_t C.struct_stat | |||||
| type StatxTimestamp C.struct_statx_timestamp | |||||
| type Statx_t C.struct_statx | |||||
| type Dirent C.struct_dirent | |||||
| // Sockets | |||||
| type RawSockaddrInet4 C.struct_sockaddr_in | |||||
| type RawSockaddrInet6 C.struct_sockaddr_in6 | |||||
| type RawSockaddrUnix C.struct_sockaddr_un | |||||
| type RawSockaddr C.struct_sockaddr | |||||
| type RawSockaddrAny C.struct_sockaddr_any | |||||
| type _Socklen C.socklen_t | |||||
| type Cmsghdr C.struct_cmsghdr | |||||
| type ICMPv6Filter C.struct_icmp6_filter | |||||
| type Iovec C.struct_iovec | |||||
| type IPMreq C.struct_ip_mreq | |||||
| type IPv6Mreq C.struct_ipv6_mreq | |||||
| type IPv6MTUInfo C.struct_ip6_mtuinfo | |||||
| type Linger C.struct_linger | |||||
| type Msghdr C.struct_msghdr | |||||
| const ( | |||||
| SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in | |||||
| SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 | |||||
| SizeofSockaddrAny = C.sizeof_struct_sockaddr_any | |||||
| SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un | |||||
| SizeofLinger = C.sizeof_struct_linger | |||||
| SizeofIPMreq = C.sizeof_struct_ip_mreq | |||||
| SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq | |||||
| SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo | |||||
| SizeofMsghdr = C.sizeof_struct_msghdr | |||||
| SizeofCmsghdr = C.sizeof_struct_cmsghdr | |||||
| SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter | |||||
| ) | |||||
| // Routing and interface messages | |||||
| const ( | |||||
| SizeofIfMsghdr = C.sizeof_struct_if_msghdr | |||||
| ) | |||||
| type IfMsgHdr C.struct_if_msghdr | |||||
| // Misc | |||||
| type FdSet C.fd_set | |||||
| type Utsname C.struct_utsname | |||||
| type Ustat_t C.struct_ustat | |||||
| type Sigset_t C.sigset_t | |||||
| const ( | |||||
| AT_FDCWD = C.AT_FDCWD | |||||
| AT_REMOVEDIR = C.AT_REMOVEDIR | |||||
| AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW | |||||
| ) | |||||
| // Terminal handling | |||||
| type Termios C.struct_termios | |||||
| type Termio C.struct_termio | |||||
| type Winsize C.struct_winsize | |||||
| //poll | |||||
| type PollFd struct { | |||||
| Fd int32 | |||||
| Events uint16 | |||||
| Revents uint16 | |||||
| } | |||||
| const ( | |||||
| POLLERR = C.POLLERR | |||||
| POLLHUP = C.POLLHUP | |||||
| POLLIN = C.POLLIN | |||||
| POLLNVAL = C.POLLNVAL | |||||
| POLLOUT = C.POLLOUT | |||||
| POLLPRI = C.POLLPRI | |||||
| POLLRDBAND = C.POLLRDBAND | |||||
| POLLRDNORM = C.POLLRDNORM | |||||
| POLLWRBAND = C.POLLWRBAND | |||||
| POLLWRNORM = C.POLLWRNORM | |||||
| ) | |||||
| //flock_t | |||||
| type Flock_t C.struct_flock64 | |||||
| // Statfs | |||||
| type Fsid_t C.struct_fsid_t | |||||
| type Fsid64_t C.struct_fsid64_t | |||||
| type Statfs_t C.struct_statfs | |||||
| const RNDGETENTCNT = 0x80045200 | |||||
| @@ -5,7 +5,7 @@ | |||||
| // +build ignore | // +build ignore | ||||
| /* | /* | ||||
| Input to cgo -godefs. See also mkerrors.sh and mkall.sh | |||||
| Input to cgo -godefs. See README.md | |||||
| */ | */ | ||||
| // +godefs map struct_in_addr [4]byte /* in_addr */ | // +godefs map struct_in_addr [4]byte /* in_addr */ | ||||
| @@ -19,6 +19,7 @@ package unix | |||||
| #define _DARWIN_USE_64_BIT_INODE | #define _DARWIN_USE_64_BIT_INODE | ||||
| #include <dirent.h> | #include <dirent.h> | ||||
| #include <fcntl.h> | #include <fcntl.h> | ||||
| #include <poll.h> | |||||
| #include <signal.h> | #include <signal.h> | ||||
| #include <termios.h> | #include <termios.h> | ||||
| #include <unistd.h> | #include <unistd.h> | ||||
| @@ -38,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> | ||||
| @@ -68,14 +70,14 @@ struct sockaddr_any { | |||||
| */ | */ | ||||
| import "C" | import "C" | ||||
| // Machine characteristics; for internal use. | |||||
| // Machine characteristics | |||||
| const ( | const ( | ||||
| sizeofPtr = C.sizeofPtr | |||||
| sizeofShort = C.sizeof_short | |||||
| sizeofInt = C.sizeof_int | |||||
| sizeofLong = C.sizeof_long | |||||
| sizeofLongLong = C.sizeof_longlong | |||||
| SizeofPtr = C.sizeofPtr | |||||
| SizeofShort = C.sizeof_short | |||||
| SizeofInt = C.sizeof_int | |||||
| SizeofLong = C.sizeof_long | |||||
| SizeofLongLong = C.sizeof_longlong | |||||
| ) | ) | ||||
| // Basic types | // Basic types | ||||
| @@ -242,9 +244,34 @@ 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 ( | ||||
| AT_FDCWD = C.AT_FDCWD | AT_FDCWD = C.AT_FDCWD | ||||
| AT_REMOVEDIR = C.AT_REMOVEDIR | |||||
| AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW | |||||
| AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW | AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW | ||||
| ) | ) | ||||
| // poll | |||||
| type PollFd C.struct_pollfd | |||||
| const ( | |||||
| POLLERR = C.POLLERR | |||||
| POLLHUP = C.POLLHUP | |||||
| POLLIN = C.POLLIN | |||||
| POLLNVAL = C.POLLNVAL | |||||
| POLLOUT = C.POLLOUT | |||||
| POLLPRI = C.POLLPRI | |||||
| POLLRDBAND = C.POLLRDBAND | |||||
| POLLRDNORM = C.POLLRDNORM | |||||
| POLLWRBAND = C.POLLWRBAND | |||||
| POLLWRNORM = C.POLLWRNORM | |||||
| ) | |||||
| // uname | |||||
| type Utsname C.struct_utsname | |||||
| @@ -5,7 +5,7 @@ | |||||
| // +build ignore | // +build ignore | ||||
| /* | /* | ||||
| Input to cgo -godefs. See also mkerrors.sh and mkall.sh | |||||
| Input to cgo -godefs. See README.md | |||||
| */ | */ | ||||
| // +godefs map struct_in_addr [4]byte /* in_addr */ | // +godefs map struct_in_addr [4]byte /* in_addr */ | ||||
| @@ -17,6 +17,7 @@ package unix | |||||
| #define KERNEL | #define KERNEL | ||||
| #include <dirent.h> | #include <dirent.h> | ||||
| #include <fcntl.h> | #include <fcntl.h> | ||||
| #include <poll.h> | |||||
| #include <signal.h> | #include <signal.h> | ||||
| #include <termios.h> | #include <termios.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| @@ -34,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> | ||||
| @@ -63,14 +65,14 @@ struct sockaddr_any { | |||||
| */ | */ | ||||
| import "C" | import "C" | ||||
| // Machine characteristics; for internal use. | |||||
| // Machine characteristics | |||||
| const ( | const ( | ||||
| sizeofPtr = C.sizeofPtr | |||||
| sizeofShort = C.sizeof_short | |||||
| sizeofInt = C.sizeof_int | |||||
| sizeofLong = C.sizeof_long | |||||
| sizeofLongLong = C.sizeof_longlong | |||||
| SizeofPtr = C.sizeofPtr | |||||
| SizeofShort = C.sizeof_short | |||||
| SizeofInt = C.sizeof_int | |||||
| SizeofLong = C.sizeof_long | |||||
| SizeofLongLong = C.sizeof_longlong | |||||
| ) | ) | ||||
| // Basic types | // Basic types | ||||
| @@ -98,23 +100,6 @@ type _Gid_t C.gid_t | |||||
| // Files | // Files | ||||
| const ( // Directory mode bits | |||||
| S_IFMT = C.S_IFMT | |||||
| S_IFIFO = C.S_IFIFO | |||||
| S_IFCHR = C.S_IFCHR | |||||
| S_IFDIR = C.S_IFDIR | |||||
| S_IFBLK = C.S_IFBLK | |||||
| S_IFREG = C.S_IFREG | |||||
| S_IFLNK = C.S_IFLNK | |||||
| S_IFSOCK = C.S_IFSOCK | |||||
| S_ISUID = C.S_ISUID | |||||
| S_ISGID = C.S_ISGID | |||||
| S_ISVTX = C.S_ISVTX | |||||
| S_IRUSR = C.S_IRUSR | |||||
| S_IWUSR = C.S_IWUSR | |||||
| S_IXUSR = C.S_IXUSR | |||||
| ) | |||||
| type Stat_t C.struct_stat | type Stat_t C.struct_stat | ||||
| type Statfs_t C.struct_statfs | type Statfs_t C.struct_statfs | ||||
| @@ -125,6 +110,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 | ||||
| @@ -240,3 +231,33 @@ type BpfHdr C.struct_bpf_hdr | |||||
| // Terminal handling | // Terminal handling | ||||
| type Termios C.struct_termios | type Termios C.struct_termios | ||||
| type Winsize C.struct_winsize | |||||
| // fchmodat-like syscalls. | |||||
| const ( | |||||
| AT_FDCWD = C.AT_FDCWD | |||||
| AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW | |||||
| ) | |||||
| // poll | |||||
| type PollFd C.struct_pollfd | |||||
| const ( | |||||
| POLLERR = C.POLLERR | |||||
| POLLHUP = C.POLLHUP | |||||
| POLLIN = C.POLLIN | |||||
| POLLNVAL = C.POLLNVAL | |||||
| POLLOUT = C.POLLOUT | |||||
| POLLPRI = C.POLLPRI | |||||
| POLLRDBAND = C.POLLRDBAND | |||||
| POLLRDNORM = C.POLLRDNORM | |||||
| POLLWRBAND = C.POLLWRBAND | |||||
| POLLWRNORM = C.POLLWRNORM | |||||
| ) | |||||
| // Uname | |||||
| type Utsname C.struct_utsname | |||||
| @@ -5,7 +5,7 @@ | |||||
| // +build ignore | // +build ignore | ||||
| /* | /* | ||||
| Input to cgo -godefs. See also mkerrors.sh and mkall.sh | |||||
| Input to cgo -godefs. See README.md | |||||
| */ | */ | ||||
| // +godefs map struct_in_addr [4]byte /* in_addr */ | // +godefs map struct_in_addr [4]byte /* in_addr */ | ||||
| @@ -14,13 +14,19 @@ Input to cgo -godefs. See also mkerrors.sh and mkall.sh | |||||
| package unix | package unix | ||||
| /* | /* | ||||
| #define KERNEL | |||||
| #define _WANT_FREEBSD11_STAT 1 | |||||
| #define _WANT_FREEBSD11_STATFS 1 | |||||
| #define _WANT_FREEBSD11_DIRENT 1 | |||||
| #define _WANT_FREEBSD11_KEVENT 1 | |||||
| #include <dirent.h> | #include <dirent.h> | ||||
| #include <fcntl.h> | #include <fcntl.h> | ||||
| #include <poll.h> | |||||
| #include <signal.h> | #include <signal.h> | ||||
| #include <termios.h> | #include <termios.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <unistd.h> | #include <unistd.h> | ||||
| #include <sys/capability.h> | |||||
| #include <sys/event.h> | #include <sys/event.h> | ||||
| #include <sys/mman.h> | #include <sys/mman.h> | ||||
| #include <sys/mount.h> | #include <sys/mount.h> | ||||
| @@ -34,6 +40,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> | ||||
| @@ -60,50 +67,6 @@ struct sockaddr_any { | |||||
| char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; | char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; | ||||
| }; | }; | ||||
| // This structure is a duplicate of stat on FreeBSD 8-STABLE. | |||||
| // See /usr/include/sys/stat.h. | |||||
| struct stat8 { | |||||
| #undef st_atimespec st_atim | |||||
| #undef st_mtimespec st_mtim | |||||
| #undef st_ctimespec st_ctim | |||||
| #undef st_birthtimespec st_birthtim | |||||
| __dev_t st_dev; | |||||
| ino_t st_ino; | |||||
| mode_t st_mode; | |||||
| nlink_t st_nlink; | |||||
| uid_t st_uid; | |||||
| gid_t st_gid; | |||||
| __dev_t st_rdev; | |||||
| #if __BSD_VISIBLE | |||||
| struct timespec st_atimespec; | |||||
| struct timespec st_mtimespec; | |||||
| struct timespec st_ctimespec; | |||||
| #else | |||||
| time_t st_atime; | |||||
| long __st_atimensec; | |||||
| time_t st_mtime; | |||||
| long __st_mtimensec; | |||||
| time_t st_ctime; | |||||
| long __st_ctimensec; | |||||
| #endif | |||||
| off_t st_size; | |||||
| blkcnt_t st_blocks; | |||||
| blksize_t st_blksize; | |||||
| fflags_t st_flags; | |||||
| __uint32_t st_gen; | |||||
| __int32_t st_lspare; | |||||
| #if __BSD_VISIBLE | |||||
| struct timespec st_birthtimespec; | |||||
| unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); | |||||
| unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); | |||||
| #else | |||||
| time_t st_birthtime; | |||||
| long st_birthtimensec; | |||||
| unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec)); | |||||
| unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec)); | |||||
| #endif | |||||
| }; | |||||
| // This structure is a duplicate of if_data on FreeBSD 8-STABLE. | // This structure is a duplicate of if_data on FreeBSD 8-STABLE. | ||||
| // See /usr/include/net/if.h. | // See /usr/include/net/if.h. | ||||
| struct if_data8 { | struct if_data8 { | ||||
| @@ -130,7 +93,10 @@ struct if_data8 { | |||||
| u_long ifi_iqdrops; | u_long ifi_iqdrops; | ||||
| u_long ifi_noproto; | u_long ifi_noproto; | ||||
| u_long ifi_hwassist; | u_long ifi_hwassist; | ||||
| // FIXME: these are now unions, so maybe need to change definitions? | |||||
| #undef ifi_epoch | |||||
| time_t ifi_epoch; | time_t ifi_epoch; | ||||
| #undef ifi_lastchange | |||||
| struct timeval ifi_lastchange; | struct timeval ifi_lastchange; | ||||
| }; | }; | ||||
| @@ -148,14 +114,14 @@ struct if_msghdr8 { | |||||
| */ | */ | ||||
| import "C" | import "C" | ||||
| // Machine characteristics; for internal use. | |||||
| // Machine characteristics | |||||
| const ( | const ( | ||||
| sizeofPtr = C.sizeofPtr | |||||
| sizeofShort = C.sizeof_short | |||||
| sizeofInt = C.sizeof_int | |||||
| sizeofLong = C.sizeof_long | |||||
| sizeofLongLong = C.sizeof_longlong | |||||
| SizeofPtr = C.sizeofPtr | |||||
| SizeofShort = C.sizeof_short | |||||
| SizeofInt = C.sizeof_int | |||||
| SizeofLong = C.sizeof_long | |||||
| SizeofLongLong = C.sizeof_longlong | |||||
| ) | ) | ||||
| // Basic types | // Basic types | ||||
| @@ -183,33 +149,33 @@ type _Gid_t C.gid_t | |||||
| // Files | // Files | ||||
| const ( // Directory mode bits | |||||
| S_IFMT = C.S_IFMT | |||||
| S_IFIFO = C.S_IFIFO | |||||
| S_IFCHR = C.S_IFCHR | |||||
| S_IFDIR = C.S_IFDIR | |||||
| S_IFBLK = C.S_IFBLK | |||||
| S_IFREG = C.S_IFREG | |||||
| S_IFLNK = C.S_IFLNK | |||||
| S_IFSOCK = C.S_IFSOCK | |||||
| S_ISUID = C.S_ISUID | |||||
| S_ISGID = C.S_ISGID | |||||
| S_ISVTX = C.S_ISVTX | |||||
| S_IRUSR = C.S_IRUSR | |||||
| S_IWUSR = C.S_IWUSR | |||||
| S_IXUSR = C.S_IXUSR | |||||
| const ( | |||||
| _statfsVersion = C.STATFS_VERSION | |||||
| _dirblksiz = C.DIRBLKSIZ | |||||
| ) | ) | ||||
| type Stat_t C.struct_stat8 | |||||
| type Stat_t C.struct_stat | |||||
| type stat_freebsd11_t C.struct_freebsd11_stat | |||||
| type Statfs_t C.struct_statfs | type Statfs_t C.struct_statfs | ||||
| type statfs_freebsd11_t C.struct_freebsd11_statfs | |||||
| type Flock_t C.struct_flock | type Flock_t C.struct_flock | ||||
| type Dirent C.struct_dirent | type Dirent C.struct_dirent | ||||
| type dirent_freebsd11 C.struct_freebsd11_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 ( | ||||
| @@ -284,7 +250,7 @@ const ( | |||||
| // Events (kqueue, kevent) | // Events (kqueue, kevent) | ||||
| type Kevent_t C.struct_kevent | |||||
| type Kevent_t C.struct_kevent_freebsd11 | |||||
| // Select | // Select | ||||
| @@ -351,3 +317,40 @@ type BpfZbufHeader C.struct_bpf_zbuf_header | |||||
| // Terminal handling | // Terminal handling | ||||
| type Termios C.struct_termios | type Termios C.struct_termios | ||||
| type Winsize C.struct_winsize | |||||
| // fchmodat-like syscalls. | |||||
| const ( | |||||
| AT_FDCWD = C.AT_FDCWD | |||||
| AT_REMOVEDIR = C.AT_REMOVEDIR | |||||
| AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW | |||||
| AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW | |||||
| ) | |||||
| // poll | |||||
| type PollFd C.struct_pollfd | |||||
| const ( | |||||
| POLLERR = C.POLLERR | |||||
| POLLHUP = C.POLLHUP | |||||
| POLLIN = C.POLLIN | |||||
| POLLINIGNEOF = C.POLLINIGNEOF | |||||
| POLLNVAL = C.POLLNVAL | |||||
| POLLOUT = C.POLLOUT | |||||
| POLLPRI = C.POLLPRI | |||||
| POLLRDBAND = C.POLLRDBAND | |||||
| POLLRDNORM = C.POLLRDNORM | |||||
| POLLWRBAND = C.POLLWRBAND | |||||
| POLLWRNORM = C.POLLWRNORM | |||||
| ) | |||||
| // Capabilities | |||||
| type CapRights C.struct_cap_rights | |||||
| // Uname | |||||
| type Utsname C.struct_utsname | |||||