1
2
3
4
5
6
7
8
9
10
11
12 package unix
13
14 import (
15 "encoding/binary"
16 "strconv"
17 "syscall"
18 "time"
19 "unsafe"
20 )
21
22
25
26 func Access(path string, mode uint32) (err error) {
27 return Faccessat(AT_FDCWD, path, mode, 0)
28 }
29
30 func Chmod(path string, mode uint32) (err error) {
31 return Fchmodat(AT_FDCWD, path, mode, 0)
32 }
33
34 func Chown(path string, uid int, gid int) (err error) {
35 return Fchownat(AT_FDCWD, path, uid, gid, 0)
36 }
37
38 func Creat(path string, mode uint32) (fd int, err error) {
39 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
40 }
41
42 func EpollCreate(size int) (fd int, err error) {
43 if size <= 0 {
44 return -1, EINVAL
45 }
46 return EpollCreate1(0)
47 }
48
49
50
51
52 func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) {
53 if pathname == "" {
54 return fanotifyMark(fd, flags, mask, dirFd, nil)
55 }
56 p, err := BytePtrFromString(pathname)
57 if err != nil {
58 return err
59 }
60 return fanotifyMark(fd, flags, mask, dirFd, p)
61 }
62
63
64
65
66 func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
67
68
69 if flags != 0 {
70 err := fchmodat2(dirfd, path, mode, flags)
71 if err == ENOSYS {
72
73
74 if flags&^(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
75 return EINVAL
76 } else if flags&(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
77 return EOPNOTSUPP
78 }
79 }
80 return err
81 }
82 return fchmodat(dirfd, path, mode)
83 }
84
85 func InotifyInit() (fd int, err error) {
86 return InotifyInit1(0)
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 func Link(oldpath string, newpath string) (err error) {
105 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0)
106 }
107
108 func Mkdir(path string, mode uint32) (err error) {
109 return Mkdirat(AT_FDCWD, path, mode)
110 }
111
112 func Mknod(path string, mode uint32, dev int) (err error) {
113 return Mknodat(AT_FDCWD, path, mode, dev)
114 }
115
116 func Open(path string, mode int, perm uint32) (fd int, err error) {
117 return openat(AT_FDCWD, path, mode|O_LARGEFILE, perm)
118 }
119
120
121
122 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
123 return openat(dirfd, path, flags|O_LARGEFILE, mode)
124 }
125
126
127
128 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
129 return openat2(dirfd, path, how, SizeofOpenHow)
130 }
131
132 func Pipe(p []int) error {
133 return Pipe2(p, 0)
134 }
135
136
137
138 func Pipe2(p []int, flags int) error {
139 if len(p) != 2 {
140 return EINVAL
141 }
142 var pp [2]_C_int
143 err := pipe2(&pp, flags)
144 if err == nil {
145 p[0] = int(pp[0])
146 p[1] = int(pp[1])
147 }
148 return err
149 }
150
151
152
153 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
154 if len(fds) == 0 {
155 return ppoll(nil, 0, timeout, sigmask)
156 }
157 return ppoll(&fds[0], len(fds), timeout, sigmask)
158 }
159
160 func Poll(fds []PollFd, timeout int) (n int, err error) {
161 var ts *Timespec
162 if timeout >= 0 {
163 ts = new(Timespec)
164 *ts = NsecToTimespec(int64(timeout) * 1e6)
165 }
166 return Ppoll(fds, ts, nil)
167 }
168
169
170
171 func Readlink(path string, buf []byte) (n int, err error) {
172 return Readlinkat(AT_FDCWD, path, buf)
173 }
174
175 func Rename(oldpath string, newpath string) (err error) {
176 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath)
177 }
178
179 func Rmdir(path string) error {
180 return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
181 }
182
183
184
185 func Symlink(oldpath string, newpath string) (err error) {
186 return Symlinkat(oldpath, AT_FDCWD, newpath)
187 }
188
189 func Unlink(path string) error {
190 return Unlinkat(AT_FDCWD, path, 0)
191 }
192
193
194
195 func Utimes(path string, tv []Timeval) error {
196 if tv == nil {
197 err := utimensat(AT_FDCWD, path, nil, 0)
198 if err != ENOSYS {
199 return err
200 }
201 return utimes(path, nil)
202 }
203 if len(tv) != 2 {
204 return EINVAL
205 }
206 var ts [2]Timespec
207 ts[0] = NsecToTimespec(TimevalToNsec(tv[0]))
208 ts[1] = NsecToTimespec(TimevalToNsec(tv[1]))
209 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
210 if err != ENOSYS {
211 return err
212 }
213 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
214 }
215
216
217
218 func UtimesNano(path string, ts []Timespec) error {
219 return UtimesNanoAt(AT_FDCWD, path, ts, 0)
220 }
221
222 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
223 if ts == nil {
224 return utimensat(dirfd, path, nil, flags)
225 }
226 if len(ts) != 2 {
227 return EINVAL
228 }
229 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
230 }
231
232 func Futimesat(dirfd int, path string, tv []Timeval) error {
233 if tv == nil {
234 return futimesat(dirfd, path, nil)
235 }
236 if len(tv) != 2 {
237 return EINVAL
238 }
239 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
240 }
241
242 func Futimes(fd int, tv []Timeval) (err error) {
243
244
245 return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv)
246 }
247
248 const ImplementsGetwd = true
249
250
251
252 func Getwd() (wd string, err error) {
253 var buf [PathMax]byte
254 n, err := Getcwd(buf[0:])
255 if err != nil {
256 return "", err
257 }
258
259 if n < 1 || n > len(buf) || buf[n-1] != 0 {
260 return "", EINVAL
261 }
262
263
264
265 if buf[0] != '/' {
266 return "", ENOENT
267 }
268
269 return string(buf[0 : n-1]), nil
270 }
271
272 func Getgroups() (gids []int, err error) {
273 n, err := getgroups(0, nil)
274 if err != nil {
275 return nil, err
276 }
277 if n == 0 {
278 return nil, nil
279 }
280
281
282 if n < 0 || n > 1<<20 {
283 return nil, EINVAL
284 }
285
286 a := make([]_Gid_t, n)
287 n, err = getgroups(n, &a[0])
288 if err != nil {
289 return nil, err
290 }
291 gids = make([]int, n)
292 for i, v := range a[0:n] {
293 gids[i] = int(v)
294 }
295 return
296 }
297
298 func Setgroups(gids []int) (err error) {
299 if len(gids) == 0 {
300 return setgroups(0, nil)
301 }
302
303 a := make([]_Gid_t, len(gids))
304 for i, v := range gids {
305 a[i] = _Gid_t(v)
306 }
307 return setgroups(len(a), &a[0])
308 }
309
310 type WaitStatus uint32
311
312
313
314
315
316
317
318
319
320
321 const (
322 mask = 0x7F
323 core = 0x80
324 exited = 0x00
325 stopped = 0x7F
326 shift = 8
327 )
328
329 func (w WaitStatus) Exited() bool { return w&mask == exited }
330
331 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
332
333 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
334
335 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
336
337 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
338
339 func (w WaitStatus) ExitStatus() int {
340 if !w.Exited() {
341 return -1
342 }
343 return int(w>>shift) & 0xFF
344 }
345
346 func (w WaitStatus) Signal() syscall.Signal {
347 if !w.Signaled() {
348 return -1
349 }
350 return syscall.Signal(w & mask)
351 }
352
353 func (w WaitStatus) StopSignal() syscall.Signal {
354 if !w.Stopped() {
355 return -1
356 }
357 return syscall.Signal(w>>shift) & 0xFF
358 }
359
360 func (w WaitStatus) TrapCause() int {
361 if w.StopSignal() != SIGTRAP {
362 return -1
363 }
364 return int(w>>shift) >> 8
365 }
366
367
368
369 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
370 var status _C_int
371 wpid, err = wait4(pid, &status, options, rusage)
372 if wstatus != nil {
373 *wstatus = WaitStatus(status)
374 }
375 return
376 }
377
378
379
380 func Mkfifo(path string, mode uint32) error {
381 return Mknod(path, mode|S_IFIFO, 0)
382 }
383
384 func Mkfifoat(dirfd int, path string, mode uint32) error {
385 return Mknodat(dirfd, path, mode|S_IFIFO, 0)
386 }
387
388 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
389 if sa.Port < 0 || sa.Port > 0xFFFF {
390 return nil, 0, EINVAL
391 }
392 sa.raw.Family = AF_INET
393 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
394 p[0] = byte(sa.Port >> 8)
395 p[1] = byte(sa.Port)
396 sa.raw.Addr = sa.Addr
397 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
398 }
399
400 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
401 if sa.Port < 0 || sa.Port > 0xFFFF {
402 return nil, 0, EINVAL
403 }
404 sa.raw.Family = AF_INET6
405 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
406 p[0] = byte(sa.Port >> 8)
407 p[1] = byte(sa.Port)
408 sa.raw.Scope_id = sa.ZoneId
409 sa.raw.Addr = sa.Addr
410 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
411 }
412
413 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
414 name := sa.Name
415 n := len(name)
416 if n >= len(sa.raw.Path) {
417 return nil, 0, EINVAL
418 }
419 sa.raw.Family = AF_UNIX
420 for i := 0; i < n; i++ {
421 sa.raw.Path[i] = int8(name[i])
422 }
423
424 sl := _Socklen(2)
425 if n > 0 {
426 sl += _Socklen(n) + 1
427 }
428 if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
429
430 sa.raw.Path[0] = 0
431
432 sl--
433 }
434
435 return unsafe.Pointer(&sa.raw), sl, nil
436 }
437
438
439 type SockaddrLinklayer struct {
440 Protocol uint16
441 Ifindex int
442 Hatype uint16
443 Pkttype uint8
444 Halen uint8
445 Addr [8]byte
446 raw RawSockaddrLinklayer
447 }
448
449 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
450 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
451 return nil, 0, EINVAL
452 }
453 sa.raw.Family = AF_PACKET
454 sa.raw.Protocol = sa.Protocol
455 sa.raw.Ifindex = int32(sa.Ifindex)
456 sa.raw.Hatype = sa.Hatype
457 sa.raw.Pkttype = sa.Pkttype
458 sa.raw.Halen = sa.Halen
459 sa.raw.Addr = sa.Addr
460 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
461 }
462
463
464 type SockaddrNetlink struct {
465 Family uint16
466 Pad uint16
467 Pid uint32
468 Groups uint32
469 raw RawSockaddrNetlink
470 }
471
472 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
473 sa.raw.Family = AF_NETLINK
474 sa.raw.Pad = sa.Pad
475 sa.raw.Pid = sa.Pid
476 sa.raw.Groups = sa.Groups
477 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
478 }
479
480
481
482 type SockaddrHCI struct {
483 Dev uint16
484 Channel uint16
485 raw RawSockaddrHCI
486 }
487
488 func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
489 sa.raw.Family = AF_BLUETOOTH
490 sa.raw.Dev = sa.Dev
491 sa.raw.Channel = sa.Channel
492 return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
493 }
494
495
496
497 type SockaddrL2 struct {
498 PSM uint16
499 CID uint16
500 Addr [6]uint8
501 AddrType uint8
502 raw RawSockaddrL2
503 }
504
505 func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
506 sa.raw.Family = AF_BLUETOOTH
507 psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))
508 psm[0] = byte(sa.PSM)
509 psm[1] = byte(sa.PSM >> 8)
510 for i := 0; i < len(sa.Addr); i++ {
511 sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]
512 }
513 cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))
514 cid[0] = byte(sa.CID)
515 cid[1] = byte(sa.CID >> 8)
516 sa.raw.Bdaddr_type = sa.AddrType
517 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
518 }
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543 type SockaddrRFCOMM struct {
544
545 Addr [6]uint8
546
547
548
549 Channel uint8
550
551 raw RawSockaddrRFCOMM
552 }
553
554 func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {
555 sa.raw.Family = AF_BLUETOOTH
556 sa.raw.Channel = sa.Channel
557 sa.raw.Bdaddr = sa.Addr
558 return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil
559 }
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578 type SockaddrCAN struct {
579 Ifindex int
580 RxID uint32
581 TxID uint32
582 raw RawSockaddrCAN
583 }
584
585 func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
586 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
587 return nil, 0, EINVAL
588 }
589 sa.raw.Family = AF_CAN
590 sa.raw.Ifindex = int32(sa.Ifindex)
591 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
592 for i := 0; i < 4; i++ {
593 sa.raw.Addr[i] = rx[i]
594 }
595 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
596 for i := 0; i < 4; i++ {
597 sa.raw.Addr[i+4] = tx[i]
598 }
599 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
600 }
601
602
603
604
605
606 type SockaddrCANJ1939 struct {
607 Ifindex int
608 Name uint64
609 PGN uint32
610 Addr uint8
611 raw RawSockaddrCAN
612 }
613
614 func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {
615 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
616 return nil, 0, EINVAL
617 }
618 sa.raw.Family = AF_CAN
619 sa.raw.Ifindex = int32(sa.Ifindex)
620 n := (*[8]byte)(unsafe.Pointer(&sa.Name))
621 for i := 0; i < 8; i++ {
622 sa.raw.Addr[i] = n[i]
623 }
624 p := (*[4]byte)(unsafe.Pointer(&sa.PGN))
625 for i := 0; i < 4; i++ {
626 sa.raw.Addr[i+8] = p[i]
627 }
628 sa.raw.Addr[12] = sa.Addr
629 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
630 }
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695 type SockaddrALG struct {
696 Type string
697 Name string
698 Feature uint32
699 Mask uint32
700 raw RawSockaddrALG
701 }
702
703 func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) {
704
705 if len(sa.Type) > len(sa.raw.Type)-1 {
706 return nil, 0, EINVAL
707 }
708 if len(sa.Name) > len(sa.raw.Name)-1 {
709 return nil, 0, EINVAL
710 }
711
712 sa.raw.Family = AF_ALG
713 sa.raw.Feat = sa.Feature
714 sa.raw.Mask = sa.Mask
715
716 copy(sa.raw.Type[:], sa.Type)
717 copy(sa.raw.Name[:], sa.Name)
718
719 return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil
720 }
721
722
723
724
725
726 type SockaddrVM struct {
727
728
729
730
731
732 CID uint32
733 Port uint32
734 Flags uint8
735 raw RawSockaddrVM
736 }
737
738 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
739 sa.raw.Family = AF_VSOCK
740 sa.raw.Port = sa.Port
741 sa.raw.Cid = sa.CID
742 sa.raw.Flags = sa.Flags
743
744 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
745 }
746
747 type SockaddrXDP struct {
748 Flags uint16
749 Ifindex uint32
750 QueueID uint32
751 SharedUmemFD uint32
752 raw RawSockaddrXDP
753 }
754
755 func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) {
756 sa.raw.Family = AF_XDP
757 sa.raw.Flags = sa.Flags
758 sa.raw.Ifindex = sa.Ifindex
759 sa.raw.Queue_id = sa.QueueID
760 sa.raw.Shared_umem_fd = sa.SharedUmemFD
761
762 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil
763 }
764
765
766
767
768
769
770
771
772 const px_proto_oe = 0
773
774 type SockaddrPPPoE struct {
775 SID uint16
776 Remote []byte
777 Dev string
778 raw RawSockaddrPPPoX
779 }
780
781 func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
782 if len(sa.Remote) != 6 {
783 return nil, 0, EINVAL
784 }
785 if len(sa.Dev) > IFNAMSIZ-1 {
786 return nil, 0, EINVAL
787 }
788
789 *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX
790
791
792
793
794
795
796
797
798 binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe)
799
800
801 binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
802 copy(sa.raw[8:14], sa.Remote)
803 for i := 14; i < 14+IFNAMSIZ; i++ {
804 sa.raw[i] = 0
805 }
806 copy(sa.raw[14:], sa.Dev)
807 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
808 }
809
810
811
812 type SockaddrTIPC struct {
813
814
815 Scope int
816
817
818
819
820
821
822
823
824 Addr TIPCAddr
825
826 raw RawSockaddrTIPC
827 }
828
829
830
831
832 type TIPCAddr interface {
833 tipcAddrtype() uint8
834 tipcAddr() [12]byte
835 }
836
837 func (sa *TIPCSocketAddr) tipcAddr() [12]byte {
838 var out [12]byte
839 copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:])
840 return out
841 }
842
843 func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR }
844
845 func (sa *TIPCServiceRange) tipcAddr() [12]byte {
846 var out [12]byte
847 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:])
848 return out
849 }
850
851 func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE }
852
853 func (sa *TIPCServiceName) tipcAddr() [12]byte {
854 var out [12]byte
855 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:])
856 return out
857 }
858
859 func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR }
860
861 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
862 if sa.Addr == nil {
863 return nil, 0, EINVAL
864 }
865 sa.raw.Family = AF_TIPC
866 sa.raw.Scope = int8(sa.Scope)
867 sa.raw.Addrtype = sa.Addr.tipcAddrtype()
868 sa.raw.Addr = sa.Addr.tipcAddr()
869 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
870 }
871
872
873 type SockaddrL2TPIP struct {
874 Addr [4]byte
875 ConnId uint32
876 raw RawSockaddrL2TPIP
877 }
878
879 func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
880 sa.raw.Family = AF_INET
881 sa.raw.Conn_id = sa.ConnId
882 sa.raw.Addr = sa.Addr
883 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
884 }
885
886
887 type SockaddrL2TPIP6 struct {
888 Addr [16]byte
889 ZoneId uint32
890 ConnId uint32
891 raw RawSockaddrL2TPIP6
892 }
893
894 func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
895 sa.raw.Family = AF_INET6
896 sa.raw.Conn_id = sa.ConnId
897 sa.raw.Scope_id = sa.ZoneId
898 sa.raw.Addr = sa.Addr
899 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
900 }
901
902
903 type SockaddrIUCV struct {
904 UserID string
905 Name string
906 raw RawSockaddrIUCV
907 }
908
909 func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
910 sa.raw.Family = AF_IUCV
911
912
913
914 for i := 0; i < 8; i++ {
915 sa.raw.Nodeid[i] = ' '
916 sa.raw.User_id[i] = ' '
917 sa.raw.Name[i] = ' '
918 }
919 if len(sa.UserID) > 8 || len(sa.Name) > 8 {
920 return nil, 0, EINVAL
921 }
922 for i, b := range []byte(sa.UserID[:]) {
923 sa.raw.User_id[i] = int8(b)
924 }
925 for i, b := range []byte(sa.Name[:]) {
926 sa.raw.Name[i] = int8(b)
927 }
928 return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
929 }
930
931 type SockaddrNFC struct {
932 DeviceIdx uint32
933 TargetIdx uint32
934 NFCProtocol uint32
935 raw RawSockaddrNFC
936 }
937
938 func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) {
939 sa.raw.Sa_family = AF_NFC
940 sa.raw.Dev_idx = sa.DeviceIdx
941 sa.raw.Target_idx = sa.TargetIdx
942 sa.raw.Nfc_protocol = sa.NFCProtocol
943 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil
944 }
945
946 type SockaddrNFCLLCP struct {
947 DeviceIdx uint32
948 TargetIdx uint32
949 NFCProtocol uint32
950 DestinationSAP uint8
951 SourceSAP uint8
952 ServiceName string
953 raw RawSockaddrNFCLLCP
954 }
955
956 func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) {
957 sa.raw.Sa_family = AF_NFC
958 sa.raw.Dev_idx = sa.DeviceIdx
959 sa.raw.Target_idx = sa.TargetIdx
960 sa.raw.Nfc_protocol = sa.NFCProtocol
961 sa.raw.Dsap = sa.DestinationSAP
962 sa.raw.Ssap = sa.SourceSAP
963 if len(sa.ServiceName) > len(sa.raw.Service_name) {
964 return nil, 0, EINVAL
965 }
966 copy(sa.raw.Service_name[:], sa.ServiceName)
967 sa.raw.SetServiceNameLen(len(sa.ServiceName))
968 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil
969 }
970
971 var socketProtocol = func(fd int) (int, error) {
972 return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
973 }
974
975 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
976 switch rsa.Addr.Family {
977 case AF_NETLINK:
978 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
979 sa := new(SockaddrNetlink)
980 sa.Family = pp.Family
981 sa.Pad = pp.Pad
982 sa.Pid = pp.Pid
983 sa.Groups = pp.Groups
984 return sa, nil
985
986 case AF_PACKET:
987 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
988 sa := new(SockaddrLinklayer)
989 sa.Protocol = pp.Protocol
990 sa.Ifindex = int(pp.Ifindex)
991 sa.Hatype = pp.Hatype
992 sa.Pkttype = pp.Pkttype
993 sa.Halen = pp.Halen
994 sa.Addr = pp.Addr
995 return sa, nil
996
997 case AF_UNIX:
998 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
999 sa := new(SockaddrUnix)
1000 if pp.Path[0] == 0 {
1001
1002
1003
1004
1005
1006 pp.Path[0] = '@'
1007 }
1008
1009
1010
1011
1012
1013
1014 n := 0
1015 for n < len(pp.Path) && pp.Path[n] != 0 {
1016 n++
1017 }
1018 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
1019 return sa, nil
1020
1021 case AF_INET:
1022 proto, err := socketProtocol(fd)
1023 if err != nil {
1024 return nil, err
1025 }
1026
1027 switch proto {
1028 case IPPROTO_L2TP:
1029 pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
1030 sa := new(SockaddrL2TPIP)
1031 sa.ConnId = pp.Conn_id
1032 sa.Addr = pp.Addr
1033 return sa, nil
1034 default:
1035 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
1036 sa := new(SockaddrInet4)
1037 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1038 sa.Port = int(p[0])<<8 + int(p[1])
1039 sa.Addr = pp.Addr
1040 return sa, nil
1041 }
1042
1043 case AF_INET6:
1044 proto, err := socketProtocol(fd)
1045 if err != nil {
1046 return nil, err
1047 }
1048
1049 switch proto {
1050 case IPPROTO_L2TP:
1051 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa))
1052 sa := new(SockaddrL2TPIP6)
1053 sa.ConnId = pp.Conn_id
1054 sa.ZoneId = pp.Scope_id
1055 sa.Addr = pp.Addr
1056 return sa, nil
1057 default:
1058 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
1059 sa := new(SockaddrInet6)
1060 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1061 sa.Port = int(p[0])<<8 + int(p[1])
1062 sa.ZoneId = pp.Scope_id
1063 sa.Addr = pp.Addr
1064 return sa, nil
1065 }
1066
1067 case AF_VSOCK:
1068 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
1069 sa := &SockaddrVM{
1070 CID: pp.Cid,
1071 Port: pp.Port,
1072 Flags: pp.Flags,
1073 }
1074 return sa, nil
1075 case AF_BLUETOOTH:
1076 proto, err := socketProtocol(fd)
1077 if err != nil {
1078 return nil, err
1079 }
1080
1081 switch proto {
1082 case BTPROTO_L2CAP:
1083 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa))
1084 sa := &SockaddrL2{
1085 PSM: pp.Psm,
1086 CID: pp.Cid,
1087 Addr: pp.Bdaddr,
1088 AddrType: pp.Bdaddr_type,
1089 }
1090 return sa, nil
1091 case BTPROTO_RFCOMM:
1092 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))
1093 sa := &SockaddrRFCOMM{
1094 Channel: pp.Channel,
1095 Addr: pp.Bdaddr,
1096 }
1097 return sa, nil
1098 }
1099 case AF_XDP:
1100 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa))
1101 sa := &SockaddrXDP{
1102 Flags: pp.Flags,
1103 Ifindex: pp.Ifindex,
1104 QueueID: pp.Queue_id,
1105 SharedUmemFD: pp.Shared_umem_fd,
1106 }
1107 return sa, nil
1108 case AF_PPPOX:
1109 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))
1110 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {
1111 return nil, EINVAL
1112 }
1113 sa := &SockaddrPPPoE{
1114 SID: binary.BigEndian.Uint16(pp[6:8]),
1115 Remote: pp[8:14],
1116 }
1117 for i := 14; i < 14+IFNAMSIZ; i++ {
1118 if pp[i] == 0 {
1119 sa.Dev = string(pp[14:i])
1120 break
1121 }
1122 }
1123 return sa, nil
1124 case AF_TIPC:
1125 pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa))
1126
1127 sa := &SockaddrTIPC{
1128 Scope: int(pp.Scope),
1129 }
1130
1131
1132
1133 switch pp.Addrtype {
1134 case TIPC_SERVICE_RANGE:
1135 sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr))
1136 case TIPC_SERVICE_ADDR:
1137 sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr))
1138 case TIPC_SOCKET_ADDR:
1139 sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr))
1140 default:
1141 return nil, EINVAL
1142 }
1143
1144 return sa, nil
1145 case AF_IUCV:
1146 pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa))
1147
1148 var user [8]byte
1149 var name [8]byte
1150
1151 for i := 0; i < 8; i++ {
1152 user[i] = byte(pp.User_id[i])
1153 name[i] = byte(pp.Name[i])
1154 }
1155
1156 sa := &SockaddrIUCV{
1157 UserID: string(user[:]),
1158 Name: string(name[:]),
1159 }
1160 return sa, nil
1161
1162 case AF_CAN:
1163 proto, err := socketProtocol(fd)
1164 if err != nil {
1165 return nil, err
1166 }
1167
1168 pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
1169
1170 switch proto {
1171 case CAN_J1939:
1172 sa := &SockaddrCANJ1939{
1173 Ifindex: int(pp.Ifindex),
1174 }
1175 name := (*[8]byte)(unsafe.Pointer(&sa.Name))
1176 for i := 0; i < 8; i++ {
1177 name[i] = pp.Addr[i]
1178 }
1179 pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))
1180 for i := 0; i < 4; i++ {
1181 pgn[i] = pp.Addr[i+8]
1182 }
1183 addr := (*[1]byte)(unsafe.Pointer(&sa.Addr))
1184 addr[0] = pp.Addr[12]
1185 return sa, nil
1186 default:
1187 sa := &SockaddrCAN{
1188 Ifindex: int(pp.Ifindex),
1189 }
1190 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
1191 for i := 0; i < 4; i++ {
1192 rx[i] = pp.Addr[i]
1193 }
1194 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
1195 for i := 0; i < 4; i++ {
1196 tx[i] = pp.Addr[i+4]
1197 }
1198 return sa, nil
1199 }
1200 case AF_NFC:
1201 proto, err := socketProtocol(fd)
1202 if err != nil {
1203 return nil, err
1204 }
1205 switch proto {
1206 case NFC_SOCKPROTO_RAW:
1207 pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa))
1208 sa := &SockaddrNFC{
1209 DeviceIdx: pp.Dev_idx,
1210 TargetIdx: pp.Target_idx,
1211 NFCProtocol: pp.Nfc_protocol,
1212 }
1213 return sa, nil
1214 case NFC_SOCKPROTO_LLCP:
1215 pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa))
1216 if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) {
1217 return nil, EINVAL
1218 }
1219 sa := &SockaddrNFCLLCP{
1220 DeviceIdx: pp.Dev_idx,
1221 TargetIdx: pp.Target_idx,
1222 NFCProtocol: pp.Nfc_protocol,
1223 DestinationSAP: pp.Dsap,
1224 SourceSAP: pp.Ssap,
1225 ServiceName: string(pp.Service_name[:pp.Service_name_len]),
1226 }
1227 return sa, nil
1228 default:
1229 return nil, EINVAL
1230 }
1231 }
1232 return nil, EAFNOSUPPORT
1233 }
1234
1235 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
1236 var rsa RawSockaddrAny
1237 var len _Socklen = SizeofSockaddrAny
1238 nfd, err = accept4(fd, &rsa, &len, 0)
1239 if err != nil {
1240 return
1241 }
1242 sa, err = anyToSockaddr(fd, &rsa)
1243 if err != nil {
1244 Close(nfd)
1245 nfd = 0
1246 }
1247 return
1248 }
1249
1250 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
1251 var rsa RawSockaddrAny
1252 var len _Socklen = SizeofSockaddrAny
1253 nfd, err = accept4(fd, &rsa, &len, flags)
1254 if err != nil {
1255 return
1256 }
1257 if len > SizeofSockaddrAny {
1258 panic("RawSockaddrAny too small")
1259 }
1260 sa, err = anyToSockaddr(fd, &rsa)
1261 if err != nil {
1262 Close(nfd)
1263 nfd = 0
1264 }
1265 return
1266 }
1267
1268 func Getsockname(fd int) (sa Sockaddr, err error) {
1269 var rsa RawSockaddrAny
1270 var len _Socklen = SizeofSockaddrAny
1271 if err = getsockname(fd, &rsa, &len); err != nil {
1272 return
1273 }
1274 return anyToSockaddr(fd, &rsa)
1275 }
1276
1277 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
1278 var value IPMreqn
1279 vallen := _Socklen(SizeofIPMreqn)
1280 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1281 return &value, err
1282 }
1283
1284 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
1285 var value Ucred
1286 vallen := _Socklen(SizeofUcred)
1287 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1288 return &value, err
1289 }
1290
1291 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
1292 var value TCPInfo
1293 vallen := _Socklen(SizeofTCPInfo)
1294 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1295 return &value, err
1296 }
1297
1298
1299
1300 func GetsockoptString(fd, level, opt int) (string, error) {
1301 buf := make([]byte, 256)
1302 vallen := _Socklen(len(buf))
1303 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1304 if err != nil {
1305 if err == ERANGE {
1306 buf = make([]byte, vallen)
1307 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1308 }
1309 if err != nil {
1310 return "", err
1311 }
1312 }
1313 return ByteSliceToString(buf[:vallen]), nil
1314 }
1315
1316 func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) {
1317 var value TpacketStats
1318 vallen := _Socklen(SizeofTpacketStats)
1319 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1320 return &value, err
1321 }
1322
1323 func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) {
1324 var value TpacketStatsV3
1325 vallen := _Socklen(SizeofTpacketStatsV3)
1326 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1327 return &value, err
1328 }
1329
1330 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
1331 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
1332 }
1333
1334 func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error {
1335 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
1336 }
1337
1338
1339
1340 func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error {
1341 return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog))
1342 }
1343
1344 func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error {
1345 var p unsafe.Pointer
1346 if len(filter) > 0 {
1347 p = unsafe.Pointer(&filter[0])
1348 }
1349 return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter))
1350 }
1351
1352 func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error {
1353 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
1354 }
1355
1356 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error {
1357 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
1358 }
1359
1360 func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) {
1361 if len(o) == 0 {
1362 return EINVAL
1363 }
1364 return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o)))
1365 }
1366
1367 func SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error {
1368 return setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s))
1369 }
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387 func KeyctlString(cmd int, id int) (string, error) {
1388
1389
1390
1391
1392 var buffer []byte
1393 for {
1394
1395 length, err := KeyctlBuffer(cmd, id, buffer, 0)
1396 if err != nil {
1397 return "", err
1398 }
1399
1400
1401 if length <= len(buffer) {
1402
1403 return string(buffer[:length-1]), nil
1404 }
1405
1406
1407 buffer = make([]byte, length)
1408 }
1409 }
1410
1411
1412
1413
1414
1415
1416 func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) {
1417 createInt := 0
1418 if create {
1419 createInt = 1
1420 }
1421 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0)
1422 }
1423
1424
1425
1426
1427
1428
1429 func KeyctlSetperm(id int, perm uint32) error {
1430 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0)
1431 return err
1432 }
1433
1434
1435
1436
1437
1438
1439 func KeyctlJoinSessionKeyring(name string) (ringid int, err error) {
1440 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name)
1441 }
1442
1443
1444
1445
1446
1447
1448 func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) {
1449 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid)
1450 }
1451
1452
1453
1454
1455
1456
1457
1458
1459 func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error {
1460 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid)
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
1475 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
1476 }
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496 func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error {
1497 if keyType == "" {
1498 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid)
1499 }
1500 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)
1501 }
1502
1503
1504
1505
1506 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
1507 var msg Msghdr
1508 msg.Name = (*byte)(unsafe.Pointer(rsa))
1509 msg.Namelen = uint32(SizeofSockaddrAny)
1510 var dummy byte
1511 if len(oob) > 0 {
1512 if emptyIovecs(iov) {
1513 var sockType int
1514 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1515 if err != nil {
1516 return
1517 }
1518
1519 if sockType != SOCK_DGRAM {
1520 var iova [1]Iovec
1521 iova[0].Base = &dummy
1522 iova[0].SetLen(1)
1523 iov = iova[:]
1524 }
1525 }
1526 msg.Control = &oob[0]
1527 msg.SetControllen(len(oob))
1528 }
1529 if len(iov) > 0 {
1530 msg.Iov = &iov[0]
1531 msg.SetIovlen(len(iov))
1532 }
1533 if n, err = recvmsg(fd, &msg, flags); err != nil {
1534 return
1535 }
1536 oobn = int(msg.Controllen)
1537 recvflags = int(msg.Flags)
1538 return
1539 }
1540
1541 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
1542 var msg Msghdr
1543 msg.Name = (*byte)(ptr)
1544 msg.Namelen = uint32(salen)
1545 var dummy byte
1546 var empty bool
1547 if len(oob) > 0 {
1548 empty = emptyIovecs(iov)
1549 if empty {
1550 var sockType int
1551 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1552 if err != nil {
1553 return 0, err
1554 }
1555
1556 if sockType != SOCK_DGRAM {
1557 var iova [1]Iovec
1558 iova[0].Base = &dummy
1559 iova[0].SetLen(1)
1560 iov = iova[:]
1561 }
1562 }
1563 msg.Control = &oob[0]
1564 msg.SetControllen(len(oob))
1565 }
1566 if len(iov) > 0 {
1567 msg.Iov = &iov[0]
1568 msg.SetIovlen(len(iov))
1569 }
1570 if n, err = sendmsg(fd, &msg, flags); err != nil {
1571 return 0, err
1572 }
1573 if len(oob) > 0 && empty {
1574 n = 0
1575 }
1576 return n, nil
1577 }
1578
1579
1580 func BindToDevice(fd int, device string) (err error) {
1581 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
1582 }
1583
1584
1585
1586
1587 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
1588
1589
1590
1591
1592
1593
1594 var buf [SizeofPtr]byte
1595
1596
1597
1598
1599
1600
1601 n := 0
1602 if addr%SizeofPtr != 0 {
1603 err = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
1604 if err != nil {
1605 return 0, err
1606 }
1607 n += copy(out, buf[addr%SizeofPtr:])
1608 out = out[n:]
1609 }
1610
1611
1612 for len(out) > 0 {
1613
1614
1615 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
1616 if err != nil {
1617 return n, err
1618 }
1619 copied := copy(out, buf[0:])
1620 n += copied
1621 out = out[copied:]
1622 }
1623
1624 return n, nil
1625 }
1626
1627 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
1628 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
1629 }
1630
1631 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
1632 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
1633 }
1634
1635 func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) {
1636 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out)
1637 }
1638
1639 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
1640
1641
1642
1643
1644 n := 0
1645 if addr%SizeofPtr != 0 {
1646 var buf [SizeofPtr]byte
1647 err = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
1648 if err != nil {
1649 return 0, err
1650 }
1651 n += copy(buf[addr%SizeofPtr:], data)
1652 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1653 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word)
1654 if err != nil {
1655 return 0, err
1656 }
1657 data = data[n:]
1658 }
1659
1660
1661 for len(data) > SizeofPtr {
1662 word := *((*uintptr)(unsafe.Pointer(&data[0])))
1663 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1664 if err != nil {
1665 return n, err
1666 }
1667 n += SizeofPtr
1668 data = data[SizeofPtr:]
1669 }
1670
1671
1672 if len(data) > 0 {
1673 var buf [SizeofPtr]byte
1674 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
1675 if err != nil {
1676 return n, err
1677 }
1678 copy(buf[0:], data)
1679 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1680 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1681 if err != nil {
1682 return n, err
1683 }
1684 n += len(data)
1685 }
1686
1687 return n, nil
1688 }
1689
1690 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
1691 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
1692 }
1693
1694 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
1695 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
1696 }
1697
1698 func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {
1699 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
1700 }
1701
1702
1703
1704
1705 const elfNT_PRSTATUS = 1
1706
1707 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
1708 var iov Iovec
1709 iov.Base = (*byte)(unsafe.Pointer(regsout))
1710 iov.SetLen(int(unsafe.Sizeof(*regsout)))
1711 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
1712 }
1713
1714 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
1715 var iov Iovec
1716 iov.Base = (*byte)(unsafe.Pointer(regs))
1717 iov.SetLen(int(unsafe.Sizeof(*regs)))
1718 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
1719 }
1720
1721 func PtraceSetOptions(pid int, options int) (err error) {
1722 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
1723 }
1724
1725 func PtraceGetEventMsg(pid int) (msg uint, err error) {
1726 var data _C_long
1727 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
1728 msg = uint(data)
1729 return
1730 }
1731
1732 func PtraceCont(pid int, signal int) (err error) {
1733 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
1734 }
1735
1736 func PtraceSyscall(pid int, signal int) (err error) {
1737 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
1738 }
1739
1740 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
1741
1742 func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) }
1743
1744 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
1745
1746 func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) }
1747
1748 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
1749
1750
1751
1752 func Reboot(cmd int) (err error) {
1753 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
1754 }
1755
1756 func direntIno(buf []byte) (uint64, bool) {
1757 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1758 }
1759
1760 func direntReclen(buf []byte) (uint64, bool) {
1761 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1762 }
1763
1764 func direntNamlen(buf []byte) (uint64, bool) {
1765 reclen, ok := direntReclen(buf)
1766 if !ok {
1767 return 0, false
1768 }
1769 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1770 }
1771
1772
1773
1774 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1775
1776
1777 if data == "" {
1778 return mount(source, target, fstype, flags, nil)
1779 }
1780 datap, err := BytePtrFromString(data)
1781 if err != nil {
1782 return err
1783 }
1784 return mount(source, target, fstype, flags, datap)
1785 }
1786
1787
1788
1789
1790
1791
1792
1793 func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error {
1794 return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr))
1795 }
1796
1797 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
1798 if raceenabled {
1799 raceReleaseMerge(unsafe.Pointer(&ioSync))
1800 }
1801 return sendfile(outfd, infd, offset, count)
1802 }
1803
1804
1805
1806
1807
1808
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828 func Dup2(oldfd, newfd int) error {
1829 return Dup3(oldfd, newfd, 0)
1830 }
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855 func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
1856 var keyp *byte
1857 if keyp, err = BytePtrFromString(key); err != nil {
1858 return
1859 }
1860 return fsconfig(fd, cmd, keyp, value, aux)
1861 }
1862
1863
1864
1865
1866
1867
1868 func FsconfigSetFlag(fd int, key string) (err error) {
1869 return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
1870 }
1871
1872
1873
1874
1875
1876
1877
1878 func FsconfigSetString(fd int, key string, value string) (err error) {
1879 var valuep *byte
1880 if valuep, err = BytePtrFromString(value); err != nil {
1881 return
1882 }
1883 return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
1884 }
1885
1886
1887
1888
1889
1890
1891
1892 func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
1893 if len(value) == 0 {
1894 return EINVAL
1895 }
1896 return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
1897 }
1898
1899
1900
1901
1902
1903
1904
1905
1906 func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
1907 var valuep *byte
1908 if valuep, err = BytePtrFromString(path); err != nil {
1909 return
1910 }
1911 return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
1912 }
1913
1914
1915
1916
1917 func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
1918 var valuep *byte
1919 if valuep, err = BytePtrFromString(path); err != nil {
1920 return
1921 }
1922 return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
1923 }
1924
1925
1926
1927
1928
1929
1930
1931 func FsconfigSetFd(fd int, key string, value int) (err error) {
1932 return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
1933 }
1934
1935
1936
1937
1938
1939 func FsconfigCreate(fd int) (err error) {
1940 return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
1941 }
1942
1943
1944
1945
1946
1947 func FsconfigReconfigure(fd int) (err error) {
1948 return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
1949 }
1950
1951
1952
1953
1954 func Getpgrp() (pid int) {
1955 pid, _ = Getpgid(0)
1956 return
1957 }
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000 func syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error
2001
2002 func Prlimit(pid, resource int, newlimit, old *Rlimit) error {
2003
2004
2005 return syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old))
2006 }
2007
2008
2009
2010
2011 func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {
2012 ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)
2013 if err != 0 {
2014 return 0, err
2015 }
2016 return int(ret), nil
2017 }
2018
2019 func Setuid(uid int) (err error) {
2020 return syscall.Setuid(uid)
2021 }
2022
2023 func Setgid(gid int) (err error) {
2024 return syscall.Setgid(gid)
2025 }
2026
2027 func Setreuid(ruid, euid int) (err error) {
2028 return syscall.Setreuid(ruid, euid)
2029 }
2030
2031 func Setregid(rgid, egid int) (err error) {
2032 return syscall.Setregid(rgid, egid)
2033 }
2034
2035 func Setresuid(ruid, euid, suid int) (err error) {
2036 return syscall.Setresuid(ruid, euid, suid)
2037 }
2038
2039 func Setresgid(rgid, egid, sgid int) (err error) {
2040 return syscall.Setresgid(rgid, egid, sgid)
2041 }
2042
2043
2044
2045
2046 func SetfsgidRetGid(gid int) (int, error) {
2047 return setfsgid(gid)
2048 }
2049
2050
2051
2052
2053 func SetfsuidRetUid(uid int) (int, error) {
2054 return setfsuid(uid)
2055 }
2056
2057 func Setfsgid(gid int) error {
2058 _, err := setfsgid(gid)
2059 return err
2060 }
2061
2062 func Setfsuid(uid int) error {
2063 _, err := setfsuid(uid)
2064 return err
2065 }
2066
2067 func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
2068 return signalfd(fd, sigmask, _C__NSIG/8, flags)
2069 }
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103 const minIovec = 8
2104
2105
2106 func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
2107 for _, b := range bs {
2108 var v Iovec
2109 v.SetLen(len(b))
2110 if len(b) > 0 {
2111 v.Base = &b[0]
2112 } else {
2113 v.Base = (*byte)(unsafe.Pointer(&_zero))
2114 }
2115 vecs = append(vecs, v)
2116 }
2117 return vecs
2118 }
2119
2120
2121 func offs2lohi(offs int64) (lo, hi uintptr) {
2122 const longBits = SizeofLong * 8
2123 return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1)
2124 }
2125
2126 func Readv(fd int, iovs [][]byte) (n int, err error) {
2127 iovecs := make([]Iovec, 0, minIovec)
2128 iovecs = appendBytes(iovecs, iovs)
2129 n, err = readv(fd, iovecs)
2130 readvRacedetect(iovecs, n, err)
2131 return n, err
2132 }
2133
2134 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
2135 iovecs := make([]Iovec, 0, minIovec)
2136 iovecs = appendBytes(iovecs, iovs)
2137 lo, hi := offs2lohi(offset)
2138 n, err = preadv(fd, iovecs, lo, hi)
2139 readvRacedetect(iovecs, n, err)
2140 return n, err
2141 }
2142
2143 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
2144 iovecs := make([]Iovec, 0, minIovec)
2145 iovecs = appendBytes(iovecs, iovs)
2146 lo, hi := offs2lohi(offset)
2147 n, err = preadv2(fd, iovecs, lo, hi, flags)
2148 readvRacedetect(iovecs, n, err)
2149 return n, err
2150 }
2151
2152 func readvRacedetect(iovecs []Iovec, n int, err error) {
2153 if !raceenabled {
2154 return
2155 }
2156 for i := 0; n > 0 && i < len(iovecs); i++ {
2157 m := int(iovecs[i].Len)
2158 if m > n {
2159 m = n
2160 }
2161 n -= m
2162 if m > 0 {
2163 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
2164 }
2165 }
2166 if err == nil {
2167 raceAcquire(unsafe.Pointer(&ioSync))
2168 }
2169 }
2170
2171 func Writev(fd int, iovs [][]byte) (n int, err error) {
2172 iovecs := make([]Iovec, 0, minIovec)
2173 iovecs = appendBytes(iovecs, iovs)
2174 if raceenabled {
2175 raceReleaseMerge(unsafe.Pointer(&ioSync))
2176 }
2177 n, err = writev(fd, iovecs)
2178 writevRacedetect(iovecs, n)
2179 return n, err
2180 }
2181
2182 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
2183 iovecs := make([]Iovec, 0, minIovec)
2184 iovecs = appendBytes(iovecs, iovs)
2185 if raceenabled {
2186 raceReleaseMerge(unsafe.Pointer(&ioSync))
2187 }
2188 lo, hi := offs2lohi(offset)
2189 n, err = pwritev(fd, iovecs, lo, hi)
2190 writevRacedetect(iovecs, n)
2191 return n, err
2192 }
2193
2194 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
2195 iovecs := make([]Iovec, 0, minIovec)
2196 iovecs = appendBytes(iovecs, iovs)
2197 if raceenabled {
2198 raceReleaseMerge(unsafe.Pointer(&ioSync))
2199 }
2200 lo, hi := offs2lohi(offset)
2201 n, err = pwritev2(fd, iovecs, lo, hi, flags)
2202 writevRacedetect(iovecs, n)
2203 return n, err
2204 }
2205
2206 func writevRacedetect(iovecs []Iovec, n int) {
2207 if !raceenabled {
2208 return
2209 }
2210 for i := 0; n > 0 && i < len(iovecs); i++ {
2211 m := int(iovecs[i].Len)
2212 if m > n {
2213 m = n
2214 }
2215 n -= m
2216 if m > 0 {
2217 raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
2218 }
2219 }
2220 }
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233 const (
2234 mremapFixed = MREMAP_FIXED
2235 mremapDontunmap = MREMAP_DONTUNMAP
2236 mremapMaymove = MREMAP_MAYMOVE
2237 )
2238
2239
2240
2241 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
2242 var p unsafe.Pointer
2243 if len(iovs) > 0 {
2244 p = unsafe.Pointer(&iovs[0])
2245 }
2246
2247 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0)
2248 if errno != 0 {
2249 return 0, syscall.Errno(errno)
2250 }
2251
2252 return int(n), nil
2253 }
2254
2255 func isGroupMember(gid int) bool {
2256 groups, err := Getgroups()
2257 if err != nil {
2258 return false
2259 }
2260
2261 for _, g := range groups {
2262 if g == gid {
2263 return true
2264 }
2265 }
2266 return false
2267 }
2268
2269 func isCapDacOverrideSet() bool {
2270 hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3}
2271 data := [2]CapUserData{}
2272 err := Capget(&hdr, &data[0])
2273
2274 return err == nil && data[0].Effective&(1<<CAP_DAC_OVERRIDE) != 0
2275 }
2276
2277
2278
2279
2280 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
2281 if flags == 0 {
2282 return faccessat(dirfd, path, mode)
2283 }
2284
2285 if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
2286 return err
2287 }
2288
2289
2290
2291
2292
2293
2294
2295 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
2296 return EINVAL
2297 }
2298
2299 var st Stat_t
2300 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil {
2301 return err
2302 }
2303
2304 mode &= 7
2305 if mode == 0 {
2306 return nil
2307 }
2308
2309 var uid int
2310 if flags&AT_EACCESS != 0 {
2311 uid = Geteuid()
2312 if uid != 0 && isCapDacOverrideSet() {
2313
2314
2315
2316 uid = 0
2317 }
2318 } else {
2319 uid = Getuid()
2320 }
2321
2322 if uid == 0 {
2323 if mode&1 == 0 {
2324
2325 return nil
2326 }
2327 if st.Mode&0111 != 0 {
2328
2329 return nil
2330 }
2331 return EACCES
2332 }
2333
2334 var fmode uint32
2335 if uint32(uid) == st.Uid {
2336 fmode = (st.Mode >> 6) & 7
2337 } else {
2338 var gid int
2339 if flags&AT_EACCESS != 0 {
2340 gid = Getegid()
2341 } else {
2342 gid = Getgid()
2343 }
2344
2345 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
2346 fmode = (st.Mode >> 3) & 7
2347 } else {
2348 fmode = st.Mode & 7
2349 }
2350 }
2351
2352 if fmode&mode == mode {
2353 return nil
2354 }
2355
2356 return EACCES
2357 }
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367 type fileHandle struct {
2368 Bytes uint32
2369 Type int32
2370 }
2371
2372
2373
2374
2375 type FileHandle struct {
2376 *fileHandle
2377 }
2378
2379
2380 func NewFileHandle(handleType int32, handle []byte) FileHandle {
2381 const hdrSize = unsafe.Sizeof(fileHandle{})
2382 buf := make([]byte, hdrSize+uintptr(len(handle)))
2383 copy(buf[hdrSize:], handle)
2384 fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
2385 fh.Type = handleType
2386 fh.Bytes = uint32(len(handle))
2387 return FileHandle{fh}
2388 }
2389
2390 func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) }
2391 func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type }
2392 func (fh *FileHandle) Bytes() []byte {
2393 n := fh.Size()
2394 if n == 0 {
2395 return nil
2396 }
2397 return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
2398 }
2399
2400
2401
2402 func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) {
2403 var mid _C_int
2404
2405
2406 size := uint32(32 + unsafe.Sizeof(fileHandle{}))
2407 didResize := false
2408 for {
2409 buf := make([]byte, size)
2410 fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
2411 fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{}))
2412 err = nameToHandleAt(dirfd, path, fh, &mid, flags)
2413 if err == EOVERFLOW {
2414 if didResize {
2415
2416 return
2417 }
2418 didResize = true
2419 size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{}))
2420 continue
2421 }
2422 if err != nil {
2423 return
2424 }
2425 return FileHandle{fh}, int(mid), nil
2426 }
2427 }
2428
2429
2430
2431 func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) {
2432 return openByHandleAt(mountFD, handle.fileHandle, flags)
2433 }
2434
2435
2436
2437 func Klogset(typ int, arg int) (err error) {
2438 var p unsafe.Pointer
2439 _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg))
2440 if errno != 0 {
2441 return errnoErr(errno)
2442 }
2443 return nil
2444 }
2445
2446
2447
2448
2449
2450 type RemoteIovec struct {
2451 Base uintptr
2452 Len int
2453 }
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471 func MakeItimerval(interval, value time.Duration) Itimerval {
2472 return Itimerval{
2473 Interval: NsecToTimeval(interval.Nanoseconds()),
2474 Value: NsecToTimeval(value.Nanoseconds()),
2475 }
2476 }
2477
2478
2479
2480 type ItimerWhich int
2481
2482
2483 const (
2484 ItimerReal ItimerWhich = ITIMER_REAL
2485 ItimerVirtual ItimerWhich = ITIMER_VIRTUAL
2486 ItimerProf ItimerWhich = ITIMER_PROF
2487 )
2488
2489
2490
2491 func Getitimer(which ItimerWhich) (Itimerval, error) {
2492 var it Itimerval
2493 if err := getitimer(int(which), &it); err != nil {
2494 return Itimerval{}, err
2495 }
2496
2497 return it, nil
2498 }
2499
2500
2501
2502
2503
2504 func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
2505 var prev Itimerval
2506 if err := setitimer(int(which), &it, &prev); err != nil {
2507 return Itimerval{}, err
2508 }
2509
2510 return prev, nil
2511 }
2512
2513
2514
2515 func PthreadSigmask(how int, set, oldset *Sigset_t) error {
2516 if oldset != nil {
2517
2518 *oldset = Sigset_t{}
2519 }
2520 return rtSigprocmask(how, set, oldset, _C__NSIG/8)
2521 }
2522
2523
2524
2525
2526 func Getresuid() (ruid, euid, suid int) {
2527 var r, e, s _C_int
2528 getresuid(&r, &e, &s)
2529 return int(r), int(e), int(s)
2530 }
2531
2532 func Getresgid() (rgid, egid, sgid int) {
2533 var r, e, s _C_int
2534 getresgid(&r, &e, &s)
2535 return int(r), int(e), int(s)
2536 }
2537
2538
2539
2540 func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
2541
2542
2543
2544 var mutableTimeout *Timespec
2545 if timeout != nil {
2546 mutableTimeout = new(Timespec)
2547 *mutableTimeout = *timeout
2548 }
2549
2550
2551
2552 var kernelMask *sigset_argpack
2553 if sigmask != nil {
2554 wordBits := 32 << (^uintptr(0) >> 63)
2555
2556
2557
2558
2559 sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits)
2560
2561 sigsetBytes := uintptr(sigsetWords * (wordBits / 8))
2562 kernelMask = &sigset_argpack{
2563 ss: sigmask,
2564 ssLen: sigsetBytes,
2565 }
2566 }
2567
2568 return pselect6(nfd, r, w, e, mutableTimeout, kernelMask)
2569 }
2570
2571
2572
2573
2574
2575
2576 func SchedSetAttr(pid int, attr *SchedAttr, flags uint) error {
2577 if attr == nil {
2578 return EINVAL
2579 }
2580 attr.Size = SizeofSchedAttr
2581 return schedSetattr(pid, attr, flags)
2582 }
2583
2584
2585
2586 func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) {
2587 attr := &SchedAttr{}
2588 if err := schedGetattr(pid, attr, SizeofSchedAttr, flags); err != nil {
2589 return nil, err
2590 }
2591 return attr, nil
2592 }
2593
2594
2595
View as plain text