diff options
Diffstat (limited to 'src/cmd/dist/windows.c')
-rw-r--r-- | src/cmd/dist/windows.c | 103 |
1 files changed, 97 insertions, 6 deletions
diff --git a/src/cmd/dist/windows.c b/src/cmd/dist/windows.c index 557e4b003..7bcda4508 100644 --- a/src/cmd/dist/windows.c +++ b/src/cmd/dist/windows.c @@ -115,7 +115,7 @@ errstr(void) binit(&b); code = GetLastError(); r = nil; - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, nil, code, 0, (Rune*)&r, 0, nil); toutf(&b, r); return bstr(&b); // leak but we're dying anyway @@ -285,9 +285,11 @@ genrun(Buf *b, char *dir, int mode, Vec *argv, int wait) binit(&cmd); for(i=0; i<argv->len; i++) { + q = argv->p[i]; + if(i == 0 && streq(q, "hg")) + bwritestr(&cmd, "cmd.exe /c "); if(i > 0) bwritestr(&cmd, " "); - q = argv->p[i]; if(contains(q, " ") || contains(q, "\t") || contains(q, "\"") || contains(q, "\\\\") || hassuffix(q, "\\")) { bwritestr(&cmd, "\""); nslash = 0; @@ -314,7 +316,7 @@ genrun(Buf *b, char *dir, int mode, Vec *argv, int wait) } } if(vflag > 1) - xprintf("%s\n", bstr(&cmd)); + errprintf("%s\n", bstr(&cmd)); torune(&rcmd, bstr(&cmd)); rexe = nil; @@ -528,8 +530,9 @@ readfile(Buf *b, char *file) HANDLE h; Rune *r; + breset(b); if(vflag > 2) - xprintf("read %s\n", file); + errprintf("read %s\n", file); torune(&r, file); h = CreateFileW(r, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if(h == INVALID_HANDLE_VALUE) @@ -548,7 +551,7 @@ writefile(Buf *b, char *file, int exec) USED(exec); if(vflag > 2) - xprintf("write %s\n", file); + errprintf("write %s\n", file); torune(&r, file); h = CreateFileW(r, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0); if(h == INVALID_HANDLE_VALUE) @@ -707,7 +710,7 @@ fatal(char *msg, ...) vsnprintf(buf1, sizeof buf1, msg, arg); va_end(arg); - xprintf("go tool dist: %s\n", buf1); + errprintf("go tool dist: %s\n", buf1); bgwait(); ExitProcess(1); @@ -848,6 +851,23 @@ xprintf(char *fmt, ...) xfree(p); } +void +errprintf(char *fmt, ...) +{ + va_list arg; + char *p; + DWORD n, w; + + va_start(arg, fmt); + n = vsnprintf(NULL, 0, fmt, arg); + p = xmalloc(n+1); + vsnprintf(p, n+1, fmt, arg); + va_end(arg); + w = 0; + WriteFile(GetStdHandle(STD_ERROR_HANDLE), p, n, &w, 0); + xfree(p); +} + int main(int argc, char **argv) { @@ -907,4 +927,75 @@ xstrrchr(char *p, int c) return nil; } +// xsamefile returns whether f1 and f2 are the same file (or dir) +int +xsamefile(char *f1, char *f2) +{ + Rune *ru; + HANDLE fd1, fd2; + BY_HANDLE_FILE_INFORMATION fi1, fi2; + int r; + + // trivial case + if(streq(f1, f2)) + return 1; + + torune(&ru, f1); + // refer to ../../pkg/os/stat_windows.go:/sameFile + fd1 = CreateFileW(ru, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + xfree(ru); + if(fd1 == INVALID_HANDLE_VALUE) + return 0; + torune(&ru, f2); + fd2 = CreateFileW(ru, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + xfree(ru); + if(fd2 == INVALID_HANDLE_VALUE) { + CloseHandle(fd1); + return 0; + } + r = GetFileInformationByHandle(fd1, &fi1) != 0 && GetFileInformationByHandle(fd2, &fi2) != 0; + CloseHandle(fd2); + CloseHandle(fd1); + if(r != 0 && + fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber && + fi1.nFileIndexHigh == fi2.nFileIndexHigh && + fi1.nFileIndexLow == fi2.nFileIndexLow) + return 1; + return 0; +} + +// xtryexecfunc tries to execute function f, if any illegal instruction +// signal received in the course of executing that function, it will +// return 0, otherwise it will return 1. +int +xtryexecfunc(void (*f)(void)) +{ + return 0; // suffice for now +} + +static void +cpuid(int dst[4], int ax) +{ + // NOTE: This asm statement is for mingw. + // If we ever support MSVC, use __cpuid(dst, ax) + // to use the built-in. +#if defined(__i386__) || defined(__x86_64__) + asm volatile("cpuid" + : "=a" (dst[0]), "=b" (dst[1]), "=c" (dst[2]), "=d" (dst[3]) + : "0" (ax)); +#else + dst[0] = dst[1] = dst[2] = dst[3] = 0; +#endif +} + +bool +cansse2(void) +{ + int info[4]; + + cpuid(info, 1); + return (info[3] & (1<<26)) != 0; // SSE2 +} + + #endif // __WINDOWS__ |