return strings.TrimSpace(string(out))
 }
 
+func compilemain(t *testing.T, libgo string) {
+       ccArgs := append(cc, "-o", "testp"+exeSuffix)
+       if GOOS == "windows" {
+               ccArgs = append(ccArgs, "main_windows.c")
+       } else {
+               ccArgs = append(ccArgs, "main_unix.c")
+       }
+       ccArgs = append(ccArgs, "main.c", libgo)
+       t.Log(ccArgs)
+
+       if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
+               t.Logf("%s", out)
+               t.Fatal(err)
+       }
+}
+
 func TestInstall(t *testing.T) {
        defer func() {
                os.Remove("libgo.a")
                t.Fatal(err)
        }
 
-       ccArgs := append(cc, "-o", "testp"+exeSuffix, "main.c", filepath.Join("pkg", GOOS+"_"+GOARCH, "libgo.a"))
-       if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
-               t.Logf("%s", out)
-               t.Fatal(err)
-       }
+       compilemain(t, filepath.Join("pkg", GOOS+"_"+GOARCH, "libgo.a"))
 
        binArgs := append(bin, "arg1", "arg2")
        if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
                t.Fatal(err)
        }
 
-       ccArgs = append(cc, "-o", "testp"+exeSuffix, "main.c", "libgo.a")
-       if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
-               t.Logf("%s", out)
-               t.Fatal(err)
-       }
+       compilemain(t, "libgo.a")
 
        if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
                t.Logf("%s", out)
                t.Fatal(err)
        }
 
-       if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
-               t.Logf("%s", out)
-               t.Fatal(err)
-       }
+       compilemain(t, "libgo.a")
 
        if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
                t.Logf("%s", out)
 
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-#include <signal.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include "p.h"
 #include "libgo.h"
 
-static void (*oldHandler)(int, siginfo_t*, void*);
-
-static void handler(int signo, siginfo_t* info, void* ctxt) {
-       if (oldHandler) {
-               oldHandler(signo, info, ctxt);
-       }
-}
+extern int install_handler();
+extern int check_handler();
 
 int main(void) {
-       struct sigaction sa;
-       struct sigaction osa;
        int32_t res;
 
-       // Install our own signal handler.
-       memset(&sa, 0, sizeof sa);
-       sa.sa_sigaction = handler;
-       sigemptyset(&sa.sa_mask);
-       sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
-       memset(&osa, 0, sizeof osa);
-       sigemptyset(&osa.sa_mask);
-       if (sigaction(SIGSEGV, &sa, &osa) < 0) {
-               perror("sigaction");
-               return 2;
+       int r1 = install_handler();
+       if (r1!=0) {
+               return r1;
        }
-       if (osa.sa_handler == SIG_DFL || (osa.sa_flags&SA_ONSTACK) == 0) {
-               fprintf(stderr, "Go runtime did not install signal handler\n");
-               return 2;
-       }
-       oldHandler = osa.sa_sigaction;
 
        if (!DidInitRun()) {
                fprintf(stderr, "ERROR: buildmode=c-archive init should run\n");
                return 2;
        }
 
-       // Make sure our signal handler is still the one in use.
-       if (sigaction(SIGSEGV, NULL, &sa) < 0) {
-               perror("sigaction check");
-               return 2;
-       }
-       if (sa.sa_sigaction != handler) {
-               fprintf(stderr, "ERROR: wrong signal handler: %p != %p\n", sa.sa_sigaction, handler);
-               return 2;
+       int r2 = check_handler();
+       if (r2!=0) {
+               return r2;
        }
 
        res = FromPkg();
 
--- /dev/null
+// Copyright 2015 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 <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+struct sigaction sa;
+struct sigaction osa;
+
+static void (*oldHandler)(int, siginfo_t*, void*);
+
+static void handler(int signo, siginfo_t* info, void* ctxt) {
+       if (oldHandler) {
+               oldHandler(signo, info, ctxt);
+       }
+}
+
+int install_handler() {
+       // Install our own signal handler.
+       memset(&sa, 0, sizeof sa);
+       sa.sa_sigaction = handler;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
+       memset(&osa, 0, sizeof osa);
+       sigemptyset(&osa.sa_mask);
+       if (sigaction(SIGSEGV, &sa, &osa) < 0) {
+               perror("sigaction");
+               return 2;
+       }
+       if (osa.sa_handler == SIG_DFL || (osa.sa_flags&SA_ONSTACK) == 0) {
+               fprintf(stderr, "Go runtime did not install signal handler\n");
+               return 2;
+       }
+       oldHandler = osa.sa_sigaction;
+
+       return 0;
+}
+
+int check_handler() {
+       if (sigaction(SIGSEGV, NULL, &sa) < 0) {
+               perror("sigaction check");
+               return 2;
+       }
+       if (sa.sa_sigaction != handler) {
+               fprintf(stderr, "ERROR: wrong signal handler: %p != %p\n", sa.sa_sigaction, handler);
+               return 2;
+       }
+       return 0;
+}
+
 
--- /dev/null
+// Copyright 2015 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.
+
+/*
+ * Dummy implementations for Windows, because Windows doesn't
+ * support Unix-style signal handling.
+ */
+
+int install_handler() {
+       return 0;
+}
+
+
+int check_handler() {
+       return 0;
+}