Commit ea31c98d by Ian Lance Taylor

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
parent a9647bf9
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.
...@@ -1082,7 +1082,7 @@ $(eval $(call PACKAGE_template,internal/x/net/lif)) ...@@ -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
......
...@@ -1131,7 +1131,7 @@ extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a ...@@ -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)) \
......
...@@ -11,18 +11,12 @@ import ( ...@@ -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
} }
...@@ -3,6 +3,8 @@ ...@@ -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 ( ...@@ -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 { ...@@ -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
......
...@@ -441,7 +441,10 @@ func raisebadsignal(sig uint32, c *sigctxt) { ...@@ -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
} }
......
...@@ -11,11 +11,129 @@ ...@@ -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))) ...@@ -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 ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment