Source file src/pkg/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go
1
2
3
4
5
6
7 package windows
8
9 import (
10 errorspkg "errors"
11 "sync"
12 "syscall"
13 "unicode/utf16"
14 "unsafe"
15 )
16
17 type Handle uintptr
18
19 const (
20 InvalidHandle = ^Handle(0)
21
22
23 DDD_EXACT_MATCH_ON_REMOVE = 0x00000004
24 DDD_NO_BROADCAST_SYSTEM = 0x00000008
25 DDD_RAW_TARGET_PATH = 0x00000001
26 DDD_REMOVE_DEFINITION = 0x00000002
27
28
29 DRIVE_UNKNOWN = 0
30 DRIVE_NO_ROOT_DIR = 1
31 DRIVE_REMOVABLE = 2
32 DRIVE_FIXED = 3
33 DRIVE_REMOTE = 4
34 DRIVE_CDROM = 5
35 DRIVE_RAMDISK = 6
36
37
38 FILE_CASE_SENSITIVE_SEARCH = 0x00000001
39 FILE_CASE_PRESERVED_NAMES = 0x00000002
40 FILE_FILE_COMPRESSION = 0x00000010
41 FILE_DAX_VOLUME = 0x20000000
42 FILE_NAMED_STREAMS = 0x00040000
43 FILE_PERSISTENT_ACLS = 0x00000008
44 FILE_READ_ONLY_VOLUME = 0x00080000
45 FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000
46 FILE_SUPPORTS_ENCRYPTION = 0x00020000
47 FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000
48 FILE_SUPPORTS_HARD_LINKS = 0x00400000
49 FILE_SUPPORTS_OBJECT_IDS = 0x00010000
50 FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000
51 FILE_SUPPORTS_REPARSE_POINTS = 0x00000080
52 FILE_SUPPORTS_SPARSE_FILES = 0x00000040
53 FILE_SUPPORTS_TRANSACTIONS = 0x00200000
54 FILE_SUPPORTS_USN_JOURNAL = 0x02000000
55 FILE_UNICODE_ON_DISK = 0x00000004
56 FILE_VOLUME_IS_COMPRESSED = 0x00008000
57 FILE_VOLUME_QUOTAS = 0x00000020
58 )
59
60
61
62
63 func StringToUTF16(s string) []uint16 {
64 a, err := UTF16FromString(s)
65 if err != nil {
66 panic("windows: string with NUL passed to StringToUTF16")
67 }
68 return a
69 }
70
71
72
73
74 func UTF16FromString(s string) ([]uint16, error) {
75 for i := 0; i < len(s); i++ {
76 if s[i] == 0 {
77 return nil, syscall.EINVAL
78 }
79 }
80 return utf16.Encode([]rune(s + "\x00")), nil
81 }
82
83
84
85 func UTF16ToString(s []uint16) string {
86 for i, v := range s {
87 if v == 0 {
88 s = s[0:i]
89 break
90 }
91 }
92 return string(utf16.Decode(s))
93 }
94
95
96
97
98 func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
99
100
101
102
103 func UTF16PtrFromString(s string) (*uint16, error) {
104 a, err := UTF16FromString(s)
105 if err != nil {
106 return nil, err
107 }
108 return &a[0], nil
109 }
110
111 func Getpagesize() int { return 4096 }
112
113
114
115
116 func NewCallback(fn interface{}) uintptr {
117 return syscall.NewCallback(fn)
118 }
119
120
121
122
123 func NewCallbackCDecl(fn interface{}) uintptr {
124 return syscall.NewCallbackCDecl(fn)
125 }
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) {
273 r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0)
274 proc = uintptr(r0)
275 if proc == 0 {
276 if e1 != 0 {
277 err = errnoErr(e1)
278 } else {
279 err = syscall.EINVAL
280 }
281 }
282 return
283 }
284
285 func Exit(code int) { ExitProcess(uint32(code)) }
286
287 func makeInheritSa() *SecurityAttributes {
288 var sa SecurityAttributes
289 sa.Length = uint32(unsafe.Sizeof(sa))
290 sa.InheritHandle = 1
291 return &sa
292 }
293
294 func Open(path string, mode int, perm uint32) (fd Handle, err error) {
295 if len(path) == 0 {
296 return InvalidHandle, ERROR_FILE_NOT_FOUND
297 }
298 pathp, err := UTF16PtrFromString(path)
299 if err != nil {
300 return InvalidHandle, err
301 }
302 var access uint32
303 switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
304 case O_RDONLY:
305 access = GENERIC_READ
306 case O_WRONLY:
307 access = GENERIC_WRITE
308 case O_RDWR:
309 access = GENERIC_READ | GENERIC_WRITE
310 }
311 if mode&O_CREAT != 0 {
312 access |= GENERIC_WRITE
313 }
314 if mode&O_APPEND != 0 {
315 access &^= GENERIC_WRITE
316 access |= FILE_APPEND_DATA
317 }
318 sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
319 var sa *SecurityAttributes
320 if mode&O_CLOEXEC == 0 {
321 sa = makeInheritSa()
322 }
323 var createmode uint32
324 switch {
325 case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
326 createmode = CREATE_NEW
327 case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
328 createmode = CREATE_ALWAYS
329 case mode&O_CREAT == O_CREAT:
330 createmode = OPEN_ALWAYS
331 case mode&O_TRUNC == O_TRUNC:
332 createmode = TRUNCATE_EXISTING
333 default:
334 createmode = OPEN_EXISTING
335 }
336 h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
337 return h, e
338 }
339
340 func Read(fd Handle, p []byte) (n int, err error) {
341 var done uint32
342 e := ReadFile(fd, p, &done, nil)
343 if e != nil {
344 if e == ERROR_BROKEN_PIPE {
345
346 return 0, nil
347 }
348 return 0, e
349 }
350 if raceenabled {
351 if done > 0 {
352 raceWriteRange(unsafe.Pointer(&p[0]), int(done))
353 }
354 raceAcquire(unsafe.Pointer(&ioSync))
355 }
356 return int(done), nil
357 }
358
359 func Write(fd Handle, p []byte) (n int, err error) {
360 if raceenabled {
361 raceReleaseMerge(unsafe.Pointer(&ioSync))
362 }
363 var done uint32
364 e := WriteFile(fd, p, &done, nil)
365 if e != nil {
366 return 0, e
367 }
368 if raceenabled && done > 0 {
369 raceReadRange(unsafe.Pointer(&p[0]), int(done))
370 }
371 return int(done), nil
372 }
373
374 var ioSync int64
375
376 func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
377 var w uint32
378 switch whence {
379 case 0:
380 w = FILE_BEGIN
381 case 1:
382 w = FILE_CURRENT
383 case 2:
384 w = FILE_END
385 }
386 hi := int32(offset >> 32)
387 lo := int32(offset)
388
389 ft, _ := GetFileType(fd)
390 if ft == FILE_TYPE_PIPE {
391 return 0, syscall.EPIPE
392 }
393 rlo, e := SetFilePointer(fd, lo, &hi, w)
394 if e != nil {
395 return 0, e
396 }
397 return int64(hi)<<32 + int64(rlo), nil
398 }
399
400 func Close(fd Handle) (err error) {
401 return CloseHandle(fd)
402 }
403
404 var (
405 Stdin = getStdHandle(STD_INPUT_HANDLE)
406 Stdout = getStdHandle(STD_OUTPUT_HANDLE)
407 Stderr = getStdHandle(STD_ERROR_HANDLE)
408 )
409
410 func getStdHandle(stdhandle uint32) (fd Handle) {
411 r, _ := GetStdHandle(stdhandle)
412 CloseOnExec(r)
413 return r
414 }
415
416 const ImplementsGetwd = true
417
418 func Getwd() (wd string, err error) {
419 b := make([]uint16, 300)
420 n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
421 if e != nil {
422 return "", e
423 }
424 return string(utf16.Decode(b[0:n])), nil
425 }
426
427 func Chdir(path string) (err error) {
428 pathp, err := UTF16PtrFromString(path)
429 if err != nil {
430 return err
431 }
432 return SetCurrentDirectory(pathp)
433 }
434
435 func Mkdir(path string, mode uint32) (err error) {
436 pathp, err := UTF16PtrFromString(path)
437 if err != nil {
438 return err
439 }
440 return CreateDirectory(pathp, nil)
441 }
442
443 func Rmdir(path string) (err error) {
444 pathp, err := UTF16PtrFromString(path)
445 if err != nil {
446 return err
447 }
448 return RemoveDirectory(pathp)
449 }
450
451 func Unlink(path string) (err error) {
452 pathp, err := UTF16PtrFromString(path)
453 if err != nil {
454 return err
455 }
456 return DeleteFile(pathp)
457 }
458
459 func Rename(oldpath, newpath string) (err error) {
460 from, err := UTF16PtrFromString(oldpath)
461 if err != nil {
462 return err
463 }
464 to, err := UTF16PtrFromString(newpath)
465 if err != nil {
466 return err
467 }
468 return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
469 }
470
471 func ComputerName() (name string, err error) {
472 var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
473 b := make([]uint16, n)
474 e := GetComputerName(&b[0], &n)
475 if e != nil {
476 return "", e
477 }
478 return string(utf16.Decode(b[0:n])), nil
479 }
480
481 func Ftruncate(fd Handle, length int64) (err error) {
482 curoffset, e := Seek(fd, 0, 1)
483 if e != nil {
484 return e
485 }
486 defer Seek(fd, curoffset, 0)
487 _, e = Seek(fd, length, 0)
488 if e != nil {
489 return e
490 }
491 e = SetEndOfFile(fd)
492 if e != nil {
493 return e
494 }
495 return nil
496 }
497
498 func Gettimeofday(tv *Timeval) (err error) {
499 var ft Filetime
500 GetSystemTimeAsFileTime(&ft)
501 *tv = NsecToTimeval(ft.Nanoseconds())
502 return nil
503 }
504
505 func Pipe(p []Handle) (err error) {
506 if len(p) != 2 {
507 return syscall.EINVAL
508 }
509 var r, w Handle
510 e := CreatePipe(&r, &w, makeInheritSa(), 0)
511 if e != nil {
512 return e
513 }
514 p[0] = r
515 p[1] = w
516 return nil
517 }
518
519 func Utimes(path string, tv []Timeval) (err error) {
520 if len(tv) != 2 {
521 return syscall.EINVAL
522 }
523 pathp, e := UTF16PtrFromString(path)
524 if e != nil {
525 return e
526 }
527 h, e := CreateFile(pathp,
528 FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
529 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
530 if e != nil {
531 return e
532 }
533 defer Close(h)
534 a := NsecToFiletime(tv[0].Nanoseconds())
535 w := NsecToFiletime(tv[1].Nanoseconds())
536 return SetFileTime(h, nil, &a, &w)
537 }
538
539 func UtimesNano(path string, ts []Timespec) (err error) {
540 if len(ts) != 2 {
541 return syscall.EINVAL
542 }
543 pathp, e := UTF16PtrFromString(path)
544 if e != nil {
545 return e
546 }
547 h, e := CreateFile(pathp,
548 FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
549 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
550 if e != nil {
551 return e
552 }
553 defer Close(h)
554 a := NsecToFiletime(TimespecToNsec(ts[0]))
555 w := NsecToFiletime(TimespecToNsec(ts[1]))
556 return SetFileTime(h, nil, &a, &w)
557 }
558
559 func Fsync(fd Handle) (err error) {
560 return FlushFileBuffers(fd)
561 }
562
563 func Chmod(path string, mode uint32) (err error) {
564 p, e := UTF16PtrFromString(path)
565 if e != nil {
566 return e
567 }
568 attrs, e := GetFileAttributes(p)
569 if e != nil {
570 return e
571 }
572 if mode&S_IWRITE != 0 {
573 attrs &^= FILE_ATTRIBUTE_READONLY
574 } else {
575 attrs |= FILE_ATTRIBUTE_READONLY
576 }
577 return SetFileAttributes(p, attrs)
578 }
579
580 func LoadGetSystemTimePreciseAsFileTime() error {
581 return procGetSystemTimePreciseAsFileTime.Find()
582 }
583
584 func LoadCancelIoEx() error {
585 return procCancelIoEx.Find()
586 }
587
588 func LoadSetFileCompletionNotificationModes() error {
589 return procSetFileCompletionNotificationModes.Find()
590 }
591
592 func WaitForMultipleObjects(handles []Handle, waitAll bool, waitMilliseconds uint32) (event uint32, err error) {
593
594
595
596
597 var handlePtr *Handle
598 if len(handles) > 0 {
599 handlePtr = &handles[0]
600 }
601 return waitForMultipleObjects(uint32(len(handles)), uintptr(unsafe.Pointer(handlePtr)), waitAll, waitMilliseconds)
602 }
603
604
605
606 const socket_error = uintptr(^uint32(0))
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646 var SocketDisableIPv6 bool
647
648 type RawSockaddrInet4 struct {
649 Family uint16
650 Port uint16
651 Addr [4]byte
652 Zero [8]uint8
653 }
654
655 type RawSockaddrInet6 struct {
656 Family uint16
657 Port uint16
658 Flowinfo uint32
659 Addr [16]byte
660 Scope_id uint32
661 }
662
663 type RawSockaddr struct {
664 Family uint16
665 Data [14]int8
666 }
667
668 type RawSockaddrAny struct {
669 Addr RawSockaddr
670 Pad [100]int8
671 }
672
673 type Sockaddr interface {
674 sockaddr() (ptr unsafe.Pointer, len int32, err error)
675 }
676
677 type SockaddrInet4 struct {
678 Port int
679 Addr [4]byte
680 raw RawSockaddrInet4
681 }
682
683 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
684 if sa.Port < 0 || sa.Port > 0xFFFF {
685 return nil, 0, syscall.EINVAL
686 }
687 sa.raw.Family = AF_INET
688 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
689 p[0] = byte(sa.Port >> 8)
690 p[1] = byte(sa.Port)
691 for i := 0; i < len(sa.Addr); i++ {
692 sa.raw.Addr[i] = sa.Addr[i]
693 }
694 return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
695 }
696
697 type SockaddrInet6 struct {
698 Port int
699 ZoneId uint32
700 Addr [16]byte
701 raw RawSockaddrInet6
702 }
703
704 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
705 if sa.Port < 0 || sa.Port > 0xFFFF {
706 return nil, 0, syscall.EINVAL
707 }
708 sa.raw.Family = AF_INET6
709 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
710 p[0] = byte(sa.Port >> 8)
711 p[1] = byte(sa.Port)
712 sa.raw.Scope_id = sa.ZoneId
713 for i := 0; i < len(sa.Addr); i++ {
714 sa.raw.Addr[i] = sa.Addr[i]
715 }
716 return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
717 }
718
719 type RawSockaddrUnix struct {
720 Family uint16
721 Path [UNIX_PATH_MAX]int8
722 }
723
724 type SockaddrUnix struct {
725 Name string
726 raw RawSockaddrUnix
727 }
728
729 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
730 name := sa.Name
731 n := len(name)
732 if n > len(sa.raw.Path) {
733 return nil, 0, syscall.EINVAL
734 }
735 if n == len(sa.raw.Path) && name[0] != '@' {
736 return nil, 0, syscall.EINVAL
737 }
738 sa.raw.Family = AF_UNIX
739 for i := 0; i < n; i++ {
740 sa.raw.Path[i] = int8(name[i])
741 }
742
743 sl := int32(2)
744 if n > 0 {
745 sl += int32(n) + 1
746 }
747 if sa.raw.Path[0] == '@' {
748 sa.raw.Path[0] = 0
749
750 sl--
751 }
752
753 return unsafe.Pointer(&sa.raw), sl, nil
754 }
755
756 func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
757 switch rsa.Addr.Family {
758 case AF_UNIX:
759 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
760 sa := new(SockaddrUnix)
761 if pp.Path[0] == 0 {
762
763
764
765
766
767 pp.Path[0] = '@'
768 }
769
770
771
772
773
774
775 n := 0
776 for n < len(pp.Path) && pp.Path[n] != 0 {
777 n++
778 }
779 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
780 sa.Name = string(bytes)
781 return sa, nil
782
783 case AF_INET:
784 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
785 sa := new(SockaddrInet4)
786 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
787 sa.Port = int(p[0])<<8 + int(p[1])
788 for i := 0; i < len(sa.Addr); i++ {
789 sa.Addr[i] = pp.Addr[i]
790 }
791 return sa, nil
792
793 case AF_INET6:
794 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
795 sa := new(SockaddrInet6)
796 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
797 sa.Port = int(p[0])<<8 + int(p[1])
798 sa.ZoneId = pp.Scope_id
799 for i := 0; i < len(sa.Addr); i++ {
800 sa.Addr[i] = pp.Addr[i]
801 }
802 return sa, nil
803 }
804 return nil, syscall.EAFNOSUPPORT
805 }
806
807 func Socket(domain, typ, proto int) (fd Handle, err error) {
808 if domain == AF_INET6 && SocketDisableIPv6 {
809 return InvalidHandle, syscall.EAFNOSUPPORT
810 }
811 return socket(int32(domain), int32(typ), int32(proto))
812 }
813
814 func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
815 v := int32(value)
816 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
817 }
818
819 func Bind(fd Handle, sa Sockaddr) (err error) {
820 ptr, n, err := sa.sockaddr()
821 if err != nil {
822 return err
823 }
824 return bind(fd, ptr, n)
825 }
826
827 func Connect(fd Handle, sa Sockaddr) (err error) {
828 ptr, n, err := sa.sockaddr()
829 if err != nil {
830 return err
831 }
832 return connect(fd, ptr, n)
833 }
834
835 func Getsockname(fd Handle) (sa Sockaddr, err error) {
836 var rsa RawSockaddrAny
837 l := int32(unsafe.Sizeof(rsa))
838 if err = getsockname(fd, &rsa, &l); err != nil {
839 return
840 }
841 return rsa.Sockaddr()
842 }
843
844 func Getpeername(fd Handle) (sa Sockaddr, err error) {
845 var rsa RawSockaddrAny
846 l := int32(unsafe.Sizeof(rsa))
847 if err = getpeername(fd, &rsa, &l); err != nil {
848 return
849 }
850 return rsa.Sockaddr()
851 }
852
853 func Listen(s Handle, n int) (err error) {
854 return listen(s, int32(n))
855 }
856
857 func Shutdown(fd Handle, how int) (err error) {
858 return shutdown(fd, int32(how))
859 }
860
861 func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
862 rsa, l, err := to.sockaddr()
863 if err != nil {
864 return err
865 }
866 return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
867 }
868
869 func LoadGetAddrInfo() error {
870 return procGetAddrInfoW.Find()
871 }
872
873 var connectExFunc struct {
874 once sync.Once
875 addr uintptr
876 err error
877 }
878
879 func LoadConnectEx() error {
880 connectExFunc.once.Do(func() {
881 var s Handle
882 s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
883 if connectExFunc.err != nil {
884 return
885 }
886 defer CloseHandle(s)
887 var n uint32
888 connectExFunc.err = WSAIoctl(s,
889 SIO_GET_EXTENSION_FUNCTION_POINTER,
890 (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
891 uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
892 (*byte)(unsafe.Pointer(&connectExFunc.addr)),
893 uint32(unsafe.Sizeof(connectExFunc.addr)),
894 &n, nil, 0)
895 })
896 return connectExFunc.err
897 }
898
899 func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
900 r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
901 if r1 == 0 {
902 if e1 != 0 {
903 err = error(e1)
904 } else {
905 err = syscall.EINVAL
906 }
907 }
908 return
909 }
910
911 func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
912 err := LoadConnectEx()
913 if err != nil {
914 return errorspkg.New("failed to find ConnectEx: " + err.Error())
915 }
916 ptr, n, err := sa.sockaddr()
917 if err != nil {
918 return err
919 }
920 return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
921 }
922
923 var sendRecvMsgFunc struct {
924 once sync.Once
925 sendAddr uintptr
926 recvAddr uintptr
927 err error
928 }
929
930 func loadWSASendRecvMsg() error {
931 sendRecvMsgFunc.once.Do(func() {
932 var s Handle
933 s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
934 if sendRecvMsgFunc.err != nil {
935 return
936 }
937 defer CloseHandle(s)
938 var n uint32
939 sendRecvMsgFunc.err = WSAIoctl(s,
940 SIO_GET_EXTENSION_FUNCTION_POINTER,
941 (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
942 uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
943 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
944 uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
945 &n, nil, 0)
946 if sendRecvMsgFunc.err != nil {
947 return
948 }
949 sendRecvMsgFunc.err = WSAIoctl(s,
950 SIO_GET_EXTENSION_FUNCTION_POINTER,
951 (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
952 uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
953 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
954 uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
955 &n, nil, 0)
956 })
957 return sendRecvMsgFunc.err
958 }
959
960 func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error {
961 err := loadWSASendRecvMsg()
962 if err != nil {
963 return err
964 }
965 r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
966 if r1 == socket_error {
967 if e1 != 0 {
968 err = errnoErr(e1)
969 } else {
970 err = syscall.EINVAL
971 }
972 }
973 return err
974 }
975
976 func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error {
977 err := loadWSASendRecvMsg()
978 if err != nil {
979 return err
980 }
981 r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
982 if r1 == socket_error {
983 if e1 != 0 {
984 err = errnoErr(e1)
985 } else {
986 err = syscall.EINVAL
987 }
988 }
989 return err
990 }
991
992
993 type Rusage struct {
994 CreationTime Filetime
995 ExitTime Filetime
996 KernelTime Filetime
997 UserTime Filetime
998 }
999
1000 type WaitStatus struct {
1001 ExitCode uint32
1002 }
1003
1004 func (w WaitStatus) Exited() bool { return true }
1005
1006 func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
1007
1008 func (w WaitStatus) Signal() Signal { return -1 }
1009
1010 func (w WaitStatus) CoreDump() bool { return false }
1011
1012 func (w WaitStatus) Stopped() bool { return false }
1013
1014 func (w WaitStatus) Continued() bool { return false }
1015
1016 func (w WaitStatus) StopSignal() Signal { return -1 }
1017
1018 func (w WaitStatus) Signaled() bool { return false }
1019
1020 func (w WaitStatus) TrapCause() int { return -1 }
1021
1022
1023
1024 type Timespec struct {
1025 Sec int64
1026 Nsec int64
1027 }
1028
1029 func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
1030
1031 func NsecToTimespec(nsec int64) (ts Timespec) {
1032 ts.Sec = nsec / 1e9
1033 ts.Nsec = nsec % 1e9
1034 return
1035 }
1036
1037
1038
1039 func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS }
1040 func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
1041 return 0, nil, syscall.EWINDOWS
1042 }
1043 func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return syscall.EWINDOWS }
1044 func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS }
1045
1046
1047
1048
1049
1050
1051
1052
1053 type Linger struct {
1054 Onoff int32
1055 Linger int32
1056 }
1057
1058 type sysLinger struct {
1059 Onoff uint16
1060 Linger uint16
1061 }
1062
1063 type IPMreq struct {
1064 Multiaddr [4]byte
1065 Interface [4]byte
1066 }
1067
1068 type IPv6Mreq struct {
1069 Multiaddr [16]byte
1070 Interface uint32
1071 }
1072
1073 func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS }
1074
1075 func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
1076 sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
1077 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
1078 }
1079
1080 func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
1081 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
1082 }
1083 func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
1084 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
1085 }
1086 func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
1087 return syscall.EWINDOWS
1088 }
1089
1090 func Getpid() (pid int) { return int(getCurrentProcessId()) }
1091
1092 func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
1093
1094
1095
1096
1097
1098
1099
1100
1101 var data1 win32finddata1
1102 handle, err = findFirstFile1(name, &data1)
1103 if err == nil {
1104 copyFindData(data, &data1)
1105 }
1106 return
1107 }
1108
1109 func FindNextFile(handle Handle, data *Win32finddata) (err error) {
1110 var data1 win32finddata1
1111 err = findNextFile1(handle, &data1)
1112 if err == nil {
1113 copyFindData(data, &data1)
1114 }
1115 return
1116 }
1117
1118 func getProcessEntry(pid int) (*ProcessEntry32, error) {
1119 snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
1120 if err != nil {
1121 return nil, err
1122 }
1123 defer CloseHandle(snapshot)
1124 var procEntry ProcessEntry32
1125 procEntry.Size = uint32(unsafe.Sizeof(procEntry))
1126 if err = Process32First(snapshot, &procEntry); err != nil {
1127 return nil, err
1128 }
1129 for {
1130 if procEntry.ProcessID == uint32(pid) {
1131 return &procEntry, nil
1132 }
1133 err = Process32Next(snapshot, &procEntry)
1134 if err != nil {
1135 return nil, err
1136 }
1137 }
1138 }
1139
1140 func Getppid() (ppid int) {
1141 pe, err := getProcessEntry(Getpid())
1142 if err != nil {
1143 return -1
1144 }
1145 return int(pe.ParentProcessID)
1146 }
1147
1148
1149 func Fchdir(fd Handle) (err error) { return syscall.EWINDOWS }
1150 func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS }
1151 func Symlink(path, link string) (err error) { return syscall.EWINDOWS }
1152
1153 func Fchmod(fd Handle, mode uint32) (err error) { return syscall.EWINDOWS }
1154 func Chown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS }
1155 func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS }
1156 func Fchown(fd Handle, uid int, gid int) (err error) { return syscall.EWINDOWS }
1157
1158 func Getuid() (uid int) { return -1 }
1159 func Geteuid() (euid int) { return -1 }
1160 func Getgid() (gid int) { return -1 }
1161 func Getegid() (egid int) { return -1 }
1162 func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS }
1163
1164 type Signal int
1165
1166 func (s Signal) Signal() {}
1167
1168 func (s Signal) String() string {
1169 if 0 <= s && int(s) < len(signals) {
1170 str := signals[s]
1171 if str != "" {
1172 return str
1173 }
1174 }
1175 return "signal " + itoa(int(s))
1176 }
1177
1178 func LoadCreateSymbolicLink() error {
1179 return procCreateSymbolicLinkW.Find()
1180 }
1181
1182
1183 func Readlink(path string, buf []byte) (n int, err error) {
1184 fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
1185 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
1186 if err != nil {
1187 return -1, err
1188 }
1189 defer CloseHandle(fd)
1190
1191 rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
1192 var bytesReturned uint32
1193 err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
1194 if err != nil {
1195 return -1, err
1196 }
1197
1198 rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
1199 var s string
1200 switch rdb.ReparseTag {
1201 case IO_REPARSE_TAG_SYMLINK:
1202 data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
1203 p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
1204 s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
1205 case IO_REPARSE_TAG_MOUNT_POINT:
1206 data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
1207 p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
1208 s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
1209 default:
1210
1211
1212 return -1, syscall.ENOENT
1213 }
1214 n = copy(buf, []byte(s))
1215
1216 return n, nil
1217 }
1218
View as plain text