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 Read(fd int, p []byte) (n int, err error) {
158 n, err = read(fd, p)
159 if raceenabled {
160 if n > 0 {
161 raceWriteRange(unsafe.Pointer(&p[0]), n)
162 }
163 if err == nil {
164 raceAcquire(unsafe.Pointer(&ioSync))
165 }
166 }
167 return
168 }
169
170 func Write(fd int, p []byte) (n int, err error) {
171 if raceenabled {
172 raceReleaseMerge(unsafe.Pointer(&ioSync))
173 }
174 n, err = write(fd, p)
175 if raceenabled && n > 0 {
176 raceReadRange(unsafe.Pointer(&p[0]), n)
177 }
178 return
179 }
180
181 func Pread(fd int, p []byte, offset int64) (n int, err error) {
182 n, err = pread(fd, p, offset)
183 if raceenabled {
184 if n > 0 {
185 raceWriteRange(unsafe.Pointer(&p[0]), n)
186 }
187 if err == nil {
188 raceAcquire(unsafe.Pointer(&ioSync))
189 }
190 }
191 return
192 }
193
194 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
195 if raceenabled {
196 raceReleaseMerge(unsafe.Pointer(&ioSync))
197 }
198 n, err = pwrite(fd, p, offset)
199 if raceenabled && n > 0 {
200 raceReadRange(unsafe.Pointer(&p[0]), n)
201 }
202 return
203 }
204
205
206
207 var SocketDisableIPv6 bool
208
209
210 type Sockaddr interface {
211 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
212 }
213
214
215 type SockaddrInet4 struct {
216 Port int
217 Addr [4]byte
218 raw RawSockaddrInet4
219 }
220
221
222 type SockaddrInet6 struct {
223 Port int
224 ZoneId uint32
225 Addr [16]byte
226 raw RawSockaddrInet6
227 }
228
229
230 type SockaddrUnix struct {
231 Name string
232 raw RawSockaddrUnix
233 }
234
235 func Bind(fd int, sa Sockaddr) (err error) {
236 ptr, n, err := sa.sockaddr()
237 if err != nil {
238 return err
239 }
240 return bind(fd, ptr, n)
241 }
242
243 func Connect(fd int, sa Sockaddr) (err error) {
244 ptr, n, err := sa.sockaddr()
245 if err != nil {
246 return err
247 }
248 return connect(fd, ptr, n)
249 }
250
251 func Getpeername(fd int) (sa Sockaddr, err error) {
252 var rsa RawSockaddrAny
253 var len _Socklen = SizeofSockaddrAny
254 if err = getpeername(fd, &rsa, &len); err != nil {
255 return
256 }
257 return anyToSockaddr(fd, &rsa)
258 }
259
260 func GetsockoptByte(fd, level, opt int) (value byte, err error) {
261 var n byte
262 vallen := _Socklen(1)
263 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
264 return n, err
265 }
266
267 func GetsockoptInt(fd, level, opt int) (value int, err error) {
268 var n int32
269 vallen := _Socklen(4)
270 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
271 return int(n), err
272 }
273
274 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
275 vallen := _Socklen(4)
276 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
277 return value, err
278 }
279
280 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
281 var value IPMreq
282 vallen := _Socklen(SizeofIPMreq)
283 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
284 return &value, err
285 }
286
287 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
288 var value IPv6Mreq
289 vallen := _Socklen(SizeofIPv6Mreq)
290 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
291 return &value, err
292 }
293
294 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
295 var value IPv6MTUInfo
296 vallen := _Socklen(SizeofIPv6MTUInfo)
297 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
298 return &value, err
299 }
300
301 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
302 var value ICMPv6Filter
303 vallen := _Socklen(SizeofICMPv6Filter)
304 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
305 return &value, err
306 }
307
308 func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
309 var linger Linger
310 vallen := _Socklen(SizeofLinger)
311 err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
312 return &linger, err
313 }
314
315 func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
316 var tv Timeval
317 vallen := _Socklen(unsafe.Sizeof(tv))
318 err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
319 return &tv, err
320 }
321
322 func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
323 var n uint64
324 vallen := _Socklen(8)
325 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
326 return n, err
327 }
328
329 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
330 var rsa RawSockaddrAny
331 var len _Socklen = SizeofSockaddrAny
332 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
333 return
334 }
335 if rsa.Addr.Family != AF_UNSPEC {
336 from, err = anyToSockaddr(fd, &rsa)
337 }
338 return
339 }
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
355 var iov [1]Iovec
356 if len(p) > 0 {
357 iov[0].Base = &p[0]
358 iov[0].SetLen(len(p))
359 }
360 var rsa RawSockaddrAny
361 n, oobn, recvflags, err = recvmsgRaw(fd, iov[:], oob, flags, &rsa)
362
363 if rsa.Addr.Family != AF_UNSPEC {
364 from, err = anyToSockaddr(fd, &rsa)
365 }
366 return
367 }
368
369
370
371
372 func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
373 iov := make([]Iovec, len(buffers))
374 for i := range buffers {
375 if len(buffers[i]) > 0 {
376 iov[i].Base = &buffers[i][0]
377 iov[i].SetLen(len(buffers[i]))
378 } else {
379 iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
380 }
381 }
382 var rsa RawSockaddrAny
383 n, oobn, recvflags, err = recvmsgRaw(fd, iov, oob, flags, &rsa)
384 if err == nil && rsa.Addr.Family != AF_UNSPEC {
385 from, err = anyToSockaddr(fd, &rsa)
386 }
387 return
388 }
389
390
391
392
393 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
394 _, err = SendmsgN(fd, p, oob, to, flags)
395 return
396 }
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
423 var iov [1]Iovec
424 if len(p) > 0 {
425 iov[0].Base = &p[0]
426 iov[0].SetLen(len(p))
427 }
428 var ptr unsafe.Pointer
429 var salen _Socklen
430 if to != nil {
431 ptr, salen, err = to.sockaddr()
432 if err != nil {
433 return 0, err
434 }
435 }
436 return sendmsgN(fd, iov[:], oob, ptr, salen, flags)
437 }
438
439
440
441
442 func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) {
443 iov := make([]Iovec, len(buffers))
444 for i := range buffers {
445 if len(buffers[i]) > 0 {
446 iov[i].Base = &buffers[i][0]
447 iov[i].SetLen(len(buffers[i]))
448 } else {
449 iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
450 }
451 }
452 var ptr unsafe.Pointer
453 var salen _Socklen
454 if to != nil {
455 ptr, salen, err = to.sockaddr()
456 if err != nil {
457 return 0, err
458 }
459 }
460 return sendmsgN(fd, iov, oob, ptr, salen, flags)
461 }
462
463 func Send(s int, buf []byte, flags int) (err error) {
464 return sendto(s, buf, flags, nil, 0)
465 }
466
467 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
468 var ptr unsafe.Pointer
469 var salen _Socklen
470 if to != nil {
471 ptr, salen, err = to.sockaddr()
472 if err != nil {
473 return err
474 }
475 }
476 return sendto(fd, p, flags, ptr, salen)
477 }
478
479 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
480 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
481 }
482
483 func SetsockoptInt(fd, level, opt int, value int) (err error) {
484 var n = int32(value)
485 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
486 }
487
488 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
489 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
490 }
491
492 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
493 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
494 }
495
496 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
497 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
498 }
499
500 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
501 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
502 }
503
504 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
505 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
506 }
507
508 func SetsockoptString(fd, level, opt int, s string) (err error) {
509 var p unsafe.Pointer
510 if len(s) > 0 {
511 p = unsafe.Pointer(&[]byte(s)[0])
512 }
513 return setsockopt(fd, level, opt, p, uintptr(len(s)))
514 }
515
516 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
517 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
518 }
519
520 func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
521 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
522 }
523
524 func Socket(domain, typ, proto int) (fd int, err error) {
525 if domain == AF_INET6 && SocketDisableIPv6 {
526 return -1, EAFNOSUPPORT
527 }
528 fd, err = socket(domain, typ, proto)
529 return
530 }
531
532 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
533 var fdx [2]int32
534 err = socketpair(domain, typ, proto, &fdx)
535 if err == nil {
536 fd[0] = int(fdx[0])
537 fd[1] = int(fdx[1])
538 }
539 return
540 }
541
542 var ioSync int64
543
544 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
545
546 func SetNonblock(fd int, nonblocking bool) (err error) {
547 flag, err := fcntl(fd, F_GETFL, 0)
548 if err != nil {
549 return err
550 }
551 if (flag&O_NONBLOCK != 0) == nonblocking {
552 return nil
553 }
554 if nonblocking {
555 flag |= O_NONBLOCK
556 } else {
557 flag &= ^O_NONBLOCK
558 }
559 _, err = fcntl(fd, F_SETFL, flag)
560 return err
561 }
562
563
564
565
566
567
568 func Exec(argv0 string, argv []string, envv []string) error {
569 return syscall.Exec(argv0, argv, envv)
570 }
571
572
573
574
575
576
577 func Lutimes(path string, tv []Timeval) error {
578 if tv == nil {
579 return UtimesNanoAt(AT_FDCWD, path, nil, AT_SYMLINK_NOFOLLOW)
580 }
581 if len(tv) != 2 {
582 return EINVAL
583 }
584 ts := []Timespec{
585 NsecToTimespec(TimevalToNsec(tv[0])),
586 NsecToTimespec(TimevalToNsec(tv[1])),
587 }
588 return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW)
589 }
590
591
592 func emptyIovecs(iov []Iovec) bool {
593 for i := range iov {
594 if iov[i].Len > 0 {
595 return false
596 }
597 }
598 return true
599 }
600
601
602 func Setrlimit(resource int, rlim *Rlimit) error {
603
604
605 return syscall.Setrlimit(resource, (*syscall.Rlimit)(rlim))
606 }
607
View as plain text