exec_windows.go (1949B)
1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Fork, exec, wait, etc. 6 7 package windows 8 9 // EscapeArg rewrites command line argument s as prescribed 10 // in http://msdn.microsoft.com/en-us/library/ms880421. 11 // This function returns "" (2 double quotes) if s is empty. 12 // Alternatively, these transformations are done: 13 // - every back slash (\) is doubled, but only if immediately 14 // followed by double quote ("); 15 // - every double quote (") is escaped by back slash (\); 16 // - finally, s is wrapped with double quotes (arg -> "arg"), 17 // but only if there is space or tab inside s. 18 func EscapeArg(s string) string { 19 if len(s) == 0 { 20 return "\"\"" 21 } 22 n := len(s) 23 hasSpace := false 24 for i := 0; i < len(s); i++ { 25 switch s[i] { 26 case '"', '\\': 27 n++ 28 case ' ', '\t': 29 hasSpace = true 30 } 31 } 32 if hasSpace { 33 n += 2 34 } 35 if n == len(s) { 36 return s 37 } 38 39 qs := make([]byte, n) 40 j := 0 41 if hasSpace { 42 qs[j] = '"' 43 j++ 44 } 45 slashes := 0 46 for i := 0; i < len(s); i++ { 47 switch s[i] { 48 default: 49 slashes = 0 50 qs[j] = s[i] 51 case '\\': 52 slashes++ 53 qs[j] = s[i] 54 case '"': 55 for ; slashes > 0; slashes-- { 56 qs[j] = '\\' 57 j++ 58 } 59 qs[j] = '\\' 60 j++ 61 qs[j] = s[i] 62 } 63 j++ 64 } 65 if hasSpace { 66 for ; slashes > 0; slashes-- { 67 qs[j] = '\\' 68 j++ 69 } 70 qs[j] = '"' 71 j++ 72 } 73 return string(qs[:j]) 74 } 75 76 func CloseOnExec(fd Handle) { 77 SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0) 78 } 79 80 // FullPath retrieves the full path of the specified file. 81 func FullPath(name string) (path string, err error) { 82 p, err := UTF16PtrFromString(name) 83 if err != nil { 84 return "", err 85 } 86 n := uint32(100) 87 for { 88 buf := make([]uint16, n) 89 n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil) 90 if err != nil { 91 return "", err 92 } 93 if n <= uint32(len(buf)) { 94 return UTF16ToString(buf[:n]), nil 95 } 96 } 97 }