From ea31c98daba7d3459dc5500049876fe0a71a89d3 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 21 Jan 2019 23:05:52 +0000 Subject: [PATCH] libgo: fix building, and some testing, on Solaris Restore some of the fixes that were applied to golang_org/x/net/lif but were lost when 1.12 moved the directory to internal/x/net/lif. Add support for reading /proc to fetch argc/argv/env for c-archive mode. Reviewed-on: https://go-review.googlesource.com/c/158640 From-SVN: r268130 --- gcc/go/gofrontend/MERGE | 2 +- libgo/Makefile.am | 2 +- libgo/Makefile.in | 2 +- libgo/go/internal/x/net/lif/syscall.go | 14 +- ...{zsys_solaris_amd64.go => zsys_solaris.go} | 8 +- libgo/go/runtime/signal_unix.go | 5 +- libgo/runtime/go-libmain.c | 122 ++++++++++++++++++ 7 files changed, 136 insertions(+), 19 deletions(-) rename libgo/go/internal/x/net/lif/{zsys_solaris_amd64.go => zsys_solaris.go} (95%) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index c5b51b79a95..8f423293d94 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -e7427654f3af83e1feea727a62a97172d7721403 +0c870ba6b3b43e0e56231f40c56b58dad0e36d9e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 2ee4a28a53c..b9ff88c2452 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -1082,7 +1082,7 @@ $(eval $(call PACKAGE_template,internal/x/net/lif)) internal_x_net_lif_lo = \ internal/x/net/lif.lo internal_x_net_lif_check = \ - internal_org/x/net/lif/check + internal/x/net/lif/check endif diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 1695dd0faec..abda06437f7 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -1131,7 +1131,7 @@ extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a @LIBGO_IS_SOLARIS_TRUE@ internal/x/net/lif.lo @LIBGO_IS_SOLARIS_TRUE@internal_x_net_lif_check = \ -@LIBGO_IS_SOLARIS_TRUE@ internal_org/x/net/lif/check +@LIBGO_IS_SOLARIS_TRUE@ internal/x/net/lif/check TPACKAGES = $(shell cat $(srcdir)/check-packages.txt) TEST_PACKAGES = $(addsuffix /check,$(TPACKAGES)) \ diff --git a/libgo/go/internal/x/net/lif/syscall.go b/libgo/go/internal/x/net/lif/syscall.go index aadab2e14ba..ea7541456bd 100644 --- a/libgo/go/internal/x/net/lif/syscall.go +++ b/libgo/go/internal/x/net/lif/syscall.go @@ -11,18 +11,12 @@ import ( "unsafe" ) -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - -//go:linkname procIoctl libc_ioctl - -var procIoctl uintptr - -func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno) +//extern __go_ioctl_ptr +func libc_ioctl(int32, int32, unsafe.Pointer) int32 func ioctl(s, ioc uintptr, arg unsafe.Pointer) error { - _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procIoctl)), 3, s, ioc, uintptr(arg), 0, 0, 0) - if errno != 0 { - return error(errno) + if libc_ioctl(int32(s), int32(ioc), arg) < 0 { + return syscall.GetErrno() } return nil } diff --git a/libgo/go/internal/x/net/lif/zsys_solaris_amd64.go b/libgo/go/internal/x/net/lif/zsys_solaris.go similarity index 95% rename from libgo/go/internal/x/net/lif/zsys_solaris_amd64.go rename to libgo/go/internal/x/net/lif/zsys_solaris.go index b5e999bec3a..0d9ed2f821a 100644 --- a/libgo/go/internal/x/net/lif/zsys_solaris_amd64.go +++ b/libgo/go/internal/x/net/lif/zsys_solaris.go @@ -3,6 +3,8 @@ package lif +import "unsafe" + const ( sysAF_UNSPEC = 0x0 sysAF_INET = 0x2 @@ -67,7 +69,6 @@ const ( type lifnum struct { Family uint16 - Pad_cgo_0 [2]byte Flags int32 Count int32 } @@ -81,16 +82,13 @@ type lifreq struct { type lifconf struct { Family uint16 - Pad_cgo_0 [2]byte Flags int32 Len int32 - Pad_cgo_1 [4]byte - Lifcu [8]byte + Lifcu [unsafe.Sizeof(unsafe.Pointer(nil))]byte } type lifIfinfoReq struct { Maxhops uint8 - Pad_cgo_0 [3]byte Reachtime uint32 Reachretrans uint32 Maxmtu uint32 diff --git a/libgo/go/runtime/signal_unix.go b/libgo/go/runtime/signal_unix.go index 0a2cf724c0d..2f89c7cbf43 100644 --- a/libgo/go/runtime/signal_unix.go +++ b/libgo/go/runtime/signal_unix.go @@ -441,7 +441,10 @@ func raisebadsignal(sig uint32, c *sigctxt) { // // On FreeBSD, the libthr sigaction code prevents // this from working so we fall through to raise. - if GOOS != "freebsd" && (isarchive || islibrary) && handler == _SIG_DFL && c.sigcode() != _SI_USER { + // + // The argument above doesn't hold for SIGPIPE, which won't + // necessarily be re-raised if we return. + if GOOS != "freebsd" && (isarchive || islibrary) && handler == _SIG_DFL && c.sigcode() != _SI_USER && sig != _SIGPIPE { return } diff --git a/libgo/runtime/go-libmain.c b/libgo/runtime/go-libmain.c index 5e3b8d9e48a..4f4763947e4 100644 --- a/libgo/runtime/go-libmain.c +++ b/libgo/runtime/go-libmain.c @@ -11,11 +11,129 @@ #include #include #include +#include +#include +#include #include "runtime.h" #include "array.h" #include "arch.h" +#if defined(__sun) && defined(__SVR4) + +/* Read a file into memory on Solaris, returning an malloc'ed buffer + and setting *SIZE to its size. */ + +static char * +read_file (const char *fn, size_t *size) +{ + struct stat st; + char *buf; + int o; + ssize_t got; + + if (stat (fn, &st) < 0) + return NULL; + buf = malloc ((size_t) st.st_size); + if (buf == NULL) + return NULL; + o = open (fn, O_RDONLY); + if (o < 0) + { + free (buf); + return NULL; + } + got = read (o, buf, st.st_size); + close (o); + if (got != st.st_size) + { + free (buf); + return NULL; + } + + *size = (size_t) got; + return buf; +} + +/* On Solaris we don't get passed argc/argv, but we can fetch it from + /proc/PID/cmdline. */ + +static void +read_cmdline (int *argc, char ***argv) +{ + pid_t pid; + char fn[50]; + char *argbuf; + size_t argsize; + char *envbuf; + size_t envsize; + char *p; + int i; + int ac; + + *argc = 0; + *argv = NULL; + + pid = getpid (); + snprintf (fn, sizeof fn, "/proc/%ld/cmdline", (long) pid); + argbuf = read_file (fn, &argsize); + if (argbuf == NULL) + return; + + snprintf (fn, sizeof fn, "/proc/%ld/environ", (long) pid); + envbuf = read_file (fn, &envsize); + if (envbuf == NULL) + { + free (argbuf); + return; + } + + i = 0; + for (p = argbuf; p < argbuf + argsize; p++) + if (*p == '\0') + ++i; + ac = i; + ++i; // For trailing NULL. + for (p = envbuf; p < envbuf + envsize; p++) + if (*p == '\0') + ++i; + ++i; // For trailing NULL. + + *argv = (char **) malloc (i * sizeof (char *)); + if (*argv == NULL) + { + free (argbuf); + free (envbuf); + return; + } + + *argc = ac; + (*argv)[0] = argbuf; + i = 0; + for (p = argbuf; p < argbuf + argsize; p++) + { + if (*p == '\0') + { + ++i; + (*argv)[i] = p + 1; + } + } + (*argv)[i] = NULL; + ++i; + (*argv)[i] = envbuf; + for (p = envbuf; p < envbuf + envsize; p++) + { + if (*p == '\0') + { + ++i; + (*argv)[i] = p + 1; + } + } + (*argv)[i] = NULL; +} + +#endif /* defined(__sun) && defined(__SVR4) */ + /* This is used when building a standalone Go library using the Go command's -buildmode=c-archive or -buildmode=c-shared option. It starts up the Go code as a global constructor but does not take any @@ -64,6 +182,10 @@ __go_init (int argc, char **argv, char** env __attribute__ ((unused))) struct args *a; pthread_t tid; +#if defined(__sun) && defined(__SVR4) + read_cmdline (&argc, &argv); +#endif + runtime_isarchive = true; setIsCgo (); -- 2.30.2