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 n, oobn, recvflags, err = recvmsgRaw(fd, iov[:], oob, flags, &rsa)
371
372 if rsa.Addr.Family != AF_UNSPEC {
373 from, err = anyToSockaddr(fd, &rsa)
374 }
375 return
376 }
377
378
379
380
381 func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
382 iov := make([]Iovec, len(buffers))
383 for i := range buffers {
384 if len(buffers[i]) > 0 {
385 iov[i].Base = &buffers[i][0]
386 iov[i].SetLen(len(buffers[i]))
387 } else {
388 iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
389 }
390 }
391 var rsa RawSockaddrAny
392 n, oobn, recvflags, err = recvmsgRaw(fd, iov, oob, flags, &rsa)
393 if err == nil && rsa.Addr.Family != AF_UNSPEC {
394 from, err = anyToSockaddr(fd, &rsa)
395 }
396 return
397 }
398
399
400
401
402 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
403 _, err = SendmsgN(fd, p, oob, to, flags)
404 return
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
432 var iov [1]Iovec
433 if len(p) > 0 {
434 iov[0].Base = &p[0]
435 iov[0].SetLen(len(p))
436 }
437 var ptr unsafe.Pointer
438 var salen _Socklen
439 if to != nil {
440 ptr, salen, err = to.sockaddr()
441 if err != nil {
442 return 0, err
443 }
444 }
445 return sendmsgN(fd, iov[:], oob, ptr, salen, flags)
446 }
447
448
449
450
451 func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) {
452 iov := make([]Iovec, len(buffers))
453 for i := range buffers {
454 if len(buffers[i]) > 0 {
455 iov[i].Base = &buffers[i][0]
456 iov[i].SetLen(len(buffers[i]))
457 } else {
458 iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
459 }
460 }
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 0, err
467 }
468 }
469 return sendmsgN(fd, iov, oob, ptr, salen, flags)
470 }
471
472 func Send(s int, buf []byte, flags int) (err error) {
473 return sendto(s, buf, flags, nil, 0)
474 }
475
476 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
477 var ptr unsafe.Pointer
478 var salen _Socklen
479 if to != nil {
480 ptr, salen, err = to.sockaddr()
481 if err != nil {
482 return err
483 }
484 }
485 return sendto(fd, p, flags, ptr, salen)
486 }
487
488 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
489 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
490 }
491
492 func SetsockoptInt(fd, level, opt int, value int) (err error) {
493 var n = int32(value)
494 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
495 }
496
497 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
498 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
499 }
500
501 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
502 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
503 }
504
505 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
506 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
507 }
508
509 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
510 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
511 }
512
513 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
514 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
515 }
516
517 func SetsockoptString(fd, level, opt int, s string) (err error) {
518 var p unsafe.Pointer
519 if len(s) > 0 {
520 p = unsafe.Pointer(&[]byte(s)[0])
521 }
522 return setsockopt(fd, level, opt, p, uintptr(len(s)))
523 }
524
525 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
526 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
527 }
528
529 func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
530 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
531 }
532
533 func Socket(domain, typ, proto int) (fd int, err error) {
534 if domain == AF_INET6 && SocketDisableIPv6 {
535 return -1, EAFNOSUPPORT
536 }
537 fd, err = socket(domain, typ, proto)
538 return
539 }
540
541 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
542 var fdx [2]int32
543 err = socketpair(domain, typ, proto, &fdx)
544 if err == nil {
545 fd[0] = int(fdx[0])
546 fd[1] = int(fdx[1])
547 }
548 return
549 }
550
551 var ioSync int64
552
553 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
554
555 func SetNonblock(fd int, nonblocking bool) (err error) {
556 flag, err := fcntl(fd, F_GETFL, 0)
557 if err != nil {
558 return err
559 }
560 if (flag&O_NONBLOCK != 0) == nonblocking {
561 return nil
562 }
563 if nonblocking {
564 flag |= O_NONBLOCK
565 } else {
566 flag &= ^O_NONBLOCK
567 }
568 _, err = fcntl(fd, F_SETFL, flag)
569 return err
570 }
571
572
573
574
575
576
577 func Exec(argv0 string, argv []string, envv []string) error {
578 return syscall.Exec(argv0, argv, envv)
579 }
580
581
582
583
584
585
586 func Lutimes(path string, tv []Timeval) error {
587 if tv == nil {
588 return UtimesNanoAt(AT_FDCWD, path, nil, AT_SYMLINK_NOFOLLOW)
589 }
590 if len(tv) != 2 {
591 return EINVAL
592 }
593 ts := []Timespec{
594 NsecToTimespec(TimevalToNsec(tv[0])),
595 NsecToTimespec(TimevalToNsec(tv[1])),
596 }
597 return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW)
598 }
599
600
601 func emptyIovecs(iov []Iovec) bool {
602 for i := range iov {
603 if iov[i].Len > 0 {
604 return false
605 }
606 }
607 return true
608 }
609
610
611 func Setrlimit(resource int, rlim *Rlimit) error {
612
613
614 return syscall.Setrlimit(resource, (*syscall.Rlimit)(rlim))
615 }
616
View as plain text