aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rwxr-xr-xerts/emulator/beam/erl_bif_info.c3
-rw-r--r--erts/emulator/beam/erl_init.c2
-rw-r--r--erts/emulator/beam/erl_utils.h4
-rw-r--r--erts/emulator/beam/utils.c91
4 files changed, 100 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 74a37f374d..447c1fdf18 100755
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -2646,6 +2646,9 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
#endif
BIF_RET(am_true);
}
+ else if (ERTS_IS_ATOM_STR("emu_args", BIF_ARG_1)) {
+ BIF_RET(erts_get_emu_args(BIF_P));
+ }
else if (ERTS_IS_ATOM_STR("dynamic_trace", BIF_ARG_1)) {
#if defined(USE_DTRACE)
DECL_AM(dtrace);
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 4bae3dfeb4..8d137df7ae 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -637,6 +637,8 @@ early_init(int *argc, char **argv) /*
char envbuf[21]; /* enough for any 64-bit integer */
size_t envbufsz;
+ erts_save_emu_args(*argc, argv);
+
erts_sched_compact_load = 1;
erts_printf_eterm_func = erts_printf_term;
erts_disable_tolerant_timeofday = 0;
diff --git a/erts/emulator/beam/erl_utils.h b/erts/emulator/beam/erl_utils.h
index a2064bd8a3..79c5105d92 100644
--- a/erts/emulator/beam/erl_utils.h
+++ b/erts/emulator/beam/erl_utils.h
@@ -24,6 +24,8 @@
#include "erl_smp.h"
#include "erl_printf.h"
+struct process;
+
typedef struct {
#ifdef DEBUG
int smp_api;
@@ -155,6 +157,8 @@ Uint32 block_hash(byte *, unsigned, Uint32);
Uint32 make_hash2(Eterm);
Uint32 make_hash(Eterm);
+void erts_save_emu_args(int argc, char **argv);
+Eterm erts_get_emu_args(struct process *c_p);
Eterm erts_bld_atom(Uint **hpp, Uint *szp, char *str);
Eterm erts_bld_uint(Uint **hpp, Uint *szp, Uint ui);
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 62caa67ce1..eb1c8f6173 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -3466,6 +3466,97 @@ erts_free_read_env(void *value)
erts_free(ERTS_ALC_T_TMP, value);
}
+
+typedef struct {
+ size_t sz;
+ char *ptr;
+} ErtsEmuArg;
+
+typedef struct {
+ int argc;
+ ErtsEmuArg *arg;
+ size_t no_bytes;
+} ErtsEmuArgs;
+
+ErtsEmuArgs saved_emu_args = {0};
+
+void
+erts_save_emu_args(int argc, char **argv)
+{
+#ifdef DEBUG
+ char *end_ptr;
+#endif
+ char *ptr;
+ int i;
+ size_t arg_sz[100];
+ size_t size;
+
+ ASSERT(!saved_emu_args.argc);
+
+ size = sizeof(ErtsEmuArg)*argc;
+ for (i = 0; i < argc; i++) {
+ size_t sz = sys_strlen(argv[i]);
+ if (i < sizeof(arg_sz)/sizeof(arg_sz[0]))
+ arg_sz[i] = sz;
+ size += sz+1;
+ }
+ ptr = (char *) malloc(size);
+#ifdef DEBUG
+ end_ptr = ptr + size;
+#endif
+ saved_emu_args.arg = (ErtsEmuArg *) ptr;
+ ptr += sizeof(ErtsEmuArg)*argc;
+ saved_emu_args.argc = argc;
+ saved_emu_args.no_bytes = 0;
+ for (i = 0; i < argc; i++) {
+ size_t sz;
+ if (i < sizeof(arg_sz)/sizeof(arg_sz[0]))
+ sz = arg_sz[i];
+ else
+ sz = sys_strlen(argv[i]);
+ saved_emu_args.arg[i].ptr = ptr;
+ saved_emu_args.arg[i].sz = sz;
+ saved_emu_args.no_bytes += sz;
+ ptr += sz+1;
+ sys_strcpy(saved_emu_args.arg[i].ptr, argv[i]);
+ }
+ ASSERT(ptr == end_ptr);
+}
+
+Eterm
+erts_get_emu_args(Process *c_p)
+{
+#ifdef DEBUG
+ Eterm *end_hp;
+#endif
+ int i;
+ Uint hsz;
+ Eterm *hp, res;
+
+ hsz = saved_emu_args.no_bytes*2;
+ hsz += saved_emu_args.argc*2;
+
+ hp = HAlloc(c_p, hsz);
+#ifdef DEBUG
+ end_hp = hp + hsz;
+#endif
+ res = NIL;
+
+ for (i = saved_emu_args.argc-1; i >= 0; i--) {
+ Eterm arg = buf_to_intlist(&hp,
+ saved_emu_args.arg[i].ptr,
+ saved_emu_args.arg[i].sz,
+ NIL);
+ res = CONS(hp, arg, res);
+ hp += 2;
+ }
+
+ ASSERT(hp == end_hp);
+
+ return res;
+}
+
+
/*
* To be used to silence unused result warnings, but do not abuse it.
*/