khenaidoo | 7d3c558 | 2021-08-11 18:09:44 -0400 | [diff] [blame] | 1 | // Copyright 2021 The Go Authors. All rights reserved. |
Andrea Campanella | aec20bd | 2021-02-25 12:41:34 +0100 | [diff] [blame] | 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 | |
khenaidoo | 7d3c558 | 2021-08-11 18:09:44 -0400 | [diff] [blame] | 7 | //go:build amd64 && illumos |
Andrea Campanella | aec20bd | 2021-02-25 12:41:34 +0100 | [diff] [blame] | 8 | // +build amd64,illumos |
| 9 | |
| 10 | package unix |
| 11 | |
khenaidoo | 7d3c558 | 2021-08-11 18:09:44 -0400 | [diff] [blame] | 12 | import ( |
| 13 | "fmt" |
| 14 | "runtime" |
| 15 | "unsafe" |
| 16 | ) |
Andrea Campanella | aec20bd | 2021-02-25 12:41:34 +0100 | [diff] [blame] | 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 | |
khenaidoo | 7d3c558 | 2021-08-11 18:09:44 -0400 | [diff] [blame] | 84 | //sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) |
Andrea Campanella | aec20bd | 2021-02-25 12:41:34 +0100 | [diff] [blame] | 85 | |
khenaidoo | 7d3c558 | 2021-08-11 18:09:44 -0400 | [diff] [blame] | 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 | } |
Andrea Campanella | aec20bd | 2021-02-25 12:41:34 +0100 | [diff] [blame] | 93 | } |
khenaidoo | 7d3c558 | 2021-08-11 18:09:44 -0400 | [diff] [blame] | 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]) |
Andrea Campanella | aec20bd | 2021-02-25 12:41:34 +0100 | [diff] [blame] | 142 | return err |
| 143 | } |
khenaidoo | 7d3c558 | 2021-08-11 18:09:44 -0400 | [diff] [blame] | 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 IoctlLifreq(fd int, req uint, l *Lifreq) error { |
| 166 | return ioctl(fd, req, uintptr(unsafe.Pointer(l))) |
| 167 | } |
| 168 | |
| 169 | // Strioctl Helpers |
| 170 | |
| 171 | func (s *Strioctl) SetInt(i int) { |
| 172 | s.Len = int32(unsafe.Sizeof(i)) |
| 173 | s.Dp = (*int8)(unsafe.Pointer(&i)) |
| 174 | } |
| 175 | |
| 176 | func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) { |
| 177 | return ioctlRet(fd, req, uintptr(unsafe.Pointer(s))) |
| 178 | } |