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
This commit is contained in:
Ian Lance Taylor 2019-01-21 23:05:52 +00:00
parent a9647bf912
commit ea31c98dab
7 changed files with 136 additions and 19 deletions

View File

@ -1,4 +1,4 @@
e7427654f3af83e1feea727a62a97172d7721403 0c870ba6b3b43e0e56231f40c56b58dad0e36d9e
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View File

@ -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.lo internal/x/net/lif.lo
internal_x_net_lif_check = \ internal_x_net_lif_check = \
internal_org/x/net/lif/check internal/x/net/lif/check
endif endif

View File

@ -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.lo
@LIBGO_IS_SOLARIS_TRUE@internal_x_net_lif_check = \ @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) TPACKAGES = $(shell cat $(srcdir)/check-packages.txt)
TEST_PACKAGES = $(addsuffix /check,$(TPACKAGES)) \ TEST_PACKAGES = $(addsuffix /check,$(TPACKAGES)) \

View File

@ -11,18 +11,12 @@ import (
"unsafe" "unsafe"
) )
//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" //extern __go_ioctl_ptr
func libc_ioctl(int32, int32, unsafe.Pointer) int32
//go:linkname procIoctl libc_ioctl
var procIoctl uintptr
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno)
func ioctl(s, ioc uintptr, arg unsafe.Pointer) error { func ioctl(s, ioc uintptr, arg unsafe.Pointer) error {
_, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procIoctl)), 3, s, ioc, uintptr(arg), 0, 0, 0) if libc_ioctl(int32(s), int32(ioc), arg) < 0 {
if errno != 0 { return syscall.GetErrno()
return error(errno)
} }
return nil return nil
} }

View File

@ -3,6 +3,8 @@
package lif package lif
import "unsafe"
const ( const (
sysAF_UNSPEC = 0x0 sysAF_UNSPEC = 0x0
sysAF_INET = 0x2 sysAF_INET = 0x2
@ -67,7 +69,6 @@ const (
type lifnum struct { type lifnum struct {
Family uint16 Family uint16
Pad_cgo_0 [2]byte
Flags int32 Flags int32
Count int32 Count int32
} }
@ -81,16 +82,13 @@ type lifreq struct {
type lifconf struct { type lifconf struct {
Family uint16 Family uint16
Pad_cgo_0 [2]byte
Flags int32 Flags int32
Len int32 Len int32
Pad_cgo_1 [4]byte Lifcu [unsafe.Sizeof(unsafe.Pointer(nil))]byte
Lifcu [8]byte
} }
type lifIfinfoReq struct { type lifIfinfoReq struct {
Maxhops uint8 Maxhops uint8
Pad_cgo_0 [3]byte
Reachtime uint32 Reachtime uint32
Reachretrans uint32 Reachretrans uint32
Maxmtu uint32 Maxmtu uint32

View File

@ -441,7 +441,10 @@ func raisebadsignal(sig uint32, c *sigctxt) {
// //
// On FreeBSD, the libthr sigaction code prevents // On FreeBSD, the libthr sigaction code prevents
// this from working so we fall through to raise. // 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 return
} }

View File

@ -11,11 +11,129 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "runtime.h" #include "runtime.h"
#include "array.h" #include "array.h"
#include "arch.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 /* This is used when building a standalone Go library using the Go
command's -buildmode=c-archive or -buildmode=c-shared option. It 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 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; struct args *a;
pthread_t tid; pthread_t tid;
#if defined(__sun) && defined(__SVR4)
read_cmdline (&argc, &argv);
#endif
runtime_isarchive = true; runtime_isarchive = true;
setIsCgo (); setIsCgo ();