| @@ -776,7 +776,8 @@ | |||
| revision = "5a06fca2c336a4b2b2fcb45702e8c47621b2aa2c" | |||
| [[projects]] | |||
| digest = "1:47495898c42062ace16d8046915b088e7c3846e77b997ec5a8a00ec552e179d5" | |||
| branch = "master" | |||
| digest = "1:030ca7763285f6cdec5684d7417faa2810d10a508b0220b1487cc876b5c00c35" | |||
| name = "golang.org/x/sys" | |||
| packages = [ | |||
| "unix", | |||
| @@ -784,7 +785,7 @@ | |||
| "windows/svc", | |||
| ] | |||
| pruneopts = "NUT" | |||
| revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8" | |||
| revision = "2772b66316d2c587efeb188dcd5ebc6987656e84" | |||
| [[projects]] | |||
| digest = "1:d2463fd72ee2636c3d9bbdb98fa4996a118f210ae3e5eaf62d281855bc0b4a83" | |||
| @@ -19,7 +19,7 @@ ignored = ["google.golang.org/appengine*"] | |||
| name = "golang.org/x/crypto" | |||
| [[constraint]] | |||
| revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8" | |||
| branch = "master" | |||
| name = "golang.org/x/sys" | |||
| [[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. | |||
| // The runtime may know about them. | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-64 | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| JMP syscall·Syscall(SB) | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-88 | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
| JMP syscall·Syscall6(SB) | |||
| TEXT ·Syscall9(SB),NOSPLIT,$0-112 | |||
| TEXT ·Syscall9(SB),NOSPLIT,$0-104 | |||
| JMP syscall·Syscall9(SB) | |||
| TEXT ·RawSyscall(SB),NOSPLIT,$0-64 | |||
| TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
| JMP syscall·RawSyscall(SB) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-88 | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
| JMP syscall·RawSyscall6(SB) | |||
| @@ -10,21 +10,51 @@ | |||
| // 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. | |||
| // The runtime may know about them. | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
| JMP syscall·Syscall(SB) | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
| 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 | |||
| JMP syscall·RawSyscall(SB) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
| 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 | |||
| JMP syscall·socketcall(SB) | |||
| @@ -13,17 +13,45 @@ | |||
| // Just jump to package syscall's implementation for all these functions. | |||
| // The runtime may know about them. | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| JMP syscall·Syscall(SB) | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
| JMP syscall·Syscall6(SB) | |||
| TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 | |||
| 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 | |||
| JMP syscall·RawSyscall(SB) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
| 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 | |||
| JMP syscall·gettimeofday(SB) | |||
| @@ -13,17 +13,44 @@ | |||
| // Just jump to package syscall's implementation for all these functions. | |||
| // The runtime may know about them. | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
| B syscall·Syscall(SB) | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
| 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 | |||
| B syscall·RawSyscall(SB) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
| 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) | |||
| @@ -11,14 +11,42 @@ | |||
| // Just jump to package syscall's implementation for all these functions. | |||
| // The runtime may know about them. | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| B syscall·Syscall(SB) | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
| 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 | |||
| B syscall·RawSyscall(SB) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
| 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. | |||
| // The runtime may know about them. | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| JMP syscall·Syscall(SB) | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
| 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) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
| JMP syscall·RawSyscall6(SB) | |||
| TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 | |||
| MOVV a1+8(FP), R4 | |||
| MOVV a2+16(FP), R5 | |||
| MOVV a3+24(FP), R6 | |||
| MOVV R0, R7 | |||
| MOVV R0, R8 | |||
| MOVV R0, R9 | |||
| MOVV trap+0(FP), 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. | |||
| // The runtime may know about them. | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
| BR syscall·Syscall(SB) | |||
| TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
| 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 | |||
| BR syscall·RawSyscall(SB) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
| 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 | |||
| 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 | |||
| BR syscall·RawSyscall(SB) | |||
| TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
| 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 | |||
| // | |||
| TEXT ·sysvicall6(SB),NOSPLIT,$0-64 | |||
| TEXT ·sysvicall6(SB),NOSPLIT,$0-88 | |||
| JMP syscall·sysvicall6(SB) | |||
| TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64 | |||
| TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88 | |||
| 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 | |||
| // 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 | |||
| @@ -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 | |||
| // 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. | |||
| @@ -25,3 +25,7 @@ func Clearenv() { | |||
| func Environ() []string { | |||
| 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. | |||
| // Use of this source code is governed by a BSD-style | |||
| // 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. | |||
| 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. | |||
| func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { | |||
| _, _, 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. | |||
| // 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 | |||
| // license that can be found in the LICENSE file. | |||
| // +build gccgo | |||
| // +build !aix | |||
| package unix | |||
| 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. | |||
| //extern gccgoRealSyscallNoError | |||
| func realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr) | |||
| //extern gccgoRealSyscall | |||
| 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) { | |||
| syscall.Entersyscall() | |||
| 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) | |||
| } | |||
| 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) { | |||
| r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) | |||
| 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 | |||
| // license that can be found in the LICENSE file. | |||
| // +build gccgo | |||
| // +build !aix | |||
| #include <errno.h> | |||
| #include <stdint.h> | |||
| @@ -31,11 +32,8 @@ gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintp | |||
| 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 | |||
| // 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 | |||
| // 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 | |||
| import ( | |||
| "bytes" | |||
| "fmt" | |||
| "go/format" | |||
| "io/ioutil" | |||
| @@ -21,42 +22,77 @@ import ( | |||
| ) | |||
| 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) | |||
| if err != nil { | |||
| 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 | |||
| b, err = format.Source([]byte(s)) | |||
| b, err = format.Source(b) | |||
| if err != nil { | |||
| 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 | |||
| // 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 | |||
| // 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 | |||
| @@ -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 | |||
| // 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 | |||
| // 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 | |||
| @@ -12,10 +12,11 @@ import "unsafe" | |||
| // Round the length of a raw sockaddr up to align it properly. | |||
| 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 | |||
| } | |||
| return (salen + salign - 1) & ^(salign - 1) | |||
| @@ -2,7 +2,7 @@ | |||
| // 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 aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||
| package unix | |||
| @@ -2,35 +2,36 @@ | |||
| // 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 aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||
| // 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 | |||
| // 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 | |||
| // to freebsd and $GOARCH to arm. | |||
| // | |||
| // The primary use of this package is inside other packages that provide a more | |||
| // portable interface to the system, such as "os", "time" and "net". Use | |||
| // those packages rather than this one if you can. | |||
| // | |||
| // For details of the functions and data types in this package consult | |||
| // the manuals for the appropriate operating system. | |||
| // | |||
| // These calls return err == nil to indicate success; otherwise | |||
| // err represents an operating system error describing the failure and | |||
| // holds a value of type syscall.Errno. | |||
| package unix // import "golang.org/x/sys/unix" | |||
| import "unsafe" | |||
| import "strings" | |||
| // ByteSliceFromString returns a NUL-terminated slice of bytes | |||
| // containing the text of s. If s contains a NUL byte at any | |||
| // location, it returns (nil, EINVAL). | |||
| func ByteSliceFromString(s string) ([]byte, error) { | |||
| for i := 0; i < len(s); i++ { | |||
| if s[i] == 0 { | |||
| return nil, EINVAL | |||
| } | |||
| if strings.IndexByte(s, 0) != -1 { | |||
| return nil, EINVAL | |||
| } | |||
| a := make([]byte, len(s)+1) | |||
| 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. | |||
| // See mkunix.pl. | |||
| var _zero uintptr | |||
| func (ts *Timespec) Unix() (sec int64, nsec int64) { | |||
| return int64(ts.Sec), int64(ts.Nsec) | |||
| } | |||
| func (tv *Timeval) Unix() (sec int64, nsec int64) { | |||
| return int64(tv.Sec), int64(tv.Usec) * 1000 | |||
| } | |||
| func (ts *Timespec) Nano() int64 { | |||
| return int64(ts.Sec)*1e9 + int64(ts.Nsec) | |||
| } | |||
| func (tv *Timeval) Nano() int64 { | |||
| return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 | |||
| } | |||
| 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 | |||
| } | |||
| // Sanity check group count. Max is 16 on BSD. | |||
| // Sanity check group count. Max is 16 on BSD. | |||
| if n < 0 || n > 1000 { | |||
| return nil, EINVAL | |||
| } | |||
| @@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
| 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 { | |||
| case AF_LINK: | |||
| pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa)) | |||
| @@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||
| Close(nfd) | |||
| return 0, nil, ECONNABORTED | |||
| } | |||
| sa, err = anyToSockaddr(&rsa) | |||
| sa, err = anyToSockaddr(fd, &rsa) | |||
| if err != nil { | |||
| Close(nfd) | |||
| nfd = 0 | |||
| @@ -306,50 +306,21 @@ func Getsockname(fd int) (sa Sockaddr, err error) { | |||
| rsa.Addr.Family = AF_UNIX | |||
| rsa.Addr.Len = SizeofSockaddrUnix | |||
| } | |||
| return anyToSockaddr(&rsa) | |||
| return anyToSockaddr(fd, &rsa) | |||
| } | |||
| //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) | |||
| @@ -385,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from | |||
| recvflags = int(msg.Flags) | |||
| // source address is only specified if the socket is unconnected | |||
| if rsa.Addr.Family != AF_UNSPEC { | |||
| from, err = anyToSockaddr(&rsa) | |||
| from, err = anyToSockaddr(fd, &rsa) | |||
| } | |||
| return | |||
| } | |||
| @@ -470,25 +441,11 @@ func Sysctl(name string) (string, error) { | |||
| } | |||
| func SysctlArgs(name string, args ...int) (string, error) { | |||
| mib, err := sysctlmib(name, args...) | |||
| buf, err := SysctlRaw(name, args...) | |||
| if err != nil { | |||
| 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. | |||
| 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 { | |||
| if ts == nil { | |||
| err := utimensat(AT_FDCWD, path, nil, 0) | |||
| if err != ENOSYS { | |||
| return err | |||
| } | |||
| 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 { | |||
| 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 | |||
| // Timeval have different types in the different OSes | |||
| tv := [2]Timeval{ | |||
| @@ -591,6 +559,20 @@ func UtimesNano(path string, ts []Timespec) error { | |||
| 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) | |||
| 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 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 | |||
| // Acct(name nil-string) (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) | |||
| 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) { | |||
| 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 | |||
| import ( | |||
| errorspkg "errors" | |||
| "errors" | |||
| "syscall" | |||
| "unsafe" | |||
| ) | |||
| @@ -36,6 +36,7 @@ func Getwd() (string, error) { | |||
| return "", ENOTSUP | |||
| } | |||
| // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. | |||
| type SockaddrDatalink struct { | |||
| Len 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 | |||
| // 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. | |||
| // I am scared that if we don't include the +2 here, the kernel | |||
| // 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 | |||
| } | |||
| // 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) | |||
| 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) } | |||
| @@ -125,7 +98,7 @@ type attrList struct { | |||
| func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) { | |||
| if len(attrBuf) < 4 { | |||
| return nil, errorspkg.New("attrBuf too small") | |||
| return nil, errors.New("attrBuf too small") | |||
| } | |||
| attrList.bitmapCount = attrBitMapCount | |||
| @@ -144,7 +117,6 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) ( | |||
| uintptr(options), | |||
| 0, | |||
| ) | |||
| use(unsafe.Pointer(_p0)) | |||
| if e1 != 0 { | |||
| 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); { | |||
| header := dat[i:] | |||
| if len(header) < 8 { | |||
| return attrs, errorspkg.New("truncated attribute header") | |||
| return attrs, errors.New("truncated attribute header") | |||
| } | |||
| datOff := *(*int32)(unsafe.Pointer(&header[0])) | |||
| attrLen := *(*uint32)(unsafe.Pointer(&header[4])) | |||
| 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 | |||
| 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)) | |||
| } | |||
| r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags)) | |||
| use(unsafe.Pointer(_p0)) | |||
| n = int(r0) | |||
| if e1 != 0 { | |||
| err = e1 | |||
| @@ -205,6 +176,148 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| 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 | |||
| */ | |||
| @@ -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) } | |||
| //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 | |||
| */ | |||
| @@ -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 Exchangedata(path1 string, path2 string, options 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 Fchflags(fd int, flags int) (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 Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) | |||
| //sys Flock(fd int, how 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 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 Fsync(fd int) (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 Lchown(path string, uid int, gid int) (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 Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 | |||
| //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 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 Openat(dirfd int, path string, mode int, perm uint32) (fd 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 Pwrite(fd int, p []byte, offset int64) (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 Readlinkat(dirfd int, path string, buf []byte) (n int, 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 Rmdir(path string) (err error) | |||
| //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 Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 | |||
| //sys Symlink(path string, link string) (err error) | |||
| //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) | |||
| //sys Sync() (err error) | |||
| //sys Truncate(path string, length int64) (err error) | |||
| //sys Umask(newmask int) (oldmask int) | |||
| //sys Undelete(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 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) | |||
| @@ -337,9 +541,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||
| // Add_profil | |||
| // Kdebug_trace | |||
| // Sigreturn | |||
| // Mmap | |||
| // Mlock | |||
| // Munlock | |||
| // Atsocket | |||
| // Kqueue_from_portset_np | |||
| // Kqueue_portset | |||
| @@ -349,18 +550,9 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||
| // Searchfs | |||
| // Delete | |||
| // Copyfile | |||
| // Poll | |||
| // Watchevent | |||
| // Waitevent | |||
| // Modwatch | |||
| // Getxattr | |||
| // Fgetxattr | |||
| // Setxattr | |||
| // Fsetxattr | |||
| // Removexattr | |||
| // Fremovexattr | |||
| // Listxattr | |||
| // Flistxattr | |||
| // Fsctl | |||
| // Initgroups | |||
| // Posix_spawn | |||
| @@ -432,8 +624,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||
| // Lio_listio | |||
| // __pthread_cond_wait | |||
| // Iopolicysys | |||
| // Mlockall | |||
| // Munlockall | |||
| // __pthread_kill | |||
| // __pthread_sigmask | |||
| // __sigwait | |||
| @@ -487,7 +677,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig | |||
| // Sendmsg_nocancel | |||
| // Recvfrom_nocancel | |||
| // Accept_nocancel | |||
| // Msync_nocancel | |||
| // Fcntl_nocancel | |||
| // Select_nocancel | |||
| // Fsync_nocancel | |||
| @@ -11,27 +11,18 @@ import ( | |||
| "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) | |||
| func Gettimeofday(tv *Timeval) (err error) { | |||
| // 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. | |||
| sec, usec, err := gettimeofday(tv) | |||
| tv.Sec = int32(sec) | |||
| @@ -11,29 +11,18 @@ import ( | |||
| "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) | |||
| func Gettimeofday(tv *Timeval) (err error) { | |||
| // 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. | |||
| sec, usec, err := gettimeofday(tv) | |||
| tv.Sec = sec | |||
| @@ -9,27 +9,18 @@ import ( | |||
| "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) | |||
| func Gettimeofday(tv *Timeval) (err error) { | |||
| // 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. | |||
| sec, usec, err := gettimeofday(tv) | |||
| 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 | |||
| // 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" | |||
| ) | |||
| 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) | |||
| func Gettimeofday(tv *Timeval) (err error) { | |||
| // 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. | |||
| sec, usec, err := gettimeofday(tv) | |||
| 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 | |||
| // license that can be found in the LICENSE file. | |||
| // FreeBSD system calls. | |||
| // DragonFly BSD 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. | |||
| @@ -14,6 +14,7 @@ package unix | |||
| import "unsafe" | |||
| // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. | |||
| type SockaddrDatalink struct { | |||
| Len 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 | |||
| // 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. | |||
| // I am scared that if we don't include the +2 here, the kernel | |||
| // 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 | |||
| } | |||
| // 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) | |||
| 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) | |||
| } | |||
| 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) { | |||
| var _p0 unsafe.Pointer | |||
| 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)) | |||
| } | |||
| r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | |||
| use(unsafe.Pointer(_p0)) | |||
| n = int(r0) | |||
| if e1 != 0 { | |||
| err = e1 | |||
| @@ -117,6 +127,113 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| 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 | |||
| */ | |||
| @@ -134,10 +251,12 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| //sys Fchdir(fd int) (err error) | |||
| //sys Fchflags(fd int, flags int) (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 Flock(fd int, how int) (err error) | |||
| //sys Fpathconf(fd int, name int) (val 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, stat *Statfs_t) (err error) | |||
| //sys Fsync(fd int) (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 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 Nanosleep(time *Timespec, leftover *Timespec) (err error) | |||
| //sys Open(path string, mode int, perm uint32) (fd 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 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 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 | |||
| @@ -220,7 +336,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // Getlogin | |||
| // Sigpending | |||
| // Sigaltstack | |||
| // Ioctl | |||
| // Reboot | |||
| // Execve | |||
| // Vfork | |||
| @@ -243,7 +358,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // Add_profil | |||
| // Kdebug_trace | |||
| // Sigreturn | |||
| // Mmap | |||
| // Atsocket | |||
| // Kqueue_from_portset_np | |||
| // Kqueue_portset | |||
| @@ -253,7 +367,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // Searchfs | |||
| // Delete | |||
| // Copyfile | |||
| // Poll | |||
| // Watchevent | |||
| // Waitevent | |||
| // Modwatch | |||
| @@ -388,7 +501,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // Sendmsg_nocancel | |||
| // Recvfrom_nocancel | |||
| // Accept_nocancel | |||
| // Msync_nocancel | |||
| // Fcntl_nocancel | |||
| // Select_nocancel | |||
| // Fsync_nocancel | |||
| @@ -400,7 +512,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // Pread_nocancel | |||
| // Pwrite_nocancel | |||
| // Waitid_nocancel | |||
| // Poll_nocancel | |||
| // Msgsnd_nocancel | |||
| // Msgrcv_nocancel | |||
| // Sem_wait_nocancel | |||
| @@ -11,21 +11,12 @@ import ( | |||
| "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) { | |||
| @@ -12,8 +12,36 @@ | |||
| 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 { | |||
| Len 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 | |||
| // 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. | |||
| // I am scared that if we don't include the +2 here, the kernel | |||
| // 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 | |||
| } | |||
| // 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 { | |||
| 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) { | |||
| @@ -113,7 +120,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { | |||
| if len > SizeofSockaddrAny { | |||
| panic("RawSockaddrAny too small") | |||
| } | |||
| sa, err = anyToSockaddr(&rsa) | |||
| sa, err = anyToSockaddr(fd, &rsa) | |||
| if err != nil { | |||
| Close(nfd) | |||
| nfd = 0 | |||
| @@ -121,252 +128,376 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { | |||
| 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) { | |||
| var _p0 unsafe.Pointer | |||
| var bufsize uintptr | |||
| var ( | |||
| _p0 unsafe.Pointer | |||
| bufsize uintptr | |||
| oldBuf []statfs_freebsd11_t | |||
| needsConvert bool | |||
| ) | |||
| 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) | |||
| if e1 != 0 { | |||
| err = e1 | |||
| } | |||
| if e1 == 0 && needsConvert { | |||
| for i := range oldBuf { | |||
| buf[i].convertFrom(&oldBuf[i]) | |||
| } | |||
| } | |||
| 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 { | |||
| 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 { | |||
| 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 { | |||
| 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 { | |||
| 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 { | |||
| 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 | |||
| } | |||
| 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 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 Chflags(path string, flags int) (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 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 Faccessat(dirfd int, path string, mode uint32, flags int) (err error) | |||
| //sys Fchdir(fd int) (err error) | |||
| //sys Fchflags(fd int, flags int) (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 Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) | |||
| //sys Flock(fd int, how 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 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) | |||
| //sysnb Getegid() (egid 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 Lchown(path string, uid int, gid int) (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 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 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 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 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 Pread(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 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 Renameat(fromfd int, from string, tofd int, to string) (err error) | |||
| //sys Revoke(path string) (err error) | |||
| //sys Rmdir(path string) (err error) | |||
| //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 Settimeofday(tp *Timeval) (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 Symlinkat(oldpath string, newdirfd int, newpath string) (err error) | |||
| //sys Sync() (err error) | |||
| //sys Truncate(path string, length int64) (err error) | |||
| //sys Umask(newmask int) (oldmask int) | |||
| //sys Undelete(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 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) | |||
| @@ -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 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 | |||
| @@ -510,30 +658,19 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||
| // Add_profil | |||
| // Kdebug_trace | |||
| // Sigreturn | |||
| // Mmap | |||
| // Mlock | |||
| // Munlock | |||
| // Atsocket | |||
| // Kqueue_from_portset_np | |||
| // Kqueue_portset | |||
| // Getattrlist | |||
| // Setattrlist | |||
| // Getdents | |||
| // Getdirentriesattr | |||
| // Searchfs | |||
| // Delete | |||
| // Copyfile | |||
| // Poll | |||
| // Watchevent | |||
| // Waitevent | |||
| // Modwatch | |||
| // Getxattr | |||
| // Fgetxattr | |||
| // Setxattr | |||
| // Fsetxattr | |||
| // Removexattr | |||
| // Fremovexattr | |||
| // Listxattr | |||
| // Flistxattr | |||
| // Fsctl | |||
| // Initgroups | |||
| // Posix_spawn | |||
| @@ -605,8 +742,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||
| // Lio_listio | |||
| // __pthread_cond_wait | |||
| // Iopolicysys | |||
| // Mlockall | |||
| // Munlockall | |||
| // __pthread_kill | |||
| // __pthread_sigmask | |||
| // __sigwait | |||
| @@ -659,7 +794,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { | |||
| // Sendmsg_nocancel | |||
| // Recvfrom_nocancel | |||
| // Accept_nocancel | |||
| // Msync_nocancel | |||
| // Fcntl_nocancel | |||
| // Select_nocancel | |||
| // Fsync_nocancel | |||
| @@ -11,21 +11,12 @@ import ( | |||
| "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) { | |||
| @@ -11,21 +11,12 @@ import ( | |||
| "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) { | |||
| @@ -11,21 +11,12 @@ import ( | |||
| "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) { | |||
| @@ -10,25 +10,15 @@ | |||
| package unix | |||
| import ( | |||
| "syscall" | |||
| "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) | |||
| @@ -60,9 +50,12 @@ func Pipe2(p []int, flags int) (err error) { | |||
| // 64-bit file system and 32-bit uid calls | |||
| // (386 default is 32-bit file system and 16-bit uid). | |||
| //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 Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 | |||
| //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 | |||
| //sysnb Getegid() (egid int) = SYS_GETEGID32 | |||
| //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 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) | |||
| //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32 | |||
| //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 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) | |||
| 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) | |||
| } | |||
| // 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) { | |||
| newoffset, errno := seek(fd, offset, whence) | |||
| if errno != 0 { | |||
| @@ -177,17 +166,17 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { | |||
| return newoffset, nil | |||
| } | |||
| // Vsyscalls on amd64. | |||
| //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) | |||
| // On x86 Linux, all the socket calls go through an extra indirection, | |||
| // 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 | |||
| // 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. | |||
| const ( | |||
| @@ -214,9 +203,6 @@ const ( | |||
| _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) { | |||
| fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) | |||
| if e != 0 { | |||
| @@ -6,13 +6,13 @@ | |||
| package unix | |||
| import "syscall" | |||
| //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 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 Ftruncate(fd int, length int64) (err error) | |||
| //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 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) | |||
| 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) | |||
| @@ -41,10 +49,16 @@ import "syscall" | |||
| //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) | |||
| 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 SyncFileRange(fd int, off int64, n int64, flags int) (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 accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, 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 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) { | |||
| errno := gettimeofday(tv) | |||
| @@ -74,8 +87,6 @@ func Gettimeofday(tv *Timeval) (err error) { | |||
| return nil | |||
| } | |||
| func Getpagesize() int { return 4096 } | |||
| func Time(t *Time_t) (tt Time_t, err error) { | |||
| var tv Timeval | |||
| 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 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) | |||
| @@ -155,3 +160,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||
| } | |||
| 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" | |||
| ) | |||
| 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) { | |||
| @@ -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 | |||
| // (16-bit uid calls are not always supported in newer kernels) | |||
| //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 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 Geteuid() (euid int) = SYS_GETEUID32 | |||
| //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 Listen(s int, n int) (err error) | |||
| //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 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 | |||
| @@ -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 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 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) | |||
| //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) | |||
| //sys Pause() (err error) | |||
| func Time(t *Time_t) (Time_t, error) { | |||
| var tv Timeval | |||
| @@ -131,6 +125,8 @@ func Utime(path string, buf *Utimbuf) error { | |||
| 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 Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 | |||
| //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 | |||
| @@ -6,9 +6,17 @@ | |||
| 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 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) | |||
| @@ -23,7 +31,15 @@ const _SYS_dup = SYS_DUP3 | |||
| //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_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 Setfsgid(gid 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 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) | |||
| @@ -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 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) | |||
| 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) { | |||
| @@ -107,6 +131,18 @@ func Utime(path string, buf *Utimbuf) error { | |||
| 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 | |||
| @@ -155,30 +191,11 @@ func Dup2(oldfd int, newfd int) (err error) { | |||
| 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) { | |||
| var ts *Timespec | |||
| 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 | |||
| // 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 Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 | |||
| //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 Ftruncate(fd int, length int64) (err error) | |||
| //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 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_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 Setfsgid(gid 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 SyncFileRange(fd int, off int64, n int64, flags int) (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 accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, 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 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) | |||
| 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 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) { | |||
| @@ -189,9 +188,9 @@ func fillStat_t(s *Stat_t, st *stat_t) { | |||
| 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) { | |||
| 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 | |||
| //sys EpollWait(epfd int, events []EpollEvent, msec int) (n 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 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 Ftruncate(fd int, length int64) (err error) | |||
| //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 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 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 Setfsgid(gid 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 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_SYNC_FILE_RANGE2 | |||
| //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 accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, 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 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 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) | |||
| 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 } | |||
| @@ -133,3 +128,24 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||
| } | |||
| 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) | |||
| //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 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 Ftruncate(fd int, length int64) (err error) | |||
| //sysnb Getegid() (egid int) | |||
| @@ -43,11 +45,11 @@ import ( | |||
| //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 Ustat(dev int, ubuf *Ustat_t) (err error) | |||
| //sysnb getgroups(n int, list *_Gid_t) (nn int, 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) | |||
| 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 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) | |||
| @@ -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) { | |||
| 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) | |||
| use(unsafe.Pointer(&mmap_args[0])) | |||
| xaddr = uintptr(r0) | |||
| if e1 != 0 { | |||
| err = errnoErr(e1) | |||
| @@ -327,3 +322,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||
| } | |||
| 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" | |||
| ) | |||
| // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. | |||
| type SockaddrDatalink struct { | |||
| Len 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) { | |||
| // Split name into components. | |||
| var parts []string | |||
| last := 0 | |||
| @@ -93,32 +93,21 @@ func nametomib(name string) (mib []_C_int, err error) { | |||
| 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) | |||
| @@ -135,11 +124,118 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { | |||
| 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 | |||
| func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
| 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 | |||
| */ | |||
| @@ -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 Dup2(from int, to int) (err error) | |||
| //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 Fchflags(fd int, flags int) (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 Flock(fd int, how int) (err error) | |||
| //sys Fpathconf(fd int, name int) (val 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 Fsync(fd int) (err error) | |||
| //sys Ftruncate(fd int, length int64) (err error) | |||
| //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 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 Nanosleep(time *Timespec, leftover *Timespec) (err error) | |||
| //sys Open(path string, mode int, perm uint32) (fd 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 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 utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||
| /* | |||
| * Unimplemented | |||
| @@ -245,7 +353,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e | |||
| // __msync13 | |||
| // __ntp_gettime30 | |||
| // __posix_chown | |||
| // __posix_fadvise50 | |||
| // __posix_fchown | |||
| // __posix_lchown | |||
| // __posix_rename | |||
| @@ -404,7 +511,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e | |||
| // getitimer | |||
| // getvfsstat | |||
| // getxattr | |||
| // ioctl | |||
| // ktrace | |||
| // lchflags | |||
| // lchmod | |||
| @@ -442,7 +548,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e | |||
| // ntp_adjtime | |||
| // pmc_control | |||
| // pmc_get_info | |||
| // poll | |||
| // pollts | |||
| // preadv | |||
| // profil | |||
| @@ -6,21 +6,12 @@ | |||
| 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) { | |||
| @@ -6,21 +6,12 @@ | |||
| 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) { | |||
| @@ -6,21 +6,12 @@ | |||
| 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) { | |||
| @@ -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 | |||
| import ( | |||
| "sort" | |||
| "syscall" | |||
| "unsafe" | |||
| ) | |||
| // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. | |||
| type SockaddrDatalink struct { | |||
| Len 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 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 | |||
| } | |||
| // 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) | |||
| @@ -98,6 +77,23 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { | |||
| 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 | |||
| func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
| 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)) | |||
| } | |||
| r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | |||
| use(unsafe.Pointer(_p0)) | |||
| n = int(r0) | |||
| if e1 != 0 { | |||
| err = e1 | |||
| @@ -119,6 +114,105 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| 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 | |||
| */ | |||
| @@ -133,13 +227,16 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| //sys Dup(fd int) (nfd int, err error) | |||
| //sys Dup2(from int, to 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 Fchflags(fd int, flags int) (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 Flock(fd int, how int) (err error) | |||
| //sys Fpathconf(fd int, name int) (val 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, stat *Statfs_t) (err error) | |||
| //sys Fsync(fd int) (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) | |||
| //sys Getpriority(which int, who int) (prio int, 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 Getsid(pid int) (sid int, 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 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 Nanosleep(time *Timespec, leftover *Timespec) (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 Pread(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 Setresuid(ruid int, euid int, suid int) (err error) | |||
| //sysnb Setrlimit(which int, lim *Rlimit) (err error) | |||
| //sysnb Setrtable(rtable int) (err error) | |||
| //sysnb Setsid() (pid int, err error) | |||
| //sysnb Settimeofday(tp *Timeval) (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 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 utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||
| /* | |||
| * Unimplemented | |||
| @@ -241,9 +337,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // getlogin | |||
| // getresgid | |||
| // getresuid | |||
| // getrtable | |||
| // getthrid | |||
| // ioctl | |||
| // ktrace | |||
| // lfs_bmapv | |||
| // lfs_markv | |||
| @@ -263,8 +357,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // msgsnd | |||
| // nfssvc | |||
| // nnpfspioctl | |||
| // openat | |||
| // poll | |||
| // preadv | |||
| // profil | |||
| // pwritev | |||
| @@ -279,7 +371,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // semop | |||
| // setgroups | |||
| // setitimer | |||
| // setrtable | |||
| // setsockopt | |||
| // shmat | |||
| // shmctl | |||
| @@ -299,6 +390,5 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
| // thrsleep | |||
| // thrwakeup | |||
| // unlinkat | |||
| // utimensat | |||
| // vfork | |||
| // writev | |||
| @@ -6,21 +6,12 @@ | |||
| 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) { | |||
| @@ -40,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) { | |||
| 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/386 the syscall is called sysctl instead of __sysctl. | |||
| const SYS___SYSCTL = SYS_SYSCTL | |||
| @@ -6,21 +6,12 @@ | |||
| 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) { | |||
| @@ -40,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) { | |||
| 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/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 | |||
| import ( | |||
| "sync/atomic" | |||
| "syscall" | |||
| "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 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 { | |||
| Family uint16 | |||
| Index uint16 | |||
| @@ -35,55 +35,20 @@ type SockaddrDatalink struct { | |||
| 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) { | |||
| if len(p) != 2 { | |||
| 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) { | |||
| @@ -147,7 +112,19 @@ func Getsockname(fd int) (sa Sockaddr, err error) { | |||
| if err = getsockname(fd, &rsa, &len); err != nil { | |||
| 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 | |||
| @@ -177,7 +154,7 @@ func Getwd() (wd string, err error) { | |||
| func Getgroups() (gids []int, err error) { | |||
| 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). | |||
| if n < 0 || n > 1024 { | |||
| if err != nil { | |||
| @@ -269,24 +246,34 @@ func (w WaitStatus) StopSignal() syscall.Signal { | |||
| 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) { | |||
| 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) | |||
| @@ -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) | |||
| // 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. | |||
| 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) | |||
| @@ -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 | |||
| // 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. | |||
| func Futimes(fd int, tv []Timeval) error { | |||
| if tv == nil { | |||
| @@ -363,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error { | |||
| 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 { | |||
| case AF_UNIX: | |||
| pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) | |||
| @@ -414,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||
| if nfd == -1 { | |||
| return | |||
| } | |||
| sa, err = anyToSockaddr(&rsa) | |||
| sa, err = anyToSockaddr(fd, &rsa) | |||
| if err != nil { | |||
| Close(nfd) | |||
| nfd = 0 | |||
| @@ -422,7 +419,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||
| 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) { | |||
| 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.SetLen(1) | |||
| } | |||
| msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) | |||
| msg.Accrightslen = int32(len(oob)) | |||
| } | |||
| msg.Iov = &iov | |||
| 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) | |||
| // source address is only specified if the socket is unconnected | |||
| if rsa.Addr.Family != AF_UNSPEC { | |||
| from, err = anyToSockaddr(&rsa) | |||
| from, err = anyToSockaddr(fd, &rsa) | |||
| } | |||
| return | |||
| } | |||
| @@ -461,7 +458,7 @@ func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { | |||
| 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) { | |||
| 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.SetLen(1) | |||
| } | |||
| msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) | |||
| msg.Accrightslen = int32(len(oob)) | |||
| } | |||
| msg.Iov = &iov | |||
| msg.Iovlen = 1 | |||
| @@ -515,52 +512,79 @@ func Acct(path string) (err error) { | |||
| 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 | |||
| */ | |||
| //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)) | |||
| } | |||
| 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))) | |||
| } | |||
| 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))) | |||
| } | |||
| 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))) | |||
| } | |||
| func IoctlGetInt(fd int, req int) (int, error) { | |||
| 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 int) (*Winsize, error) { | |||
| 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 int) (*Termios, error) { | |||
| func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
| var value Termios | |||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
| return &value, err | |||
| } | |||
| func IoctlGetTermio(fd int, req int) (*Termio, error) { | |||
| func IoctlGetTermio(fd int, req uint) (*Termio, error) { | |||
| var value Termio | |||
| err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
| 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 | |||
| */ | |||
| @@ -575,14 +599,18 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { | |||
| //sys Dup(fd int) (nfd int, err error) | |||
| //sys Dup2(oldfd int, newfd 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 Fchown(fd int, uid int, gid int) (err error) | |||
| //sys Fchownat(dirfd int, path string, uid int, gid int, flags 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 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) | |||
| //sysnb Getgid() (gid 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 Lchown(path string, uid int, gid int) (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 Madvise(b []byte, advice int) (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 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) | |||
| //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 Rmdir(path string) (err error) | |||
| //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 Seteuid(euid 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) | |||
| //sys Shutdown(s int, how int) (err error) = libsocket.shutdown | |||
| //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 Sync() (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 Ustat(dev int, ubuf *Ustat_t) (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 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 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 | |||
| //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 | |||
| @@ -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) { | |||
| 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 | |||
| 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) { | |||
| @@ -28,8 +21,3 @@ func (iov *Iovec) SetLen(length int) { | |||
| func (cmsg *Cmsghdr) SetLen(length int) { | |||
| 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 | |||
| // 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 | |||
| import ( | |||
| "bytes" | |||
| "runtime" | |||
| "sort" | |||
| "sync" | |||
| "syscall" | |||
| "unsafe" | |||
| @@ -20,9 +22,10 @@ var ( | |||
| ) | |||
| 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 | |||
| @@ -49,10 +52,36 @@ func errnoErr(e syscall.Errno) error { | |||
| 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. | |||
| @@ -142,16 +171,19 @@ func Write(fd int, p []byte) (n int, err error) { | |||
| // creation of IPv6 sockets to return EAFNOSUPPORT. | |||
| var SocketDisableIPv6 bool | |||
| // Sockaddr represents a socket address. | |||
| type Sockaddr interface { | |||
| 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 { | |||
| Port int | |||
| Addr [4]byte | |||
| raw RawSockaddrInet4 | |||
| } | |||
| // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets. | |||
| type SockaddrInet6 struct { | |||
| Port int | |||
| ZoneId uint32 | |||
| @@ -159,6 +191,7 @@ type SockaddrInet6 struct { | |||
| raw RawSockaddrInet6 | |||
| } | |||
| // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets. | |||
| type SockaddrUnix struct { | |||
| Name string | |||
| raw RawSockaddrUnix | |||
| @@ -186,7 +219,14 @@ func Getpeername(fd int) (sa Sockaddr, err error) { | |||
| if err = getpeername(fd, &rsa, &len); err != nil { | |||
| 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) { | |||
| @@ -196,6 +236,54 @@ func GetsockoptInt(fd, level, opt int) (value int, err error) { | |||
| 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) { | |||
| var rsa RawSockaddrAny | |||
| var len _Socklen = SizeofSockaddrAny | |||
| @@ -203,7 +291,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { | |||
| return | |||
| } | |||
| if rsa.Addr.Family != AF_UNSPEC { | |||
| from, err = anyToSockaddr(&rsa) | |||
| from, err = anyToSockaddr(fd, &rsa) | |||
| } | |||
| return | |||
| } | |||
| @@ -295,3 +383,12 @@ func SetNonblock(fd int, nonblocking bool) (err error) { | |||
| _, err = fcntl(fd, F_SETFL, flag) | |||
| 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 | |||
| /* | |||
| 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 */ | |||
| @@ -19,6 +19,7 @@ package unix | |||
| #define _DARWIN_USE_64_BIT_INODE | |||
| #include <dirent.h> | |||
| #include <fcntl.h> | |||
| #include <poll.h> | |||
| #include <signal.h> | |||
| #include <termios.h> | |||
| #include <unistd.h> | |||
| @@ -38,6 +39,7 @@ package unix | |||
| #include <sys/types.h> | |||
| #include <sys/uio.h> | |||
| #include <sys/un.h> | |||
| #include <sys/utsname.h> | |||
| #include <sys/wait.h> | |||
| #include <net/bpf.h> | |||
| #include <net/if.h> | |||
| @@ -68,14 +70,14 @@ struct sockaddr_any { | |||
| */ | |||
| import "C" | |||
| // Machine characteristics; for internal use. | |||
| // Machine characteristics | |||
| 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 | |||
| @@ -242,9 +244,34 @@ type BpfHdr C.struct_bpf_hdr | |||
| 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 | |||
| 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 | |||
| /* | |||
| 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 */ | |||
| @@ -17,6 +17,7 @@ package unix | |||
| #define KERNEL | |||
| #include <dirent.h> | |||
| #include <fcntl.h> | |||
| #include <poll.h> | |||
| #include <signal.h> | |||
| #include <termios.h> | |||
| #include <stdio.h> | |||
| @@ -34,6 +35,7 @@ package unix | |||
| #include <sys/time.h> | |||
| #include <sys/types.h> | |||
| #include <sys/un.h> | |||
| #include <sys/utsname.h> | |||
| #include <sys/wait.h> | |||
| #include <net/bpf.h> | |||
| #include <net/if.h> | |||
| @@ -63,14 +65,14 @@ struct sockaddr_any { | |||
| */ | |||
| import "C" | |||
| // Machine characteristics; for internal use. | |||
| // Machine characteristics | |||
| 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 | |||
| @@ -98,23 +100,6 @@ type _Gid_t C.gid_t | |||
| // 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 Statfs_t C.struct_statfs | |||
| @@ -125,6 +110,12 @@ type Dirent C.struct_dirent | |||
| type Fsid C.struct_fsid | |||
| // File system limits | |||
| const ( | |||
| PathMax = C.PATH_MAX | |||
| ) | |||
| // Sockets | |||
| type RawSockaddrInet4 C.struct_sockaddr_in | |||
| @@ -240,3 +231,33 @@ type BpfHdr C.struct_bpf_hdr | |||
| // Terminal handling | |||
| 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 | |||
| /* | |||
| 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 */ | |||
| @@ -14,13 +14,19 @@ Input to cgo -godefs. See also mkerrors.sh and mkall.sh | |||
| 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 <fcntl.h> | |||
| #include <poll.h> | |||
| #include <signal.h> | |||
| #include <termios.h> | |||
| #include <stdio.h> | |||
| #include <unistd.h> | |||
| #include <sys/capability.h> | |||
| #include <sys/event.h> | |||
| #include <sys/mman.h> | |||
| #include <sys/mount.h> | |||
| @@ -34,6 +40,7 @@ package unix | |||
| #include <sys/time.h> | |||
| #include <sys/types.h> | |||
| #include <sys/un.h> | |||
| #include <sys/utsname.h> | |||
| #include <sys/wait.h> | |||
| #include <net/bpf.h> | |||
| #include <net/if.h> | |||
| @@ -60,50 +67,6 @@ struct sockaddr_any { | |||
| 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. | |||
| // See /usr/include/net/if.h. | |||
| struct if_data8 { | |||
| @@ -130,7 +93,10 @@ struct if_data8 { | |||
| u_long ifi_iqdrops; | |||
| u_long ifi_noproto; | |||
| u_long ifi_hwassist; | |||
| // FIXME: these are now unions, so maybe need to change definitions? | |||
| #undef ifi_epoch | |||
| time_t ifi_epoch; | |||
| #undef ifi_lastchange | |||
| struct timeval ifi_lastchange; | |||
| }; | |||
| @@ -148,14 +114,14 @@ struct if_msghdr8 { | |||
| */ | |||
| import "C" | |||
| // Machine characteristics; for internal use. | |||
| // Machine characteristics | |||
| 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 | |||
| @@ -183,33 +149,33 @@ type _Gid_t C.gid_t | |||
| // 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_freebsd11_t C.struct_freebsd11_statfs | |||
| type Flock_t C.struct_flock | |||
| type Dirent C.struct_dirent | |||
| type dirent_freebsd11 C.struct_freebsd11_dirent | |||
| type Fsid C.struct_fsid | |||
| // File system limits | |||
| const ( | |||
| PathMax = C.PATH_MAX | |||
| ) | |||
| // Advice to Fadvise | |||
| const ( | |||
| @@ -284,7 +250,7 @@ const ( | |||
| // Events (kqueue, kevent) | |||
| type Kevent_t C.struct_kevent | |||
| type Kevent_t C.struct_kevent_freebsd11 | |||
| // Select | |||
| @@ -351,3 +317,40 @@ type BpfZbufHeader C.struct_bpf_zbuf_header | |||
| // Terminal handling | |||
| 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 | |||