Fix unit tests
[govpp.git] / vendor / github.com / sirupsen / logrus / terminal_windows.go
1 // Based on ssh/terminal:
2 // Copyright 2011 The Go Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
5
6 // +build windows,!appengine
7
8 package logrus
9
10 import (
11         "bytes"
12         "errors"
13         "io"
14         "os"
15         "os/exec"
16         "strconv"
17         "strings"
18         "syscall"
19         "unsafe"
20 )
21
22 var kernel32 = syscall.NewLazyDLL("kernel32.dll")
23
24 var (
25         procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
26         procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
27 )
28
29 const (
30         enableProcessedOutput           = 0x0001
31         enableWrapAtEolOutput           = 0x0002
32         enableVirtualTerminalProcessing = 0x0004
33 )
34
35 func getVersion() (float64, error) {
36         stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
37         cmd := exec.Command("cmd", "ver")
38         cmd.Stdout = stdout
39         cmd.Stderr = stderr
40         err := cmd.Run()
41         if err != nil {
42                 return -1, err
43         }
44         
45         // The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
46         version := strings.Replace(stdout.String(), "\n", "", -1)
47         version = strings.Replace(version, "\r\n", "", -1)
48
49         x1 := strings.Index(version, "[Version")
50
51         if x1 == -1 || strings.Index(version, "]") == -1 {
52                 return -1, errors.New("Can't determine Windows version")
53         }
54
55         return strconv.ParseFloat(version[x1+9:x1+13], 64)
56 }
57
58 func init() {
59         ver, err := getVersion()
60         if err != nil {
61                 return
62         }
63
64         // Activate Virtual Processing for Windows CMD
65         // Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
66         if ver >= 10 {
67                 handle := syscall.Handle(os.Stderr.Fd())
68                 procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
69         }
70 }
71
72 // IsTerminal returns true if stderr's file descriptor is a terminal.
73 func IsTerminal(f io.Writer) bool {
74         switch v := f.(type) {
75         case *os.File:
76                 var st uint32
77                 r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
78                 return r != 0 && e == 0
79         default:
80                 return false
81         }
82 }