1
2
3
4
5
6
7
8 package unix
9
10 import (
11 "bytes"
12 "sort"
13 "sync"
14 "syscall"
15 "unsafe"
16 )
17
18 var (
19 Stdin = 0
20 Stdout = 1
21 Stderr = 2
22 )
23
24
25
26 var (
27 errEAGAIN error = syscall.EAGAIN
28 errEINVAL error = syscall.EINVAL
29 errENOENT error = syscall.ENOENT
30 )
31
32 var (
33 signalNameMapOnce sync.Once
34 signalNameMap map[string]syscall.Signal
35 )
36
37
38
39 func errnoErr(e syscall.Errno) error {
40 switch e {
41 case 0:
42 return nil
43 case EAGAIN:
44 return errEAGAIN
45 case EINVAL:
46 return errEINVAL
47 case ENOENT:
48 return errENOENT
49 }
50 return e
51 }
52
53
54 func ErrnoName(e syscall.Errno) string {
55 i := sort.Search(len(errorList), func(i int) bool {
56 return errorList[i].num >= e
57 })
58 if i < len(errorList) && errorList[i].num == e {
59 return errorList[i].name
60 }
61 return ""
62 }
63
64
65 func SignalName(s syscall.Signal) string {
66 i := sort.Search(len(signalList), func(i int) bool {
67 return signalList[i].num >= s
68 })
69 if i < len(signalList) && signalList[i].num == s {
70 return signalList[i].name
71 }
72 return ""
73 }
74
75
76
77
78 func SignalNum(s string) syscall.Signal {
79 signalNameMapOnce.Do(func() {
80 signalNameMap = make(map[string]syscall.Signal, len(signalList))
81 for _, signal := range signalList {
82 signalNameMap[signal.name] = signal.num
83 }
84 })
85 return signalNameMap[s]
86 }
87
88
89 func clen(n []byte) int {
90 i := bytes.IndexByte(n, 0)
91 if i == -1 {
92 i = len(n)
93 }
94 return i
95 }
96
97
98
99 type mmapper struct {
100 sync.Mutex
101 active map[*byte][]byte
102 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
103 munmap func(addr uintptr, length uintptr) error
104 }
105
106 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
107 if length <= 0 {
108 return nil, EINVAL
109 }
110
111
112 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
113 if errno != nil {
114 return nil, errno
115 }
116
117
118 b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
119
120
121 p := &b[cap(b)-1]
122 m.Lock()
123 defer m.Unlock()
124 m.active[p] = b
125 return b, nil
126 }
127
128 func (m *mmapper) Munmap(data []byte) (err error) {
129 if len(data) == 0 || len(data) != cap(data) {
130 return EINVAL
131 }
132
133
134 p := &data[cap(data)-1]
135 m.Lock()
136 defer m.Unlock()
137 b := m.active[p]
138 if b == nil || &b[0] != &data[0] {
139 return EINVAL
140 }
141
142
143 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
144 return errno
145 }
146 delete(m.active, p)
147 return nil
148 }
149
150 func Read(fd int, p []byte) (n int, err error) {
151 n, err = read(fd, p)
152 if raceenabled {
153 if n > 0 {
154 raceWriteRange(unsafe.Pointer(&p[0]), n)
155 }
156 if err == nil {
157 raceAcquire(unsafe.Pointer(&ioSync))
158 }
159 }
160 return
161 }
162
163 func Write(fd int, p []byte) (n int, err error) {
164 if raceenabled {
165 raceReleaseMerge(unsafe.Pointer(&ioSync))
166 }
167 n, err = write(fd, p)
168 if raceenabled && n > 0 {
169 raceReadRange(unsafe.Pointer(&p[0]), n)
170 }
171 return
172 }
173
174 func Pread(fd int, p []byte, offset int64) (n int, err error) {
175 n, err = pread(fd, p, offset)
176 if raceenabled {
177 if n > 0 {
178 raceWriteRange(unsafe.Pointer(&p[0]), n)
179 }
180 if err == nil {
181 raceAcquire(unsafe.Pointer(&ioSync))
182 }
183 }
184 return
185 }
186
187 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
188 if raceenabled {
189 raceReleaseMerge(unsafe.Pointer(&ioSync))
190 }
191 n, err = pwrite(fd, p, offset)
192 if raceenabled && n > 0 {
193 raceReadRange(unsafe.Pointer(&p[0]), n)
194 }
195 return
196 }
197
198
199
200 var SocketDisableIPv6 bool
201
202
203 type Sockaddr interface {
204 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
205 }
206
207
208 type SockaddrInet4 struct {
209 Port int
210 Addr [4]byte
211 raw RawSockaddrInet4
212 }
213
214
215 type SockaddrInet6 struct {
216 Port int
217 ZoneId uint32
218 Addr [16]byte
219 raw RawSockaddrInet6
220 }
221
222
223 type SockaddrUnix struct {
224 Name string
225 raw RawSockaddrUnix
226 }
227
228 func Bind(fd int, sa Sockaddr) (err error) {
229 ptr, n, err := sa.sockaddr()
230 if err != nil {
231 return err
232 }
233 return bind(fd, ptr, n)
234 }
235
236 func Connect(fd int, sa Sockaddr) (err error) {
237 ptr, n, err := sa.sockaddr()
238 if err != nil {
239 return err
240 }
241 return connect(fd, ptr, n)
242 }
243
244 func Getpeername(fd int) (sa Sockaddr, err error) {
245 var rsa RawSockaddrAny
246 var len _Socklen = SizeofSockaddrAny
247 if err = getpeername(fd, &rsa, &len); err != nil {
248 return
249 }
250 return anyToSockaddr(fd, &rsa)
251 }
252
253 func GetsockoptByte(fd, level, opt int) (value byte, err error) {
254 var n byte
255 vallen := _Socklen(1)
256 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
257 return n, err
258 }
259
260 func GetsockoptInt(fd, level, opt int) (value int, err error) {
261 var n int32
262 vallen := _Socklen(4)
263 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
264 return int(n), err
265 }
266
267 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
268 vallen := _Socklen(4)
269 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
270 return value, err
271 }
272
273 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
274 var value IPMreq
275 vallen := _Socklen(SizeofIPMreq)
276 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
277 return &value, err
278 }
279
280 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
281 var value IPv6Mreq
282 vallen := _Socklen(SizeofIPv6Mreq)
283 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
284 return &value, err
285 }
286
287 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
288 var value IPv6MTUInfo
289 vallen := _Socklen(SizeofIPv6MTUInfo)
290 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
291 return &value, err
292 }
293
294 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
295 var value ICMPv6Filter
296 vallen := _Socklen(SizeofICMPv6Filter)
297 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
298 return &value, err
299 }
300
301 func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
302 var linger Linger
303 vallen := _Socklen(SizeofLinger)
304 err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
305 return &linger, err
306 }
307
308 func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
309 var tv Timeval
310 vallen := _Socklen(unsafe.Sizeof(tv))
311 err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
312 return &tv, err
313 }
314
315 func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
316 var n uint64
317 vallen := _Socklen(8)
318 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
319 return n, err
320 }
321
322 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
323 var rsa RawSockaddrAny
324 var len _Socklen = SizeofSockaddrAny
325 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
326 return
327 }
328 if rsa.Addr.Family != AF_UNSPEC {
329 from, err = anyToSockaddr(fd, &rsa)
330 }
331 return
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
348 var iov [1]Iovec
349 if len(p) > 0 {
350 iov[0].Base = &p[0]
351 iov[0].SetLen(len(p))
352 }
353 var rsa RawSockaddrAny
354 n, oobn, recvflags, err = recvmsgRaw(fd, iov[:], oob, flags, &rsa)
355
356 if rsa.Addr.Family != AF_UNSPEC {
357 from, err = anyToSockaddr(fd, &rsa)
358 }
359 return
360 }
361
362
363
364
365 func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
366 iov := make([]Iovec, len(buffers))
367 for i := range buffers {
368 if len(buffers[i]) > 0 {
369 iov[i].Base = &buffers[i][0]
370 iov[i].SetLen(len(buffers[i]))
371 } else {
372 iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
373 }
374 }
375 var rsa RawSockaddrAny
376 n, oobn, recvflags, err = recvmsgRaw(fd, iov, oob, flags, &rsa)
377 if err == nil && rsa.Addr.Family != AF_UNSPEC {
378 from, err = anyToSockaddr(fd, &rsa)
379 }
380 return
381 }
382
383
384
385
386 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
387 _, err = SendmsgN(fd, p, oob, to, flags)
388 return
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
416 var iov [1]Iovec
417 if len(p) > 0 {
418 iov[0].Base = &p[0]
419 iov[0].SetLen(len(p))
420 }
421 var ptr unsafe.Pointer
422 var salen _Socklen
423 if to != nil {
424 ptr, salen, err = to.sockaddr()
425 if err != nil {
426 return 0, err
427 }
428 }
429 return sendmsgN(fd, iov[:], oob, ptr, salen, flags)
430 }
431
432
433
434
435 func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) {
436 iov := make([]Iovec, len(buffers))
437 for i := range buffers {
438 if len(buffers[i]) > 0 {
439 iov[i].Base = &buffers[i][0]
440 iov[i].SetLen(len(buffers[i]))
441 } else {
442 iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
443 }
444 }
445 var ptr unsafe.Pointer
446 var salen _Socklen
447 if to != nil {
448 ptr, salen, err = to.sockaddr()
449 if err != nil {
450 return 0, err
451 }
452 }
453 return sendmsgN(fd, iov, oob, ptr, salen, flags)
454 }
455
456 func Send(s int, buf []byte, flags int) (err error) {
457 return sendto(s, buf, flags, nil, 0)
458 }
459
460 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
461 var ptr unsafe.Pointer
462 var salen _Socklen
463 if to != nil {
464 ptr, salen, err = to.sockaddr()
465 if err != nil {
466 return err
467 }
468 }
469 return sendto(fd, p, flags, ptr, salen)
470 }
471
472 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
473 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
474 }
475
476 func SetsockoptInt(fd, level, opt int, value int) (err error) {
477 var n = int32(value)
478 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
479 }
480
481 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
482 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
483 }
484
485 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
486 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
487 }
488
489 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
490 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
491 }
492
493 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
494 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
495 }
496
497 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
498 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
499 }
500
501 func SetsockoptString(fd, level, opt int, s string) (err error) {
502 var p unsafe.Pointer
503 if len(s) > 0 {
504 p = unsafe.Pointer(&[]byte(s)[0])
505 }
506 return setsockopt(fd, level, opt, p, uintptr(len(s)))
507 }
508
509 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
510 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
511 }
512
513 func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
514 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
515 }
516
517 func Socket(domain, typ, proto int) (fd int, err error) {
518 if domain == AF_INET6 && SocketDisableIPv6 {
519 return -1, EAFNOSUPPORT
520 }
521 fd, err = socket(domain, typ, proto)
522 return
523 }
524
525 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
526 var fdx [2]int32
527 err = socketpair(domain, typ, proto, &fdx)
528 if err == nil {
529 fd[0] = int(fdx[0])
530 fd[1] = int(fdx[1])
531 }
532 return
533 }
534
535 var ioSync int64
536
537 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
538
539 func SetNonblock(fd int, nonblocking bool) (err error) {
540 flag, err := fcntl(fd, F_GETFL, 0)
541 if err != nil {
542 return err
543 }
544 if nonblocking {
545 flag |= O_NONBLOCK
546 } else {
547 flag &= ^O_NONBLOCK
548 }
549 _, err = fcntl(fd, F_SETFL, flag)
550 return err
551 }
552
553
554
555
556
557
558 func Exec(argv0 string, argv []string, envv []string) error {
559 return syscall.Exec(argv0, argv, envv)
560 }
561
562
563
564
565
566
567 func Lutimes(path string, tv []Timeval) error {
568 if tv == nil {
569 return UtimesNanoAt(AT_FDCWD, path, nil, AT_SYMLINK_NOFOLLOW)
570 }
571 if len(tv) != 2 {
572 return EINVAL
573 }
574 ts := []Timespec{
575 NsecToTimespec(TimevalToNsec(tv[0])),
576 NsecToTimespec(TimevalToNsec(tv[1])),
577 }
578 return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW)
579 }
580
581
582 func emptyIovecs(iov []Iovec) bool {
583 for i := range iov {
584 if iov[i].Len > 0 {
585 return false
586 }
587 }
588 return true
589 }
590
View as plain text