mirror of
https://github.com/golang/go
synced 2024-11-21 22:24:40 -07:00
misc/cgo/test: make tests run on windows
- use proper Win64 gcc calling convention when calling initcgo on amd64 - increase g0 stack size to 64K on amd64 to make it the same as 386 - implement C.sleep - do not use C.stat, since it is renamed to C._stat by mingw - use fopen to implement TestErrno, since C.strtol always succeeds on windows - skip TestSetEnv on windows, because os.Setenv sets windows process environment, while C.getenv inspects internal C runtime variable instead R=golang-dev, vcc.163, rsc CC=golang-dev https://golang.org/cl/5500094
This commit is contained in:
parent
7fc4c07172
commit
8d6958fc04
@ -25,4 +25,21 @@ CGO_OFILES=\
|
|||||||
OFILES=\
|
OFILES=\
|
||||||
runtime.$O\
|
runtime.$O\
|
||||||
|
|
||||||
|
ifeq ($(GOOS),windows)
|
||||||
|
GCCVERSION=$(shell gcc -dumpversion)
|
||||||
|
ifeq ($(GOARCH),386)
|
||||||
|
GCCLIBDIR=/mingw/lib/gcc/mingw32/$(GCCVERSION)
|
||||||
|
CHKSTK=_chkstk.o
|
||||||
|
else
|
||||||
|
GCCLIBDIR=/mingw/lib/gcc/x86_64-w64-mingw32/$(GCCVERSION)
|
||||||
|
CHKSTK=_chkstk_ms.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
CGOFILES+=sleep_windows.go
|
||||||
|
CGO_OFILES+=$(CHKSTK)
|
||||||
|
|
||||||
|
$(CHKSTK):
|
||||||
|
ar -x "$(GCCLIBDIR)/libgcc.a" $@
|
||||||
|
endif
|
||||||
|
|
||||||
include ../../../src/Make.pkg
|
include ../../../src/Make.pkg
|
||||||
|
@ -69,17 +69,6 @@ func uuidgen() {
|
|||||||
C.uuid_generate(&uuid[0])
|
C.uuid_generate(&uuid[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func Size(name string) (int64, error) {
|
|
||||||
var st C.struct_stat
|
|
||||||
p := C.CString(name)
|
|
||||||
_, err := C.stat(p, &st)
|
|
||||||
C.free(unsafe.Pointer(p))
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return int64(C.ulong(st.st_size)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Strtol(s string, base int) (int, error) {
|
func Strtol(s string, base int) (int, error) {
|
||||||
p := C.CString(s)
|
p := C.CString(s)
|
||||||
n, err := C.strtol(p, nil, C.int(base))
|
n, err := C.strtol(p, nil, C.int(base))
|
||||||
@ -112,9 +101,17 @@ func testAtol(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testErrno(t *testing.T) {
|
func testErrno(t *testing.T) {
|
||||||
n, err := Strtol("asdf", 123)
|
p := C.CString("no-such-file")
|
||||||
if n != 0 || err != os.EINVAL {
|
m := C.CString("r")
|
||||||
t.Error("Strtol: ", n, err)
|
f, err := C.fopen(p, m)
|
||||||
|
C.free(unsafe.Pointer(p))
|
||||||
|
C.free(unsafe.Pointer(m))
|
||||||
|
if err == nil {
|
||||||
|
C.fclose(f)
|
||||||
|
t.Fatalf("C.fopen: should fail")
|
||||||
|
}
|
||||||
|
if err != os.ENOENT {
|
||||||
|
t.Fatalf("C.fopen: unexpected error: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,12 +10,21 @@ package cgotest
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is really an os package test but here for convenience.
|
// This is really an os package test but here for convenience.
|
||||||
func testSetEnv(t *testing.T) {
|
func testSetEnv(t *testing.T) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
// Go uses SetEnvironmentVariable on windows. Howerver,
|
||||||
|
// C runtime takes a *copy* at process startup of thei
|
||||||
|
// OS environment, and stores it in environ/envp.
|
||||||
|
// It is this copy that getenv/putenv manipulate.
|
||||||
|
t.Logf("skipping test")
|
||||||
|
return
|
||||||
|
}
|
||||||
const key = "CGO_OS_TEST_KEY"
|
const key = "CGO_OS_TEST_KEY"
|
||||||
const val = "CGO_OS_TEST_VALUE"
|
const val = "CGO_OS_TEST_VALUE"
|
||||||
os.Setenv(key, val)
|
os.Setenv(key, val)
|
||||||
|
@ -7,6 +7,8 @@ package cgotest
|
|||||||
/*
|
/*
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
unsigned int sleep(unsigned int seconds);
|
||||||
|
|
||||||
extern void BackgroundSleep(int);
|
extern void BackgroundSleep(int);
|
||||||
void twoSleep(int n) {
|
void twoSleep(int n) {
|
||||||
BackgroundSleep(n);
|
BackgroundSleep(n);
|
||||||
|
16
misc/cgo/test/sleep_windows.go
Normal file
16
misc/cgo/test/sleep_windows.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2011 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.
|
||||||
|
|
||||||
|
package cgotest
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
unsigned int sleep(unsigned int seconds) {
|
||||||
|
Sleep(1000 * seconds);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
@ -16,7 +16,7 @@ TEXT _rt0_amd64(SB),7,$-8
|
|||||||
// create istack out of the given (operating system) stack.
|
// create istack out of the given (operating system) stack.
|
||||||
// initcgo may update stackguard.
|
// initcgo may update stackguard.
|
||||||
MOVQ $runtime·g0(SB), DI
|
MOVQ $runtime·g0(SB), DI
|
||||||
LEAQ (-8192+104)(SP), BX
|
LEAQ (-64*1024+104)(SP), BX
|
||||||
MOVQ BX, g_stackguard(DI)
|
MOVQ BX, g_stackguard(DI)
|
||||||
MOVQ SP, g_stackbase(DI)
|
MOVQ SP, g_stackbase(DI)
|
||||||
|
|
||||||
@ -24,7 +24,9 @@ TEXT _rt0_amd64(SB),7,$-8
|
|||||||
MOVQ initcgo(SB), AX
|
MOVQ initcgo(SB), AX
|
||||||
TESTQ AX, AX
|
TESTQ AX, AX
|
||||||
JZ needtls
|
JZ needtls
|
||||||
CALL AX // g0 already in DI
|
// g0 already in DI
|
||||||
|
MOVQ DI, CX // Win64 uses CX for first parameter
|
||||||
|
CALL AX
|
||||||
CMPL runtime·iswindows(SB), $0
|
CMPL runtime·iswindows(SB), $0
|
||||||
JEQ ok
|
JEQ ok
|
||||||
|
|
||||||
|
@ -97,7 +97,6 @@ gomake clean
|
|||||||
) || exit $?
|
) || exit $?
|
||||||
|
|
||||||
[ "$CGO_ENABLED" != 1 ] ||
|
[ "$CGO_ENABLED" != 1 ] ||
|
||||||
[ "$GOHOSTOS" == windows ] ||
|
|
||||||
(xcd ../misc/cgo/test
|
(xcd ../misc/cgo/test
|
||||||
gomake clean
|
gomake clean
|
||||||
gotest
|
gotest
|
||||||
|
Loading…
Reference in New Issue
Block a user