mirror of
https://github.com/rclone/rclone.git
synced 2025-01-03 04:49:47 +01:00
log: update windows redirection code to use x/sys/windows and include dup
This modernises the Windows redirect code to use x/sys/windows and to dup os.Stderr for use in the terminal.
This commit is contained in:
parent
16b383e18f
commit
3450d049b5
@ -12,29 +12,43 @@ package log
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/rclone/rclone/lib/terminal"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// dup oldfd creating a functional copy as newfd
|
||||
// conceptually the same as the unix `dup()` function
|
||||
func dup(oldfd uintptr) (newfd uintptr, err error) {
|
||||
var (
|
||||
kernel32 = syscall.MustLoadDLL("kernel32.dll")
|
||||
procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
|
||||
newfdHandle windows.Handle
|
||||
processHandle = windows.CurrentProcess()
|
||||
)
|
||||
|
||||
func setStdHandle(stdhandle int32, handle syscall.Handle) error {
|
||||
r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
|
||||
if r0 == 0 {
|
||||
if e1 != 0 {
|
||||
return error(e1)
|
||||
err = windows.DuplicateHandle(
|
||||
processHandle, // hSourceProcessHandle
|
||||
windows.Handle(oldfd), // hSourceHandle
|
||||
processHandle, // hTargetProcessHandle
|
||||
&newfdHandle, // lpTargetHandle
|
||||
0, // dwDesiredAccess
|
||||
true, // bInheritHandle
|
||||
windows.DUPLICATE_SAME_ACCESS, // dwOptions
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return syscall.EINVAL
|
||||
}
|
||||
return nil
|
||||
return uintptr(newfdHandle), nil
|
||||
}
|
||||
|
||||
// redirectStderr to the file passed in
|
||||
func redirectStderr(f *os.File) {
|
||||
err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
|
||||
termFd, err := dup(os.Stderr.Fd())
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to duplicate stderr: %v", err)
|
||||
}
|
||||
terminal.RawOut = os.NewFile(termFd, "termOut")
|
||||
err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(f.Fd()))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to redirect stderr to file: %v", err)
|
||||
}
|
||||
os.Stderr = f
|
||||
}
|
||||
|
@ -81,8 +81,11 @@ func Start() {
|
||||
// If output is not a tty then remove escape codes
|
||||
Out = colorable.NewNonColorable(f)
|
||||
} else if runtime.GOOS == "windows" && os.Getenv("TERM") != "" {
|
||||
// If TERM is set just use stdout
|
||||
Out = os.Stdout
|
||||
// If TERM is set on Windows then we should just send output
|
||||
// straight to the terminal for cygwin/git bash environments.
|
||||
// We don't want to use NewColorable here because it will
|
||||
// use Windows console calls which cygwin/git bash don't support.
|
||||
Out = f
|
||||
} else {
|
||||
Out = colorable.NewColorable(f)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user