]> Cypherpunks repositories - gostls13.git/commitdiff
misc/cgo/testcshared: add c-shared test with no exports
authorIan Lance Taylor <iant@golang.org>
Tue, 21 Apr 2015 17:46:29 +0000 (10:46 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 21 Apr 2015 20:50:23 +0000 (20:50 +0000)
The purpose of this test is to make sure that -buildmode=c-shared
works even when the shared library can be built without invoking cgo.

Change-Id: Id6f95af755992b209aff770440ca9819b74113ab
Reviewed-on: https://go-review.googlesource.com/9166
Reviewed-by: David Crawshaw <crawshaw@golang.org>
misc/cgo/testcshared/main2.c [new file with mode: 0644]
misc/cgo/testcshared/src/libgo2/libgo2.go [new file with mode: 0644]
misc/cgo/testcshared/test.bash

diff --git a/misc/cgo/testcshared/main2.c b/misc/cgo/testcshared/main2.c
new file mode 100644 (file)
index 0000000..24bc62e
--- /dev/null
@@ -0,0 +1,56 @@
+// 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define fd (10)
+
+// Tests libgo2.so, which does not export any functions.
+// Read a string from the file descriptor and print it.
+int main(void) {
+  int i;
+  ssize_t n;
+  char buf[20];
+  struct timespec ts;
+
+  // The descriptor will be initialized in a thread, so we have to
+  // give a chance to get opened.
+  for (i = 0; i < 10; i++) {
+    n = read(fd, buf, sizeof buf);
+    if (n >= 0)
+      break;
+    if (errno != EBADF) {
+      fprintf(stderr, "BUG: read: %s\n", strerror(errno));
+      return 2;
+    }
+
+    // An EBADF error means that the shared library has not opened the
+    // descriptor yet.
+    ts.tv_sec = 0;
+    ts.tv_nsec = 1000000;
+    nanosleep(&ts, NULL);
+  }
+
+  if (n < 0) {
+    fprintf(stderr, "BUG: failed to read any data from pipe\n");
+    return 2;
+  }
+
+  if (n == 0) {
+    fprintf(stderr, "BUG: unexpected EOF\n");
+    return 2;
+  }
+
+  if (n == sizeof buf) {
+    n--;
+  }
+  buf[n] = '\0';
+  printf("%s\n", buf);
+  return 0;
+}
diff --git a/misc/cgo/testcshared/src/libgo2/libgo2.go b/misc/cgo/testcshared/src/libgo2/libgo2.go
new file mode 100644 (file)
index 0000000..6096860
--- /dev/null
@@ -0,0 +1,52 @@
+// 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.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package main
+
+// Test a shared library created by -buildmode=c-shared that does not
+// export anything.
+
+import (
+       "fmt"
+       "os"
+       "syscall"
+)
+
+// To test this we want to communicate between the main program and
+// the shared library without using any exported symbols.  The init
+// function creates a pipe and Dups the read end to a known number
+// that the C code can also use.
+
+const (
+       fd = 10
+)
+
+func init() {
+       var p [2]int
+       if e := syscall.Pipe(p[0:]); e != nil {
+               fmt.Fprintf(os.Stderr, "pipe: %v\n", e)
+               os.Exit(2)
+       }
+
+       if e := syscall.Dup2(p[0], fd); e != nil {
+               fmt.Fprintf(os.Stderr, "dup2: %v\n", e)
+               os.Exit(2)
+       }
+
+       const str = "PASS"
+       if n, e := syscall.Write(p[1], []byte(str)); e != nil || n != len(str) {
+               fmt.Fprintf(os.Stderr, "write: %d %v\n", n, e)
+               os.Exit(2)
+       }
+
+       if e := syscall.Close(p[1]); e != nil {
+               fmt.Fprintf(os.Stderr, "close: %v\n", e)
+               os.Exit(2)
+       }
+}
+
+func main() {
+}
index 61f80ea9a2260245dd0fc510185803a78b2769bb..1c2e3c23f23d47529760a29d94d426abdc8f6cec 100755 (executable)
@@ -6,7 +6,7 @@
 set -e
 
 function cleanup() {
-       rm libgo.so testp
+       rm -f libgo.so libgo2.so testp testp2
 }
 trap cleanup EXIT
 
@@ -27,3 +27,13 @@ if [ "$output" != "PASS" ]; then
        echo "FAIL: got $output"
        exit 1
 fi
+
+GOPATH=$(pwd) go build -buildmode=c-shared -o libgo2.so src/libgo2/libgo2.go
+
+$(go env CC) $(go env GOGCCFLAGS) -o testp2 main2.c -Wl,--no-as-needed libgo2.so
+output=$(LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./testp2)
+# testp2 prints PASS at the end of its execution.
+if [ "$output" != "PASS" ]; then
+       echo "FAIL: got $output"
+       exit 1
+fi