root/src/lib9/run_windows.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. runcmd

// Copyright 2013 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.

#include <u.h>
#include <windows.h>
#define NOPLAN9DEFINES
#include <libc.h>
#include "win.h"

int
runcmd(char **argv)
{
        // Mostly copied from ../cmd/dist/windows.c.
        // If there's a bug here, fix the logic there too.
        int i, j, nslash;
        Fmt fmt;
        char *q;
        WinRune *r;
        STARTUPINFOW si;
        PROCESS_INFORMATION pi;
        DWORD code;

        fmtstrinit(&fmt);
        for(i=0; argv[i]; i++) {
                if(i > 0)
                        fmtprint(&fmt, " ");
                q = argv[i];
                if(strstr(q, " ") || strstr(q, "\t") || strstr(q, "\"") || strstr(q, "\\\\") || (strlen(q) > 0 && q[strlen(q)-1] == '\\')) {
                        fmtprint(&fmt, "\"");
                        nslash = 0;
                        for(; *q; q++) {
                                if(*q == '\\') {
                                        nslash++;
                                        continue;
                                }
                                if(*q == '"') {
                                        for(j=0; j<2*nslash+1; j++)
                                                fmtprint(&fmt, "\\");
                                        nslash = 0;
                                }
                                for(j=0; j<nslash; j++)
                                        fmtprint(&fmt, "\\");
                                nslash = 0;
                                fmtprint(&fmt, "\"");
                        }
                        for(j=0; j<2*nslash; j++)
                                fmtprint(&fmt, "\\");
                        fmtprint(&fmt, "\"");
                } else {
                        fmtprint(&fmt, "%s", q);
                }
        }
        
        q = fmtstrflush(&fmt);
        r = torune(q);
        free(q);

        memset(&si, 0, sizeof si);
        si.cb = sizeof si;
        si.dwFlags = STARTF_USESTDHANDLES;
        si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

        if(!CreateProcessW(nil, r, nil, nil, TRUE, 0, nil, nil, &si, &pi)) {
                free(r);
                return -1;
        }

        free(r);
        if(WaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE) != 0)
                return -1;
        i = GetExitCodeProcess(pi.hProcess, &code);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        if(!i)
                return -1;
        if(code != 0) {
                werrstr("unsuccessful exit status: %d", (int)code);
                return -1;
        }
        return 0;
}

/* [<][>][^][v][top][bottom][index][help] */