Source file
src/syscall/syscall_unix.go
Documentation: syscall
1
2
3
4
5
6
7
8 package syscall
9
10 import (
11 "internal/itoa"
12 "internal/oserror"
13 "internal/race"
14 "internal/unsafeheader"
15 "runtime"
16 "sync"
17 "unsafe"
18 )
19
20 var (
21 Stdin = 0
22 Stdout = 1
23 Stderr = 2
24 )
25
26 const (
27 darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
28 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
29 )
30
31 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
32 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
33 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
34 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
35
36
37 func clen(n []byte) int {
38 for i := 0; i < len(n); i++ {
39 if n[i] == 0 {
40 return i
41 }
42 }
43 return len(n)
44 }
45
46
47
48 type mmapper struct {
49 sync.Mutex
50 active map[*byte][]byte
51 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
52 munmap func(addr uintptr, length uintptr) error
53 }
54
55 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
56 if length <= 0 {
57 return nil, EINVAL
58 }
59
60
61 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
62 if errno != nil {
63 return nil, errno
64 }
65
66
67 var b []byte
68 hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
69 hdr.Data = unsafe.Pointer(addr)
70 hdr.Cap = length
71 hdr.Len = length
72
73
74 p := &b[cap(b)-1]
75 m.Lock()
76 defer m.Unlock()
77 m.active[p] = b
78 return b, nil
79 }
80
81 func (m *mmapper) Munmap(data []byte) (err error) {
82 if len(data) == 0 || len(data) != cap(data) {
83 return EINVAL
84 }
85
86
87 p := &data[cap(data)-1]
88 m.Lock()
89 defer m.Unlock()
90 b := m.active[p]
91 if b == nil || &b[0] != &data[0] {
92 return EINVAL
93 }
94
95
96 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
97 return errno
98 }
99 delete(m.active, p)
100 return nil
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 type Errno uintptr
117
118 func (e Errno) Error() string {
119 if 0 <= int(e) && int(e) < len(errors) {
120 s := errors[e]
121 if s != "" {
122 return s
123 }
124 }
125 return "errno " + itoa.Itoa(int(e))
126 }
127
128 func (e Errno) Is(target error) bool {
129 switch target {
130 case oserror.ErrPermission:
131 return e == EACCES || e == EPERM
132 case oserror.ErrExist:
133 return e == EEXIST || e == ENOTEMPTY
134 case oserror.ErrNotExist:
135 return e == ENOENT
136 }
137 return false
138 }
139
140 func (e Errno) Temporary() bool {
141 return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout()
142 }
143
144 func (e Errno) Timeout() bool {
145 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
146 }
147
148
149
150 var (
151 errEAGAIN error = EAGAIN
152 errEINVAL error = EINVAL
153 errENOENT error = ENOENT
154 )
155
156
157
158 func errnoErr(e Errno) error {
159 switch e {
160 case 0:
161 return nil
162 case EAGAIN:
163 return errEAGAIN
164 case EINVAL:
165 return errEINVAL
166 case ENOENT:
167 return errENOENT
168 }
169 return e
170 }
171
172
173
174 type Signal int
175
176 func (s Signal) Signal() {}
177
178 func (s Signal) String() string {
179 if 0 <= s && int(s) < len(signals) {
180 str := signals[s]
181 if str != "" {
182 return str
183 }
184 }
185 return "signal " + itoa.Itoa(int(s))
186 }
187
188 func Read(fd int, p []byte) (n int, err error) {
189 n, err = read(fd, p)
190 if race.Enabled {
191 if n > 0 {
192 race.WriteRange(unsafe.Pointer(&p[0]), n)
193 }
194 if err == nil {
195 race.Acquire(unsafe.Pointer(&ioSync))
196 }
197 }
198 if msanenabled && n > 0 {
199 msanWrite(unsafe.Pointer(&p[0]), n)
200 }
201 return
202 }
203
204 func Write(fd int, p []byte) (n int, err error) {
205 if race.Enabled {
206 race.ReleaseMerge(unsafe.Pointer(&ioSync))
207 }
208 if faketime && (fd == 1 || fd == 2) {
209 n = faketimeWrite(fd, p)
210 if n < 0 {
211 n, err = 0, errnoErr(Errno(-n))
212 }
213 } else {
214 n, err = write(fd, p)
215 }
216 if race.Enabled && n > 0 {
217 race.ReadRange(unsafe.Pointer(&p[0]), n)
218 }
219 if msanenabled && n > 0 {
220 msanRead(unsafe.Pointer(&p[0]), n)
221 }
222 return
223 }
224
225
226
227 var SocketDisableIPv6 bool
228
229 type Sockaddr interface {
230 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
231 }
232
233 type SockaddrInet4 struct {
234 Port int
235 Addr [4]byte
236 raw RawSockaddrInet4
237 }
238
239 type SockaddrInet6 struct {
240 Port int
241 ZoneId uint32
242 Addr [16]byte
243 raw RawSockaddrInet6
244 }
245
246 type SockaddrUnix struct {
247 Name string
248 raw RawSockaddrUnix
249 }
250
251 func Bind(fd int, sa Sockaddr) (err error) {
252 ptr, n, err := sa.sockaddr()
253 if err != nil {
254 return err
255 }
256 return bind(fd, ptr, n)
257 }
258
259 func Connect(fd int, sa Sockaddr) (err error) {
260 ptr, n, err := sa.sockaddr()
261 if err != nil {
262 return err
263 }
264 return connect(fd, ptr, n)
265 }
266
267 func Getpeername(fd int) (sa Sockaddr, err error) {
268 var rsa RawSockaddrAny
269 var len _Socklen = SizeofSockaddrAny
270 if err = getpeername(fd, &rsa, &len); err != nil {
271 return
272 }
273 return anyToSockaddr(&rsa)
274 }
275
276 func GetsockoptInt(fd, level, opt int) (value int, err error) {
277 var n int32
278 vallen := _Socklen(4)
279 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
280 return int(n), err
281 }
282
283 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
284 var rsa RawSockaddrAny
285 var len _Socklen = SizeofSockaddrAny
286 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
287 return
288 }
289 if rsa.Addr.Family != AF_UNSPEC {
290 from, err = anyToSockaddr(&rsa)
291 }
292 return
293 }
294
295 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
296 ptr, n, err := to.sockaddr()
297 if err != nil {
298 return err
299 }
300 return sendto(fd, p, flags, ptr, n)
301 }
302
303 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
304 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
305 }
306
307 func SetsockoptInt(fd, level, opt int, value int) (err error) {
308 var n = int32(value)
309 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
310 }
311
312 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
313 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
314 }
315
316 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
317 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
318 }
319
320 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
321 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
322 }
323
324 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
325 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
326 }
327
328 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
329 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
330 }
331
332 func SetsockoptString(fd, level, opt int, s string) (err error) {
333 var p unsafe.Pointer
334 if len(s) > 0 {
335 p = unsafe.Pointer(&[]byte(s)[0])
336 }
337 return setsockopt(fd, level, opt, p, uintptr(len(s)))
338 }
339
340 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
341 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
342 }
343
344 func Socket(domain, typ, proto int) (fd int, err error) {
345 if domain == AF_INET6 && SocketDisableIPv6 {
346 return -1, EAFNOSUPPORT
347 }
348 fd, err = socket(domain, typ, proto)
349 return
350 }
351
352 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
353 var fdx [2]int32
354 err = socketpair(domain, typ, proto, &fdx)
355 if err == nil {
356 fd[0] = int(fdx[0])
357 fd[1] = int(fdx[1])
358 }
359 return
360 }
361
362 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
363 if race.Enabled {
364 race.ReleaseMerge(unsafe.Pointer(&ioSync))
365 }
366 return sendfile(outfd, infd, offset, count)
367 }
368
369 var ioSync int64
370
View as plain text