github.com/zaquestion/lab@v0.25.1/cmd/util_windows.go (about) 1 // This file contains Windows specific calls. 2 3 package cmd 4 5 // Even though Windows has a POSIX layer, it's implemented in userspace and, 6 // consequently, the "syscall" lib doesn't export it. 7 // Because of it, we need to use specific Windows calls to handle some of the 8 // syscall we're using the `lab`. 9 10 import "syscall" 11 12 // SetStdHandle is not exported by golang syscall lib, we need to get it 13 // ourselves from kernel32.dll. 14 var ( 15 kernel32 = syscall.MustLoadDLL("kernel32.dll") 16 procSetStdHandleAddr = kernel32.MustFindProc("SetStdHandle").Addr() 17 ) 18 19 // Windows has the concept of "Handles", which in Unix can be directly 20 // converted to integers. 21 var ( 22 sysStdout = int(syscall.Stdout) 23 sysStderr = int(syscall.Stderr) 24 ) 25 26 // closeFD behaves the as POSIX close() 27 func closeFD(fd int) error { 28 return syscall.Close(syscall.Handle(fd)) 29 } 30 31 // dupFD behaves the same as POSIX dup() 32 func dupFD(fd int) (int, error) { 33 proc, err := syscall.GetCurrentProcess() 34 if err != nil { 35 return 0, err 36 } 37 38 var hndl syscall.Handle 39 err = syscall.DuplicateHandle(proc, syscall.Handle(fd), proc, &hndl, 0, true, syscall.DUPLICATE_SAME_ACCESS) 40 return int(hndl), err 41 } 42 43 // dupFD2 behaves the same as POSIX dup2() 44 func dupFD2(oldFD, newFD int) error { 45 ret, _, err := syscall.Syscall(procSetStdHandleAddr, 2, uintptr(oldFD), uintptr(newFD), 0) 46 if err != 0 { 47 return error(err) 48 } 49 50 if ret == 0 { 51 return syscall.EINVAL 52 } 53 54 return nil 55 }