usb-ks

USB Killswitch
git clone git://git.laack.co/usb-ks.git
Log | Files | Refs | README | LICENSE

syscall_illumos.go (4297B)


      1 // Copyright 2021 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // illumos system calls not present on Solaris.
      6 
      7 //go:build amd64 && illumos
      8 // +build amd64,illumos
      9 
     10 package unix
     11 
     12 import (
     13 	"fmt"
     14 	"runtime"
     15 	"unsafe"
     16 )
     17 
     18 func bytes2iovec(bs [][]byte) []Iovec {
     19 	iovecs := make([]Iovec, len(bs))
     20 	for i, b := range bs {
     21 		iovecs[i].SetLen(len(b))
     22 		if len(b) > 0 {
     23 			// somehow Iovec.Base on illumos is (*int8), not (*byte)
     24 			iovecs[i].Base = (*int8)(unsafe.Pointer(&b[0]))
     25 		} else {
     26 			iovecs[i].Base = (*int8)(unsafe.Pointer(&_zero))
     27 		}
     28 	}
     29 	return iovecs
     30 }
     31 
     32 //sys	readv(fd int, iovs []Iovec) (n int, err error)
     33 
     34 func Readv(fd int, iovs [][]byte) (n int, err error) {
     35 	iovecs := bytes2iovec(iovs)
     36 	n, err = readv(fd, iovecs)
     37 	return n, err
     38 }
     39 
     40 //sys	preadv(fd int, iovs []Iovec, off int64) (n int, err error)
     41 
     42 func Preadv(fd int, iovs [][]byte, off int64) (n int, err error) {
     43 	iovecs := bytes2iovec(iovs)
     44 	n, err = preadv(fd, iovecs, off)
     45 	return n, err
     46 }
     47 
     48 //sys	writev(fd int, iovs []Iovec) (n int, err error)
     49 
     50 func Writev(fd int, iovs [][]byte) (n int, err error) {
     51 	iovecs := bytes2iovec(iovs)
     52 	n, err = writev(fd, iovecs)
     53 	return n, err
     54 }
     55 
     56 //sys	pwritev(fd int, iovs []Iovec, off int64) (n int, err error)
     57 
     58 func Pwritev(fd int, iovs [][]byte, off int64) (n int, err error) {
     59 	iovecs := bytes2iovec(iovs)
     60 	n, err = pwritev(fd, iovecs, off)
     61 	return n, err
     62 }
     63 
     64 //sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = libsocket.accept4
     65 
     66 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
     67 	var rsa RawSockaddrAny
     68 	var len _Socklen = SizeofSockaddrAny
     69 	nfd, err = accept4(fd, &rsa, &len, flags)
     70 	if err != nil {
     71 		return
     72 	}
     73 	if len > SizeofSockaddrAny {
     74 		panic("RawSockaddrAny too small")
     75 	}
     76 	sa, err = anyToSockaddr(fd, &rsa)
     77 	if err != nil {
     78 		Close(nfd)
     79 		nfd = 0
     80 	}
     81 	return
     82 }
     83 
     84 //sys	putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
     85 
     86 func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
     87 	var clp, datap *strbuf
     88 	if len(cl) > 0 {
     89 		clp = &strbuf{
     90 			Len: int32(len(cl)),
     91 			Buf: (*int8)(unsafe.Pointer(&cl[0])),
     92 		}
     93 	}
     94 	if len(data) > 0 {
     95 		datap = &strbuf{
     96 			Len: int32(len(data)),
     97 			Buf: (*int8)(unsafe.Pointer(&data[0])),
     98 		}
     99 	}
    100 	return putmsg(fd, clp, datap, flags)
    101 }
    102 
    103 //sys	getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
    104 
    105 func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
    106 	var clp, datap *strbuf
    107 	if len(cl) > 0 {
    108 		clp = &strbuf{
    109 			Maxlen: int32(len(cl)),
    110 			Buf:    (*int8)(unsafe.Pointer(&cl[0])),
    111 		}
    112 	}
    113 	if len(data) > 0 {
    114 		datap = &strbuf{
    115 			Maxlen: int32(len(data)),
    116 			Buf:    (*int8)(unsafe.Pointer(&data[0])),
    117 		}
    118 	}
    119 
    120 	if err = getmsg(fd, clp, datap, &flags); err != nil {
    121 		return nil, nil, 0, err
    122 	}
    123 
    124 	if len(cl) > 0 {
    125 		retCl = cl[:clp.Len]
    126 	}
    127 	if len(data) > 0 {
    128 		retData = data[:datap.Len]
    129 	}
    130 	return retCl, retData, flags, nil
    131 }
    132 
    133 func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
    134 	return ioctlRet(fd, req, uintptr(arg))
    135 }
    136 
    137 func IoctlSetString(fd int, req uint, val string) error {
    138 	bs := make([]byte, len(val)+1)
    139 	copy(bs[:len(bs)-1], val)
    140 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
    141 	runtime.KeepAlive(&bs[0])
    142 	return err
    143 }
    144 
    145 // Lifreq Helpers
    146 
    147 func (l *Lifreq) SetName(name string) error {
    148 	if len(name) >= len(l.Name) {
    149 		return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
    150 	}
    151 	for i := range name {
    152 		l.Name[i] = int8(name[i])
    153 	}
    154 	return nil
    155 }
    156 
    157 func (l *Lifreq) SetLifruInt(d int) {
    158 	*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
    159 }
    160 
    161 func (l *Lifreq) GetLifruInt() int {
    162 	return *(*int)(unsafe.Pointer(&l.Lifru[0]))
    163 }
    164 
    165 func (l *Lifreq) SetLifruUint(d uint) {
    166 	*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
    167 }
    168 
    169 func (l *Lifreq) GetLifruUint() uint {
    170 	return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
    171 }
    172 
    173 func IoctlLifreq(fd int, req uint, l *Lifreq) error {
    174 	return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
    175 }
    176 
    177 // Strioctl Helpers
    178 
    179 func (s *Strioctl) SetInt(i int) {
    180 	s.Len = int32(unsafe.Sizeof(i))
    181 	s.Dp = (*int8)(unsafe.Pointer(&i))
    182 }
    183 
    184 func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
    185 	return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
    186 }