98 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			98 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								// Copyright 2009 The Go Authors. All rights reserved.
							 | 
						||
| 
								 | 
							
								// Use of this source code is governed by a BSD-style
							 | 
						||
| 
								 | 
							
								// license that can be found in the LICENSE file.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Fork, exec, wait, etc.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								package windows
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// EscapeArg rewrites command line argument s as prescribed
							 | 
						||
| 
								 | 
							
								// in http://msdn.microsoft.com/en-us/library/ms880421.
							 | 
						||
| 
								 | 
							
								// This function returns "" (2 double quotes) if s is empty.
							 | 
						||
| 
								 | 
							
								// Alternatively, these transformations are done:
							 | 
						||
| 
								 | 
							
								// - every back slash (\) is doubled, but only if immediately
							 | 
						||
| 
								 | 
							
								//   followed by double quote (");
							 | 
						||
| 
								 | 
							
								// - every double quote (") is escaped by back slash (\);
							 | 
						||
| 
								 | 
							
								// - finally, s is wrapped with double quotes (arg -> "arg"),
							 | 
						||
| 
								 | 
							
								//   but only if there is space or tab inside s.
							 | 
						||
| 
								 | 
							
								func EscapeArg(s string) string {
							 | 
						||
| 
								 | 
							
									if len(s) == 0 {
							 | 
						||
| 
								 | 
							
										return "\"\""
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									n := len(s)
							 | 
						||
| 
								 | 
							
									hasSpace := false
							 | 
						||
| 
								 | 
							
									for i := 0; i < len(s); i++ {
							 | 
						||
| 
								 | 
							
										switch s[i] {
							 | 
						||
| 
								 | 
							
										case '"', '\\':
							 | 
						||
| 
								 | 
							
											n++
							 | 
						||
| 
								 | 
							
										case ' ', '\t':
							 | 
						||
| 
								 | 
							
											hasSpace = true
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if hasSpace {
							 | 
						||
| 
								 | 
							
										n += 2
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if n == len(s) {
							 | 
						||
| 
								 | 
							
										return s
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									qs := make([]byte, n)
							 | 
						||
| 
								 | 
							
									j := 0
							 | 
						||
| 
								 | 
							
									if hasSpace {
							 | 
						||
| 
								 | 
							
										qs[j] = '"'
							 | 
						||
| 
								 | 
							
										j++
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									slashes := 0
							 | 
						||
| 
								 | 
							
									for i := 0; i < len(s); i++ {
							 | 
						||
| 
								 | 
							
										switch s[i] {
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											slashes = 0
							 | 
						||
| 
								 | 
							
											qs[j] = s[i]
							 | 
						||
| 
								 | 
							
										case '\\':
							 | 
						||
| 
								 | 
							
											slashes++
							 | 
						||
| 
								 | 
							
											qs[j] = s[i]
							 | 
						||
| 
								 | 
							
										case '"':
							 | 
						||
| 
								 | 
							
											for ; slashes > 0; slashes-- {
							 | 
						||
| 
								 | 
							
												qs[j] = '\\'
							 | 
						||
| 
								 | 
							
												j++
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											qs[j] = '\\'
							 | 
						||
| 
								 | 
							
											j++
							 | 
						||
| 
								 | 
							
											qs[j] = s[i]
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										j++
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if hasSpace {
							 | 
						||
| 
								 | 
							
										for ; slashes > 0; slashes-- {
							 | 
						||
| 
								 | 
							
											qs[j] = '\\'
							 | 
						||
| 
								 | 
							
											j++
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										qs[j] = '"'
							 | 
						||
| 
								 | 
							
										j++
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return string(qs[:j])
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func CloseOnExec(fd Handle) {
							 | 
						||
| 
								 | 
							
									SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// FullPath retrieves the full path of the specified file.
							 | 
						||
| 
								 | 
							
								func FullPath(name string) (path string, err error) {
							 | 
						||
| 
								 | 
							
									p, err := UTF16PtrFromString(name)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return "", err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									n := uint32(100)
							 | 
						||
| 
								 | 
							
									for {
							 | 
						||
| 
								 | 
							
										buf := make([]uint16, n)
							 | 
						||
| 
								 | 
							
										n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											return "", err
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if n <= uint32(len(buf)) {
							 | 
						||
| 
								 | 
							
											return UTF16ToString(buf[:n]), nil
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |