aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/sys.h6
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c3
-rw-r--r--erts/emulator/sys/common/erl_check_io.c10
-rw-r--r--erts/emulator/sys/common/erl_mseg.c7
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h1
-rw-r--r--erts/emulator/sys/unix/sys.c44
-rw-r--r--erts/emulator/sys/unix/sys_drivers.c1
7 files changed, 64 insertions, 8 deletions
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index d49edad6dc..dd4f05686b 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -481,6 +481,12 @@ extern volatile int erts_break_requested;
void erts_do_break_handling(void);
#endif
+#if !defined(ERTS_SMP) && !defined(__WIN32__)
+extern volatile Uint erts_signal_sigterm;
+#define ERTS_SIGNAL_SIGTERM erts_signal_sigterm
+void erts_handle_signal_sigterm(void);
+#endif
+
#ifdef ERTS_WANT_GOT_SIGUSR1
# ifndef UNIX
# define ERTS_GOT_SIGUSR1 0
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 3ff68a8859..0acc2432a7 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -430,6 +430,9 @@ efile_openfile(Efile_error* errInfo, /* Where to return error codes. */
if ( (stat("/dev/null", &nullstatbuf) < 0)
|| (statbuf.st_ino != nullstatbuf.st_ino)
|| (statbuf.st_dev != nullstatbuf.st_dev) ) {
+#ifdef HAVE_FSTAT
+ efile_closefile(fd);
+#endif
errno = EISDIR;
return check_error(-1, errInfo);
}
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c
index 44a77f3ea5..8f2f1f9521 100644
--- a/erts/emulator/sys/common/erl_check_io.c
+++ b/erts/emulator/sys/common/erl_check_io.c
@@ -1617,6 +1617,11 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait)
erts_do_break_handling();
#endif
+#ifdef ERTS_SIGNAL_SIGTERM
+ if (ERTS_SIGNAL_SIGTERM)
+ erts_handle_signal_sigterm();
+#endif
+
/* Figure out timeout value */
timeout_time = (do_wait
? erts_check_next_timeout_time(esdp)
@@ -1654,6 +1659,11 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait)
erts_do_break_handling();
#endif
+#ifdef ERTS_SIGNAL_SIGTERM
+ if (ERTS_SIGNAL_SIGTERM)
+ erts_handle_signal_sigterm();
+#endif
+
if (poll_ret != 0) {
erts_smp_atomic_set_nob(&pollset.in_poll_wait, 0);
forget_removed(&pollset);
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index 882c93a83c..968f71211c 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -87,6 +87,7 @@ static const int debruijn[32] = {
#define CACHE_AREAS (32 - MSEG_ALIGN_BITS)
+/* FIXME: segment sizes > 2 GB result in bogus negative indices */
#define SIZE_TO_CACHE_AREA_IDX(S) (LOG2((S)) - MSEG_ALIGN_BITS)
#define MAX_CACHE_SIZE (30)
@@ -396,6 +397,9 @@ static ERTS_INLINE int cache_bless_segment(ErtsMsegAllctr_t *ma, void *seg, UWor
if (MSEG_FLG_IS_2POW(flags)) {
int ix = SIZE_TO_CACHE_AREA_IDX(size);
+ if (ix < 0)
+ return 0;
+
ASSERT(ix < CACHE_AREAS);
ASSERT((1 << (ix + MSEG_ALIGN_BITS)) == size);
@@ -471,6 +475,9 @@ static ERTS_INLINE void *cache_get_segment(ErtsMsegAllctr_t *ma, UWord *size_p,
ASSERT(IS_2POW(size));
+ if (ix < 0)
+ return NULL;
+
for( i = ix; i < CACHE_AREAS; i++) {
if (erts_circleq_is_empty(&(ma->cache_powered_node[i])))
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index b64b0d87f6..054a4678c8 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -322,6 +322,7 @@ extern SIGFUNC sys_signal(int, SIGFUNC);
extern void sys_sigrelease(int);
extern void sys_sigblock(int);
extern void sys_init_suspend_handler(void);
+extern void erts_sys_unix_later_init(void);
/*
* Handling of floating point exceptions.
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 6459fa064b..de8481b206 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -148,11 +148,18 @@ volatile int erts_break_requested = 0;
#define ERTS_SET_BREAK_REQUESTED (erts_break_requested = 1)
#define ERTS_UNSET_BREAK_REQUESTED (erts_break_requested = 0)
#endif
+
+#ifndef ERTS_SMP
+volatile Uint erts_signal_sigterm = 0;
+#define ERTS_SET_SIGNAL_SIGTERM (erts_signal_sigterm = 1)
+#define ERTS_CLEAR_SIGNAL_SIGTERM (erts_signal_sigterm = 0)
+#endif
+
/* set early so the break handler has access to initial mode */
static struct termios initial_tty_mode;
static int replace_intr = 0;
/* assume yes initially, ttsl_init will clear it */
-int using_oldshell = 1;
+int using_oldshell = 1;
#ifdef ERTS_ENABLE_KERNEL_POLL
@@ -684,11 +691,11 @@ static RETSIGTYPE request_stop(int signum)
#ifdef ERTS_SMP
smp_sig_notify('S');
#else
- stop_requested();
+ ERTS_SET_SIGNAL_SIGTERM;
+ ERTS_CHK_IO_AS_INTR();
#endif
}
-
static ERTS_INLINE void
sigusr1_exit(void)
{
@@ -784,10 +791,14 @@ 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);
+ /*
+ * Ignore signals that can be sent to the VM by
+ * typing certain key combinations at the
+ * controlling terminal...
+ */
+ sys_signal(SIGINT, SIG_IGN); /* Ctrl-C */
+ sys_signal(SIGQUIT, SIG_IGN); /* Ctrl-\ */
+ sys_signal(SIGTSTP, SIG_IGN); /* Ctrl-Z */
}
/* Don't use ctrl-c for break handler but let it be
@@ -811,7 +822,6 @@ 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 */
@@ -825,6 +835,17 @@ void sys_init_suspend_handler(void)
#endif
}
+void
+erts_sys_unix_later_init(void)
+{
+ char env[4];
+ size_t envsz = sizeof(env);
+ if (erts_sys_getenv_raw("ERL_ZZ_SIGTERM_KILL", env, &envsz) == 0)
+ if (envsz == 4 && sys_strncmp("true",env,4) == 0)
+ return;
+ sys_signal(SIGTERM, request_stop);
+}
+
int sys_max_files(void)
{
return(max_files);
@@ -958,6 +979,13 @@ void erts_do_break_handling(void)
erts_smp_thr_progress_unblock();
}
+#ifdef ERTS_SIGNAL_SIGTERM
+void erts_handle_signal_sigterm(void) {
+ ERTS_CLEAR_SIGNAL_SIGTERM;
+ stop_requested();
+}
+#endif
+
/* Fills in the systems representation of the jam/beam process identifier.
** The Pid is put in STRING representation in the supplied buffer,
** no interpretatione of this should be done by the rest of the
diff --git a/erts/emulator/sys/unix/sys_drivers.c b/erts/emulator/sys/unix/sys_drivers.c
index 400f163652..93cf64719a 100644
--- a/erts/emulator/sys/unix/sys_drivers.c
+++ b/erts/emulator/sys/unix/sys_drivers.c
@@ -204,6 +204,7 @@ erl_sys_late_init(void)
#ifdef ERTS_SMP
erts_mtx_unlock(port->lock);
#endif
+ erts_sys_unix_later_init(); /* Need to be called after forker has been started */
}
/* II. Prototypes */