mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-24 13:48:49 +08:00
system(syscall): switch to x/sys (#963)
This commit is contained in:
parent
0648f66ef8
commit
bc3d7d4194
@ -32,7 +32,7 @@ linters:
|
||||
# currently active linters:
|
||||
#
|
||||
#INFO [lintersdb] Active 35 linters: [asasalint asciicheck bidichk contextcheck decorder depguard durationcheck errcheck exportloopref
|
||||
# gocheckcompilerdirectives gomoddirectives gomodguard goprintffuncname gosimple govet grouper importas ineffassign mirror musttag
|
||||
# gocheckcompilerdirectives gomoddirectives gomodguard goprintffuncname gosimple govet grouper ineffassign mirror musttag
|
||||
# nilerr nilnil nolintlint nosprintfhostport prealloc reassign revive staticcheck tagalign tenv testableexamples tparallel typecheck unused wastedassign]
|
||||
|
||||
enable-all: true
|
||||
@ -62,6 +62,7 @@ linters:
|
||||
- goerr113 # not used (we allow error creation at return statement)
|
||||
- gofumpt # not used (we use "go fmt" or "gofmt" not gofumpt"
|
||||
- gosmopolitan # not needed (report i18n/l10n anti-patterns)
|
||||
- importas # not needed (there is no alias rule at the moment)
|
||||
- ireturn # not used (we allow return interfaces)
|
||||
- loggercheck # not needed (relates to kitlog, klog, logr, zap)
|
||||
- paralleltest # not used
|
||||
|
2
Makefile
2
Makefile
@ -16,7 +16,7 @@ including_except := $(shell go list ./... | grep -v platforms/opencv)
|
||||
|
||||
# Run tests on nearly all directories without test cache
|
||||
test:
|
||||
go test -count=1 -v $(including_except)
|
||||
go test -failfast -count=1 -v $(including_except)
|
||||
|
||||
# Run tests with race detection
|
||||
test_race:
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
@ -17,13 +16,13 @@ import (
|
||||
|
||||
const dev = "/dev/i2c-1"
|
||||
|
||||
func getSyscallFuncImpl(errorMask byte) func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
func getSyscallFuncImpl(errorMask byte) func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err system.SyscallErrno) {
|
||||
// bit 0: error on function query
|
||||
// bit 1: error on set address
|
||||
// bit 2: error on command
|
||||
return func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
return func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err system.SyscallErrno) {
|
||||
// function query
|
||||
if (trap == syscall.SYS_IOCTL) && (a2 == system.I2C_FUNCS) {
|
||||
if (trap == system.Syscall_SYS_IOCTL) && (a2 == system.I2C_FUNCS) {
|
||||
if errorMask&0x01 == 0x01 {
|
||||
return 0, 0, 1
|
||||
}
|
||||
@ -35,13 +34,13 @@ func getSyscallFuncImpl(errorMask byte) func(trap, a1, a2, a3 uintptr) (r1, r2 u
|
||||
system.I2C_FUNC_SMBUS_WRITE_WORD_DATA
|
||||
}
|
||||
// set address
|
||||
if (trap == syscall.SYS_IOCTL) && (a2 == system.I2C_SLAVE) {
|
||||
if (trap == system.Syscall_SYS_IOCTL) && (a2 == system.I2C_SLAVE) {
|
||||
if errorMask&0x02 == 0x02 {
|
||||
return 0, 0, 1
|
||||
}
|
||||
}
|
||||
// command
|
||||
if (trap == syscall.SYS_IOCTL) && (a2 == system.I2C_SMBUS) {
|
||||
if (trap == system.Syscall_SYS_IOCTL) && (a2 == system.I2C_SMBUS) {
|
||||
if errorMask&0x04 == 0x04 {
|
||||
return 0, 0, 1
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
@ -92,7 +91,7 @@ func (d *digitalPinSysfs) Unexport() error {
|
||||
if err != nil {
|
||||
// If EINVAL then the pin is reserved in the system and can't be unexported
|
||||
e, ok := err.(*os.PathError)
|
||||
if !ok || e.Err != syscall.EINVAL {
|
||||
if !ok || e.Err != Syscall_EINVAL {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -126,7 +125,7 @@ func (d *digitalPinSysfs) reconfigure() error {
|
||||
if err != nil {
|
||||
// If EBUSY then the pin has already been exported
|
||||
e, ok := err.(*os.PathError)
|
||||
if !ok || e.Err != syscall.EBUSY {
|
||||
if !ok || e.Err != Syscall_EBUSY {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package system
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
@ -63,7 +62,7 @@ func TestDigitalPin(t *testing.T) {
|
||||
gobottest.Assert(t, data, 0)
|
||||
|
||||
writeFile = func(File, []byte) (int, error) {
|
||||
return 0, &os.PathError{Err: syscall.EINVAL}
|
||||
return 0, &os.PathError{Err: Syscall_EINVAL}
|
||||
}
|
||||
|
||||
err = pin.Unexport()
|
||||
@ -81,7 +80,7 @@ func TestDigitalPin(t *testing.T) {
|
||||
writeFile = func(File, []byte) (int, error) {
|
||||
cnt++
|
||||
if cnt == 1 {
|
||||
return 0, &os.PathError{Err: syscall.EBUSY}
|
||||
return 0, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
@ -104,7 +103,7 @@ func TestDigitalPinExportError(t *testing.T) {
|
||||
pin, _ := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths)
|
||||
|
||||
writeFile = func(File, []byte) (int, error) {
|
||||
return 0, &os.PathError{Err: syscall.EBUSY}
|
||||
return 0, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
|
||||
err := pin.Export()
|
||||
@ -118,7 +117,7 @@ func TestDigitalPinUnexportError(t *testing.T) {
|
||||
pin, _ := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths)
|
||||
|
||||
writeFile = func(File, []byte) (int, error) {
|
||||
return 0, &os.PathError{Err: syscall.EBUSY}
|
||||
return 0, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
|
||||
err := pin.Unexport()
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -375,7 +374,7 @@ func (d *i2cDevice) syscallIoctl(signal uintptr, payload unsafe.Pointer, sender
|
||||
if err := d.openFileLazy(sender); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, _, errno := d.sys.syscall(syscall.SYS_IOCTL, d.file, signal, payload); errno != 0 {
|
||||
if _, _, errno := d.sys.syscall(Syscall_SYS_IOCTL, d.file, signal, payload); errno != 0 {
|
||||
return fmt.Errorf("%s failed with syscall.Errno %v", sender, errno)
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package system
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
@ -13,13 +12,13 @@ import (
|
||||
|
||||
const dev = "/dev/i2c-1"
|
||||
|
||||
func getSyscallFuncImpl(errorMask byte) func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
func getSyscallFuncImpl(errorMask byte) func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) {
|
||||
// bit 0: error on function query
|
||||
// bit 1: error on set address
|
||||
// bit 2: error on command
|
||||
return func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
return func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) {
|
||||
// function query
|
||||
if (trap == syscall.SYS_IOCTL) && (a2 == I2C_FUNCS) {
|
||||
if (trap == Syscall_SYS_IOCTL) && (a2 == I2C_FUNCS) {
|
||||
if errorMask&0x01 == 0x01 {
|
||||
return 0, 0, 1
|
||||
}
|
||||
@ -31,13 +30,13 @@ func getSyscallFuncImpl(errorMask byte) func(trap, a1, a2, a3 uintptr) (r1, r2 u
|
||||
I2C_FUNC_SMBUS_WRITE_WORD_DATA
|
||||
}
|
||||
// set address
|
||||
if (trap == syscall.SYS_IOCTL) && (a2 == I2C_SLAVE) {
|
||||
if (trap == Syscall_SYS_IOCTL) && (a2 == I2C_SLAVE) {
|
||||
if errorMask&0x02 == 0x02 {
|
||||
return 0, 0, 1
|
||||
}
|
||||
}
|
||||
// command
|
||||
if (trap == syscall.SYS_IOCTL) && (a2 == I2C_SMBUS) {
|
||||
if (trap == Syscall_SYS_IOCTL) && (a2 == I2C_SMBUS) {
|
||||
if errorMask&0x04 == 0x04 {
|
||||
return 0, 0, 1
|
||||
}
|
||||
@ -117,7 +116,7 @@ func TestWriteRead(t *testing.T) {
|
||||
func TestReadByte(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"read_byte_ok": {
|
||||
@ -161,7 +160,7 @@ func TestReadByte(t *testing.T) {
|
||||
func TestReadByteData(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"read_byte_data_ok": {
|
||||
@ -208,7 +207,7 @@ func TestReadByteData(t *testing.T) {
|
||||
func TestReadWordData(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"read_word_data_ok": {
|
||||
@ -272,7 +271,7 @@ func TestReadBlockData(t *testing.T) {
|
||||
)
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"read_block_data_ok": {
|
||||
@ -317,7 +316,7 @@ func TestReadBlockData(t *testing.T) {
|
||||
func TestWriteByte(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"write_byte_ok": {
|
||||
@ -359,7 +358,7 @@ func TestWriteByte(t *testing.T) {
|
||||
func TestWriteByteData(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"write_byte_data_ok": {
|
||||
@ -406,7 +405,7 @@ func TestWriteByteData(t *testing.T) {
|
||||
func TestWriteWordData(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"write_word_data_ok": {
|
||||
@ -471,7 +470,7 @@ func TestWriteBlockData(t *testing.T) {
|
||||
)
|
||||
var tests = map[string]struct {
|
||||
funcs uint64
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
}{
|
||||
"write_block_data_ok": {
|
||||
@ -533,7 +532,7 @@ func Test_queryFunctionality(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
requested uint64
|
||||
dev string
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
wantErr string
|
||||
wantFile bool
|
||||
wantFuncs uint64
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -50,7 +49,7 @@ func (p *pwmPinSysFs) Export() error {
|
||||
if err != nil {
|
||||
// If EBUSY then the pin has already been exported
|
||||
e, ok := err.(*os.PathError)
|
||||
if !ok || e.Err != syscall.EBUSY {
|
||||
if !ok || e.Err != Syscall_EBUSY {
|
||||
return fmt.Errorf(pwmPinErrorPattern, "Export", p.pin, err)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package system
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
@ -85,7 +84,7 @@ func TestPwmPinAlreadyExported(t *testing.T) {
|
||||
pin, _ := initTestPWMPinSysFsWithMockedFilesystem(mockedPaths)
|
||||
|
||||
pin.write = func(filesystem, string, []byte) (int, error) {
|
||||
return 0, &os.PathError{Err: syscall.EBUSY}
|
||||
return 0, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
|
||||
// no error indicates that the pin was already exported
|
||||
@ -103,7 +102,7 @@ func TestPwmPinExportError(t *testing.T) {
|
||||
pin, _ := initTestPWMPinSysFsWithMockedFilesystem(mockedPaths)
|
||||
|
||||
pin.write = func(filesystem, string, []byte) (int, error) {
|
||||
return 0, &os.PathError{Err: syscall.EFAULT}
|
||||
return 0, &os.PathError{Err: Syscall_EFAULT}
|
||||
}
|
||||
|
||||
// no error indicates that the pin was already exported
|
||||
@ -122,7 +121,7 @@ func TestPwmPinUnxportError(t *testing.T) {
|
||||
pin, _ := initTestPWMPinSysFsWithMockedFilesystem(mockedPaths)
|
||||
|
||||
pin.write = func(filesystem, string, []byte) (int, error) {
|
||||
return 0, &os.PathError{Err: syscall.EBUSY}
|
||||
return 0, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
|
||||
err := pin.Unexport()
|
||||
@ -140,7 +139,7 @@ func TestPwmPinPeriodError(t *testing.T) {
|
||||
pin, _ := initTestPWMPinSysFsWithMockedFilesystem(mockedPaths)
|
||||
|
||||
pin.read = func(filesystem, string) ([]byte, error) {
|
||||
return nil, &os.PathError{Err: syscall.EBUSY}
|
||||
return nil, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
|
||||
_, err := pin.Period()
|
||||
@ -158,7 +157,7 @@ func TestPwmPinPolarityError(t *testing.T) {
|
||||
pin, _ := initTestPWMPinSysFsWithMockedFilesystem(mockedPaths)
|
||||
|
||||
pin.read = func(filesystem, string) ([]byte, error) {
|
||||
return nil, &os.PathError{Err: syscall.EBUSY}
|
||||
return nil, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
|
||||
_, err := pin.Polarity()
|
||||
@ -176,7 +175,7 @@ func TestPwmPinDutyCycleError(t *testing.T) {
|
||||
pin, _ := initTestPWMPinSysFsWithMockedFilesystem(mockedPaths)
|
||||
|
||||
pin.read = func(filesystem, string) ([]byte, error) {
|
||||
return nil, &os.PathError{Err: syscall.EBUSY}
|
||||
return nil, &os.PathError{Err: Syscall_EBUSY}
|
||||
}
|
||||
|
||||
_, err := pin.DutyCycle()
|
||||
|
@ -1,14 +1,32 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// SyscallErrno wraps the "unix.Errno"
|
||||
type SyscallErrno unix.Errno
|
||||
|
||||
// wrapping for used constants of unix package
|
||||
const (
|
||||
Syscall_SYS_IOCTL = unix.SYS_IOCTL
|
||||
Syscall_EINVAL = unix.EINVAL
|
||||
Syscall_EBUSY = unix.EBUSY
|
||||
Syscall_EFAULT = unix.EFAULT
|
||||
)
|
||||
|
||||
// nativeSyscall represents the native Syscall
|
||||
type nativeSyscall struct{}
|
||||
|
||||
// Syscall calls the native syscall.Syscall, implements the SystemCaller interface
|
||||
func (sys *nativeSyscall) syscall(trap uintptr, f File, signal uintptr, payload unsafe.Pointer) (r1, r2 uintptr, err syscall.Errno) {
|
||||
return syscall.Syscall(trap, f.Fd(), signal, uintptr(payload))
|
||||
// Syscall calls the native unix.Syscall, implements the SystemCaller interface
|
||||
func (sys *nativeSyscall) syscall(trap uintptr, f File, signal uintptr, payload unsafe.Pointer) (r1, r2 uintptr, err SyscallErrno) {
|
||||
r1, r2, errNo := unix.Syscall(trap, f.Fd(), signal, uintptr(payload))
|
||||
return r1, r2, SyscallErrno(errNo)
|
||||
}
|
||||
|
||||
// Error implements the error interface. It wraps the "unix.Errno.Error()".
|
||||
func (e SyscallErrno) Error() string {
|
||||
return unix.Errno(e).Error()
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -14,11 +13,11 @@ type mockSyscall struct {
|
||||
smbus *i2cSmbusIoctlData
|
||||
sliceSize uint8
|
||||
dataSlice []byte
|
||||
Impl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
Impl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno)
|
||||
}
|
||||
|
||||
// Syscall calls the user defined implementation, used for tests, implements the SystemCaller interface
|
||||
func (sys *mockSyscall) syscall(trap uintptr, f File, signal uintptr, payload unsafe.Pointer) (r1, r2 uintptr, err syscall.Errno) {
|
||||
func (sys *mockSyscall) syscall(trap uintptr, f File, signal uintptr, payload unsafe.Pointer) (r1, r2 uintptr, err SyscallErrno) {
|
||||
sys.lastTrap = trap // points to the used syscall (e.g. "SYS_IOCTL")
|
||||
sys.lastFile = f // a character device file (e.g. file to path "/dev/i2c-1")
|
||||
sys.lastSignal = signal // points to used function type (e.g. I2C_SMBUS, I2C_RDWR)
|
||||
|
@ -2,7 +2,6 @@ package system
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
@ -33,7 +32,7 @@ type filesystem interface {
|
||||
// systemCaller represents unexposed Syscall interface to allow the switch between native and mocked implementation
|
||||
// Prevent unsafe call, since go 1.15, see "Pattern 4" in: https://go101.org/article/unsafe.html
|
||||
type systemCaller interface {
|
||||
syscall(trap uintptr, f File, signal uintptr, payload unsafe.Pointer) (r1, r2 uintptr, err syscall.Errno)
|
||||
syscall(trap uintptr, f File, signal uintptr, payload unsafe.Pointer) (r1, r2 uintptr, err SyscallErrno)
|
||||
}
|
||||
|
||||
// digitalPinAccesser represents unexposed interface to allow the switch between different implementations and
|
||||
|
Loading…
x
Reference in New Issue
Block a user