github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/lib9/run_windows.c (about) 1 // Copyright 2013 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 #include <u.h> 6 #include <windows.h> 7 #define NOPLAN9DEFINES 8 #include <libc.h> 9 #include "win.h" 10 11 int 12 runcmd(char **argv) 13 { 14 // Mostly copied from ../cmd/dist/windows.c. 15 // If there's a bug here, fix the logic there too. 16 int i, j, nslash; 17 Fmt fmt; 18 char *q; 19 WinRune *r; 20 STARTUPINFOW si; 21 PROCESS_INFORMATION pi; 22 DWORD code; 23 24 fmtstrinit(&fmt); 25 for(i=0; argv[i]; i++) { 26 if(i > 0) 27 fmtprint(&fmt, " "); 28 q = argv[i]; 29 if(strstr(q, " ") || strstr(q, "\t") || strstr(q, "\"") || strstr(q, "\\\\") || (strlen(q) > 0 && q[strlen(q)-1] == '\\')) { 30 fmtprint(&fmt, "\""); 31 nslash = 0; 32 for(; *q; q++) { 33 if(*q == '\\') { 34 nslash++; 35 continue; 36 } 37 if(*q == '"') { 38 for(j=0; j<2*nslash+1; j++) 39 fmtprint(&fmt, "\\"); 40 nslash = 0; 41 } 42 for(j=0; j<nslash; j++) 43 fmtprint(&fmt, "\\"); 44 nslash = 0; 45 fmtprint(&fmt, "\""); 46 } 47 for(j=0; j<2*nslash; j++) 48 fmtprint(&fmt, "\\"); 49 fmtprint(&fmt, "\""); 50 } else { 51 fmtprint(&fmt, "%s", q); 52 } 53 } 54 55 q = fmtstrflush(&fmt); 56 r = torune(q); 57 free(q); 58 59 memset(&si, 0, sizeof si); 60 si.cb = sizeof si; 61 si.dwFlags = STARTF_USESTDHANDLES; 62 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 63 si.hStdError = GetStdHandle(STD_ERROR_HANDLE); 64 65 if(!CreateProcessW(nil, r, nil, nil, TRUE, 0, nil, nil, &si, &pi)) { 66 free(r); 67 return -1; 68 } 69 70 free(r); 71 if(WaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE) != 0) 72 return -1; 73 i = GetExitCodeProcess(pi.hProcess, &code); 74 CloseHandle(pi.hProcess); 75 CloseHandle(pi.hThread); 76 if(!i) 77 return -1; 78 if(code != 0) { 79 werrstr("unsuccessful exit status: %d", (int)code); 80 return -1; 81 } 82 return 0; 83 }