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