aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/sys')
-rw-r--r--erts/emulator/sys/common/erl_mmap.c8
-rw-r--r--erts/emulator/sys/common/erl_mmap.h5
-rw-r--r--erts/emulator/sys/common/erl_mseg.c20
-rw-r--r--erts/emulator/sys/common/erl_mseg.h4
-rw-r--r--erts/emulator/sys/common/erl_poll.c14
-rw-r--r--erts/emulator/sys/unix/erl_child_setup.c117
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h2
-rw-r--r--erts/emulator/sys/unix/sys.c63
-rw-r--r--erts/emulator/sys/unix/sys_drivers.c55
-rw-r--r--erts/emulator/sys/win32/erl_win_sys.h2
-rw-r--r--erts/emulator/sys/win32/sys.c9
11 files changed, 218 insertions, 81 deletions
diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c
index 7bbb406f29..a5714f8325 100644
--- a/erts/emulator/sys/common/erl_mmap.c
+++ b/erts/emulator/sys/common/erl_mmap.c
@@ -2390,7 +2390,7 @@ add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
}
Eterm erts_mmap_info(ErtsMemMapper* mm,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Eterm** hpp, Uint* szp,
struct erts_mmap_info_struct* emis)
@@ -2431,7 +2431,7 @@ Eterm erts_mmap_info(ErtsMemMapper* mm,
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
if (mm->supercarrier) {
const char* prefix = "supercarrier ";
@@ -2485,7 +2485,7 @@ Eterm erts_mmap_info(ErtsMemMapper* mm,
Eterm erts_mmap_info_options(ErtsMemMapper* mm,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -2496,7 +2496,7 @@ Eterm erts_mmap_info_options(ErtsMemMapper* mm,
Eterm res = THE_NON_VALUE;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to, arg, "%sscs: %bpu\n", prefix, scs);
if (mm->supercarrier) {
diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h
index fa51b663fa..623b5188ac 100644
--- a/erts/emulator/sys/common/erl_mmap.h
+++ b/erts/emulator/sys/common/erl_mmap.h
@@ -22,6 +22,7 @@
#define ERL_MMAP_H__
#include "sys.h"
+#include "erl_printf.h"
#define ERTS_MMAP_SUPERALIGNED_BITS (18)
/* Affects hard limits for sbct and lmbcs documented in erts_alloc.xml */
@@ -146,10 +147,10 @@ struct erts_mmap_info_struct
UWord segs[6];
UWord os_used;
};
-Eterm erts_mmap_info(ErtsMemMapper*, int *print_to_p, void *print_to_arg,
+Eterm erts_mmap_info(ErtsMemMapper*, fmtfn_t *print_to_p, void *print_to_arg,
Eterm** hpp, Uint* szp, struct erts_mmap_info_struct*);
Eterm erts_mmap_info_options(ErtsMemMapper*,
- char *prefix, int *print_to_p, void *print_to_arg,
+ char *prefix, fmtfn_t *print_to_p, void *print_to_arg,
Uint **hpp, Uint *szp);
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index f3306a888c..882c93a83c 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -991,7 +991,7 @@ add_4tup(Uint **hpp, Uint *szp, Eterm *lp,
static Eterm
info_options(ErtsMsegAllctr_t *ma,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -999,7 +999,7 @@ info_options(ErtsMsegAllctr_t *ma,
Eterm res = NIL;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to, arg, "%samcbf: %beu\n", prefix, ma->abs_max_cache_bad_fit);
erts_print(to, arg, "%srmcbf: %beu\n", prefix, ma->rel_max_cache_bad_fit);
@@ -1027,7 +1027,7 @@ info_options(ErtsMsegAllctr_t *ma,
}
static Eterm
-info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
+info_calls(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1040,7 +1040,7 @@ info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp
erts_print(TO, TOA, "mseg_%s calls: %b32u%09b32u\n", #CC, \
ma->calls.CC.giga_no, ma->calls.CC.no)
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
PRINT_CC(to, arg, alloc);
@@ -1106,7 +1106,7 @@ info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp
}
static Eterm
-info_status(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
+info_status(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg,
int begin_new_max_period, int only_sz, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1117,7 +1117,7 @@ info_status(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
ma->segments.max_ever.sz = ma->segments.max.sz;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
if (!only_sz) {
@@ -1165,7 +1165,7 @@ info_status(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
return res;
}
-static Eterm info_memkind(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
+static Eterm info_memkind(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg,
int begin_max_per, int only_sz, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1196,7 +1196,7 @@ static Eterm info_memkind(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_
}
static Eterm
-info_version(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
+info_version(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1218,7 +1218,7 @@ info_version(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **h
Eterm
erts_mseg_info_options(int ix,
- int *print_to_p, void *print_to_arg,
+ fmtfn_t *print_to_p, void *print_to_arg,
Uint **hpp, Uint *szp)
{
ErtsMsegAllctr_t *ma = ERTS_MSEG_ALLCTR_IX(ix);
@@ -1231,7 +1231,7 @@ erts_mseg_info_options(int ix,
Eterm
erts_mseg_info(int ix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
int begin_max_per,
int only_sz,
diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h
index a43b409e94..bba0dec499 100644
--- a/erts/emulator/sys/common/erl_mseg.h
+++ b/erts/emulator/sys/common/erl_mseg.h
@@ -98,8 +98,8 @@ Uint erts_mseg_unit_size(void);
void erts_mseg_init(ErtsMsegInit_t *init);
void erts_mseg_late_init(void); /* Have to be called after all allocators,
threads and timers have been initialized. */
-Eterm erts_mseg_info_options(int, int *, void*, Uint **, Uint *);
-Eterm erts_mseg_info(int, int *, void*, int, int, Uint **, Uint *);
+Eterm erts_mseg_info_options(int, fmtfn_t*, void*, Uint **, Uint *);
+Eterm erts_mseg_info(int, fmtfn_t *, void*, int, int, Uint **, Uint *);
#endif /* #if HAVE_ERTS_MSEG */
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index e394d84f73..b8a28bcc18 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -75,6 +75,7 @@
#include "erl_driver.h"
#include "erl_alloc.h"
#include "erl_msacc.h"
+#include "erl_misc_utils.h"
#if !defined(ERTS_POLL_USE_EPOLL) \
&& !defined(ERTS_POLL_USE_DEVPOLL) \
@@ -2132,16 +2133,19 @@ get_timeout(ErtsPollSet ps,
if (timeout > (ErtsMonotonicTime) INT_MAX)
timeout = (ErtsMonotonicTime) INT_MAX;
save_timeout_time += ERTS_MSEC_TO_MONOTONIC(timeout);
+ timeout -= ERTS_PREMATURE_TIMEOUT(timeout, 1000);
break;
case 1000000:
/* Round up to nearest even micro second */
timeout = ERTS_MONOTONIC_TO_USEC(diff_time - 1) + 1;
save_timeout_time += ERTS_USEC_TO_MONOTONIC(timeout);
+ timeout -= ERTS_PREMATURE_TIMEOUT(timeout, 1000*1000);
break;
case 1000000000:
/* Round up to nearest even nano second */
timeout = ERTS_MONOTONIC_TO_NSEC(diff_time - 1) + 1;
save_timeout_time += ERTS_NSEC_TO_MONOTONIC(timeout);
+ timeout -= ERTS_PREMATURE_TIMEOUT(timeout, 1000*1000*1000);
break;
default:
ERTS_INTERNAL_ERROR("Invalid resolution");
@@ -2452,7 +2456,15 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
}
#endif
- res = check_fd_events(ps, to, no_fds);
+ while (1) {
+ res = check_fd_events(ps, to, no_fds);
+ if (res != 0)
+ break;
+ if (to == ERTS_POLL_NO_TIMEOUT)
+ break;
+ if (erts_get_monotonic_time(NULL) >= timeout_time)
+ break;
+ }
woke_up(ps);
diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c
index 6beb316350..69fc6c2879 100644
--- a/erts/emulator/sys/unix/erl_child_setup.c
+++ b/erts/emulator/sys/unix/erl_child_setup.c
@@ -54,6 +54,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <stdarg.h>
#include <sys/wait.h>
#define WANT_NONBLOCKING
@@ -74,15 +75,22 @@
//#define HARD_DEBUG
#ifdef HARD_DEBUG
-#define DEBUG_PRINT(fmt, ...) fprintf(stderr, fmt "\r\n", ##__VA_ARGS__)
+#define DEBUG_PRINT(fmt, ...) fprintf(stderr, "%d:" fmt "\r\n", getpid(), ##__VA_ARGS__)
#else
#define DEBUG_PRINT(fmt, ...)
#endif
-#define ABORT(fmt, ...) do { \
- fprintf(stderr, "erl_child_setup: " fmt "\r\n", ##__VA_ARGS__); \
- abort(); \
- } while(0)
+static char abort_reason[200]; /* for core dump inspection */
+
+static void ABORT(const char* fmt, ...)
+{
+ va_list arglist;
+ va_start(arglist, fmt);
+ vsprintf(abort_reason, fmt, arglist);
+ fprintf(stderr, "erl_child_setup: %s\r\n", abort_reason);
+ va_end(arglist);
+ abort();
+}
#ifdef DEBUG
void
@@ -123,12 +131,13 @@ static int sigchld_pipe[2];
static int
start_new_child(int pipes[])
{
+ int errln = -1;
int size, res, i, pos = 0;
char *buff, *o_buff;
- char *cmd, *wd, **new_environ, **args = NULL;
+ char *cmd, *cwd, *wd, **new_environ, **args = NULL;
- Sint cnt, flags;
+ Sint32 cnt, flags;
/* only child executes here */
@@ -137,6 +146,7 @@ start_new_child(int pipes[])
} while(res < 0 && (errno == EINTR || errno == ERRNO_BLOCK));
if (res <= 0) {
+ errln = __LINE__;
goto child_error;
}
@@ -148,10 +158,12 @@ start_new_child(int pipes[])
if ((res = read(pipes[0], buff + pos, size - pos)) < 0) {
if (errno == ERRNO_BLOCK || errno == EINTR)
continue;
+ errln = __LINE__;
goto child_error;
}
if (res == 0) {
errno = EPIPE;
+ errln = __LINE__;
goto child_error;
}
pos += res;
@@ -160,12 +172,16 @@ start_new_child(int pipes[])
o_buff = buff;
flags = get_int32(buff);
- buff += sizeof(Sint32);
+ buff += sizeof(flags);
DEBUG_PRINT("flags = %d", flags);
cmd = buff;
buff += strlen(buff) + 1;
+
+ cwd = buff;
+ buff += strlen(buff) + 1;
+
if (*buff == '\0') {
wd = NULL;
} else {
@@ -177,10 +193,10 @@ start_new_child(int pipes[])
DEBUG_PRINT("wd = %s", wd);
cnt = get_int32(buff);
- buff += sizeof(Sint32);
+ buff += sizeof(cnt);
new_environ = malloc(sizeof(char*)*(cnt + 1));
- DEBUG_PRINT("env_len = %ld", cnt);
+ DEBUG_PRINT("env_len = %d", cnt);
for (i = 0; i < cnt; i++, buff++) {
new_environ[i] = buff;
while(*buff != '\0') buff++;
@@ -190,7 +206,7 @@ start_new_child(int pipes[])
if (o_buff + size != buff) {
/* This is a spawn executable call */
cnt = get_int32(buff);
- buff += sizeof(Sint32);
+ buff += sizeof(cnt);
args = malloc(sizeof(char*)*(cnt + 1));
for (i = 0; i < cnt; i++, buff++) {
args[i] = buff;
@@ -201,7 +217,12 @@ start_new_child(int pipes[])
if (o_buff + size != buff) {
errno = EINVAL;
- goto child_error;
+ errln = __LINE__;
+ fprintf(stderr,"erl_child_setup: failed with protocol "
+ "error %d on line %d", errno, errln);
+ /* we abort here as it is most likely a symptom of an
+ emulator/erl_child_setup bug */
+ abort();
}
DEBUG_PRINT("read ack");
@@ -213,12 +234,32 @@ start_new_child(int pipes[])
ASSERT(res == sizeof(proto));
}
} while(res < 0 && (errno == EINTR || errno == ERRNO_BLOCK));
+
if (res < 1) {
errno = EPIPE;
+ errln = __LINE__;
goto child_error;
}
- DEBUG_PRINT("Do that forking business: '%s'\n",cmd);
+ DEBUG_PRINT("Set cwd to: '%s'",cwd);
+
+ if (chdir(cwd) < 0) {
+ /* This is not good, it probably means that the cwd of
+ beam is invalid. We ignore it and try anyways as
+ the child might now need a cwd or the chdir below
+ could take us to a valid directory.
+ */
+ }
+
+ DEBUG_PRINT("Set wd to: '%s'",wd);
+
+ if (wd && chdir(wd) < 0) {
+ int err = errno;
+ fprintf(stderr,"spawn: Could not cd to %s\r\n", wd);
+ _exit(err);
+ }
+
+ DEBUG_PRINT("Do that forking business: '%s'",cmd);
/* When the dup2'ing below is done, only
fd's 0, 1, 2 and maybe 3, 4 should survive the
@@ -228,25 +269,34 @@ start_new_child(int pipes[])
if (flags & FORKER_FLAG_USE_STDIO) {
/* stdin for process */
if (flags & FORKER_FLAG_DO_WRITE &&
- dup2(pipes[0], 0) < 0)
+ dup2(pipes[0], 0) < 0) {
+ errln = __LINE__;
goto child_error;
+ }
/* stdout for process */
if (flags & FORKER_FLAG_DO_READ &&
- dup2(pipes[1], 1) < 0)
+ dup2(pipes[1], 1) < 0) {
+ errln = __LINE__;
goto child_error;
+ }
}
else { /* XXX will fail if pipes[0] == 4 (unlikely..) */
- if (flags & FORKER_FLAG_DO_READ && dup2(pipes[1], 4) < 0)
+ if (flags & FORKER_FLAG_DO_READ && dup2(pipes[1], 4) < 0) {
+ errln = __LINE__;
goto child_error;
- if (flags & FORKER_FLAG_DO_WRITE && dup2(pipes[0], 3) < 0)
+ }
+ if (flags & FORKER_FLAG_DO_WRITE && dup2(pipes[0], 3) < 0) {
+ errln = __LINE__;
goto child_error;
+ }
}
- if (dup2(pipes[2], 2) < 0)
- goto child_error;
-
- if (wd && chdir(wd) < 0)
+ /* we do the dup2 of stderr last so that errors
+ in child_error will be printed to stderr */
+ if (dup2(pipes[2], 2) < 0) {
+ errln = __LINE__;
goto child_error;
+ }
#if defined(USE_SETPGRP_NOARGS) /* SysV */
(void) setpgrp();
@@ -268,9 +318,14 @@ start_new_child(int pipes[])
} else {
execle(SHELL, "sh", "-c", cmd, (char *) NULL, new_environ);
}
+
+ DEBUG_PRINT("exec error: %d",errno);
+ _exit(errno);
+
child_error:
- DEBUG_PRINT("exec error: %d\r\n",errno);
- _exit(128 + errno);
+ fprintf(stderr,"erl_child_setup: failed with error %d on line %d\r\n",
+ errno, errln);
+ _exit(errno);
}
@@ -293,7 +348,7 @@ child_error:
* for posterity. */
static void handle_sigchld(int sig) {
- int buff[2], res;
+ int buff[2], res, __preverrno = errno;
sys_sigblock(SIGCHLD);
@@ -307,6 +362,16 @@ static void handle_sigchld(int sig) {
}
sys_sigrelease(SIGCHLD);
+
+ /* We save and restore the original errno as otherwise
+ the thread we are running in may end up with an
+ unexpected errno. An example of when this happened
+ was when the select in main had gotten an EINTR but
+ before the errno was checked the signal handler
+ was called and set errno to ECHILD from waitpid
+ which caused erl_child_setup to abort as it does
+ not expect ECHILD to be set after select */
+ errno = __preverrno;
}
#if defined(__ANDROID__)
@@ -368,7 +433,7 @@ main(int argc, char *argv[])
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &sa, 0) == -1) {
- perror(0);
+ perror(NULL);
exit(1);
}
@@ -461,7 +526,7 @@ main(int argc, char *argv[])
proto.action = ErtsSysForkerProtoAction_SigChld;
proto.u.sigchld.error_number = ibuff[1];
- DEBUG_PRINT("send %s to %d", buff, uds_fd);
+ DEBUG_PRINT("send sigchld to %d (errno = %d)", uds_fd, ibuff[1]);
if (write(uds_fd, &proto, sizeof(proto)) < 0) {
if (errno == EINTR)
continue;
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 3a0d23cd36..b64b0d87f6 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -282,7 +282,7 @@ ERTS_GLB_INLINE ErtsSysPerfCounter erts_sys_perf_counter(void);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
-ERTS_GLB_INLINE ErtsSysPerfCounter
+ERTS_GLB_FORCE_INLINE ErtsSysPerfCounter
erts_sys_perf_counter()
{
return (*erts_sys_time_data__.r.o.perf_counter)();
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 6fb86f6dda..e135dbff99 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -90,8 +90,6 @@ extern void erl_sys_args(int*, char**);
extern void erts_sys_init_float(void);
-extern void erl_crash_dump(char* file, int line, char* fmt, ...);
-
#ifdef DEBUG
static int debug_log = 0;
@@ -121,9 +119,8 @@ erts_smp_atomic_t sys_misc_mem_sz;
static void smp_sig_notify(char c);
static int sig_notify_fds[2] = {-1, -1};
-#if !defined(ETHR_UNUSABLE_SIGUSRX) && defined(ERTS_THR_HAVE_SIG_FUNCS)
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
static int sig_suspend_fds[2] = {-1, -1};
-#define ERTS_SYS_SUSPEND_SIGNAL SIGUSR2
#endif
#endif
@@ -409,11 +406,16 @@ erts_sys_pre_init(void)
#ifdef ERTS_THR_HAVE_SIG_FUNCS
sigemptyset(&thr_create_sigmask);
sigaddset(&thr_create_sigmask, SIGINT); /* block interrupt */
+ sigaddset(&thr_create_sigmask, SIGTERM); /* block terminate signal */
sigaddset(&thr_create_sigmask, SIGUSR1); /* block user defined signal */
#endif
erts_thr_init(&eid);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_init();
+#endif
+
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_init();
#endif
@@ -653,6 +655,40 @@ static RETSIGTYPE request_break(int signum)
#endif
}
+static void stop_requested(void) {
+ Process* p = NULL;
+ Eterm msg, *hp;
+ ErtsProcLocks locks = 0;
+ ErlOffHeap *ohp;
+ Eterm id = erts_whereis_name_to_id(NULL, am_init);
+
+ if ((p = (erts_pid2proc_opt(NULL, 0, id, 0, ERTS_P2P_FLG_INC_REFC))) != NULL) {
+ ErtsMessage *msgp = erts_alloc_message_heap(p, &locks, 3, &hp, &ohp);
+
+ /* init ! {stop,stop} */
+ msg = TUPLE2(hp, am_stop, am_stop);
+ erts_queue_message(p, locks, msgp, msg, am_system);
+
+ if (locks)
+ erts_smp_proc_unlock(p, locks);
+ erts_proc_dec_refc(p);
+ }
+}
+
+#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
+static RETSIGTYPE request_stop(void)
+#else
+static RETSIGTYPE request_stop(int signum)
+#endif
+{
+#ifdef ERTS_SMP
+ smp_sig_notify('S');
+#else
+ stop_requested();
+#endif
+}
+
+
static ERTS_INLINE void
sigusr1_exit(void)
{
@@ -672,7 +708,7 @@ sigusr1_exit(void)
}
prepare_crash_dump(secs);
- erts_exit(ERTS_ERROR_EXIT, "Received SIGUSR1\n");
+ erts_exit(ERTS_DUMP_EXIT, "Received SIGUSR1\n");
}
#ifdef ETHR_UNUSABLE_SIGUSRX
@@ -715,11 +751,13 @@ static RETSIGTYPE suspend_signal(void)
static RETSIGTYPE suspend_signal(int signum)
#endif
{
- int res;
- int buf[1];
- do {
- res = read(sig_suspend_fds[0], buf, sizeof(int));
- } while (res < 0 && errno == EINTR);
+ int res, buf[1], tmp_errno = errno;
+ do {
+ res = read(sig_suspend_fds[0], buf, sizeof(int));
+ } while (res < 0 && errno == EINTR);
+
+ /* restore previous errno in case read changed it */
+ errno = tmp_errno;
}
#endif /* #ifdef ERTS_SYS_SUSPEND_SIGNAL */
@@ -747,6 +785,7 @@ static RETSIGTYPE do_quit(int signum)
/* Disable break */
void erts_set_ignore_break(void) {
sys_signal(SIGINT, SIG_IGN);
+ sys_signal(SIGTERM, SIG_IGN);
sys_signal(SIGQUIT, SIG_IGN);
sys_signal(SIGTSTP, SIG_IGN);
}
@@ -772,6 +811,7 @@ void erts_replace_intr(void) {
void init_break_handler(void)
{
sys_signal(SIGINT, request_break);
+ sys_signal(SIGTERM, request_stop);
#ifndef ETHR_UNUSABLE_SIGUSRX
sys_signal(SIGUSR1, user_signal1);
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
@@ -1285,6 +1325,9 @@ signal_dispatcher_thread_func(void *unused)
switch (buf[i]) {
case 0: /* Emulator initialized */
break;
+ case 'S': /* SIGTERM */
+ stop_requested();
+ break;
case 'I': /* SIGINT */
break_requested();
break;
diff --git a/erts/emulator/sys/unix/sys_drivers.c b/erts/emulator/sys/unix/sys_drivers.c
index 812112fb91..400f163652 100644
--- a/erts/emulator/sys/unix/sys_drivers.c
+++ b/erts/emulator/sys/unix/sys_drivers.c
@@ -554,7 +554,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name,
ErtsSysDriverData *dd;
char *cmd_line;
char wd_buff[MAXPATHLEN+1];
- char *wd;
+ char *wd, *cwd;
int ifd[2], ofd[2], stderrfd;
if (pipe(ifd) < 0) return ERL_DRV_ERROR_ERRNO;
@@ -631,24 +631,22 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name,
return ERL_DRV_ERROR_ERRNO;
}
- if (opts->wd == NULL) {
- if ((wd = getcwd(wd_buff, MAXPATHLEN+1)) == NULL) {
- /* on some OSs this call opens a fd in the
- background which means that this can
- return EMFILE */
- int err = errno;
- close_pipes(ifd, ofd);
- erts_free(ERTS_ALC_T_TMP, (void *) cmd_line);
- if (new_environ != environ)
- erts_free(ERTS_ALC_T_ENVIRONMENT, (void *) new_environ);
- erts_smp_rwmtx_runlock(&environ_rwmtx);
- errno = err;
- return ERL_DRV_ERROR_ERRNO;
- }
- } else {
- wd = opts->wd;
+ if ((cwd = getcwd(wd_buff, MAXPATHLEN+1)) == NULL) {
+ /* on some OSs this call opens a fd in the
+ background which means that this can
+ return EMFILE */
+ int err = errno;
+ close_pipes(ifd, ofd);
+ erts_free(ERTS_ALC_T_TMP, (void *) cmd_line);
+ if (new_environ != environ)
+ erts_free(ERTS_ALC_T_ENVIRONMENT, (void *) new_environ);
+ erts_smp_rwmtx_runlock(&environ_rwmtx);
+ errno = err;
+ return ERL_DRV_ERROR_ERRNO;
}
+ wd = opts->wd;
+
{
struct iovec *io_vector;
int iov_len = 5;
@@ -660,6 +658,8 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name,
| (opts->read_write & DO_READ ? FORKER_FLAG_DO_READ : 0)
| (opts->read_write & DO_WRITE ? FORKER_FLAG_DO_WRITE : 0);
+ if (wd) iov_len++;
+
/* count number of elements in environment */
while(new_environ[env_len] != NULL)
env_len++;
@@ -688,6 +688,10 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name,
return ERL_DRV_ERROR_ERRNO;
}
+ /*
+ * Whitebox test port_SUITE:pipe_limit_env
+ * assumes this command payload format.
+ */
io_vector[i].iov_base = (void*)&buffsz;
io_vector[i++].iov_len = sizeof(buffsz);
@@ -700,10 +704,16 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name,
io_vector[i++].iov_len = len;
buffsz += len;
- io_vector[i].iov_base = wd;
+ io_vector[i].iov_base = cwd;
io_vector[i].iov_len = strlen(io_vector[i].iov_base) + 1;
buffsz += io_vector[i++].iov_len;
+ if (wd) {
+ io_vector[i].iov_base = wd;
+ io_vector[i].iov_len = strlen(io_vector[i].iov_base) + 1;
+ buffsz += io_vector[i++].iov_len;
+ }
+
io_vector[i].iov_base = nullbuff;
io_vector[i++].iov_len = 1;
buffsz += io_vector[i-1].iov_len;
@@ -765,9 +775,14 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name,
if (res < (buffsz + sizeof(buffsz))) {
/* we only wrote part of the command payload. Enqueue the rest. */
for (i = 0; i < iov_len; i++) {
- driver_enq(port_num, io_vector[i].iov_base, io_vector[i].iov_len);
+ if (res >= io_vector[i].iov_len)
+ res -= io_vector[i].iov_len;
+ else {
+ driver_enq(port_num, io_vector[i].iov_base + res,
+ io_vector[i].iov_len - res);
+ res = 0;
+ }
}
- driver_deq(port_num, res);
driver_select(port_num, ofd[1], ERL_DRV_WRITE|ERL_DRV_USE, 1);
}
diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h
index 04fbf23109..78005aada9 100644
--- a/erts/emulator/sys/win32/erl_win_sys.h
+++ b/erts/emulator/sys/win32/erl_win_sys.h
@@ -182,6 +182,8 @@ typedef LONGLONG ErtsMonotonicTime;
typedef LONGLONG ErtsSysHrTime;
#endif
+#define ErtsStrToSint64 _strtoi64
+
typedef ErtsMonotonicTime ErtsSystemTime;
typedef ErtsMonotonicTime ErtsSysPerfCounter;
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index cf821b05cb..f3881e0736 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -40,7 +40,6 @@ void erts_sys_init_float(void);
void erl_start(int, char**);
void erts_exit(int n, char*, ...);
void erl_error(char*, va_list);
-void erl_crash_dump(char*, int, char*, ...);
/*
* Microsoft-specific function to map a WIN32 error code to a Posix errno.
@@ -3187,16 +3186,16 @@ erts_sys_pre_init(void)
eid.thread_create_parent_func = thr_create_cleanup;
erts_thr_init(&eid);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_init();
#endif
-
- erts_init_sys_time_sup();
-
-#ifdef USE_THREADS
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_init();
#endif
#endif
+ erts_init_sys_time_sup();
+
erts_smp_atomic_init_nob(&sys_misc_mem_sz, 0);
}