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