diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-01-21 23:05:52 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-01-21 23:05:52 +0000 |
commit | ea31c98daba7d3459dc5500049876fe0a71a89d3 (patch) | |
tree | 9dc7ee584a37d93ea00455a5ec27d75fa464bf58 /libgo/runtime/go-libmain.c | |
parent | a9647bf912b9d2eeb9297bb96d5274eb8c9ed75c (diff) | |
download | gcc-ea31c98daba7d3459dc5500049876fe0a71a89d3.zip gcc-ea31c98daba7d3459dc5500049876fe0a71a89d3.tar.gz gcc-ea31c98daba7d3459dc5500049876fe0a71a89d3.tar.bz2 |
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
Diffstat (limited to 'libgo/runtime/go-libmain.c')
-rw-r--r-- | libgo/runtime/go-libmain.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/libgo/runtime/go-libmain.c b/libgo/runtime/go-libmain.c index 5e3b8d9..4f47639 100644 --- a/libgo/runtime/go-libmain.c +++ b/libgo/runtime/go-libmain.c @@ -11,11 +11,129 @@ #include <stdlib.h> #include <time.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #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 (); |