}
+/***********************************************
+* Handler for SIGSEGV *
+***********************************************/
+
+static void
+segv_handler(int sig)
+{
+log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (maybe attempt to write to immutable memory)");
+signal(SIGSEGV, SIG_DFL);
+kill(getpid(), sig);
+}
+
+
/*************************************************
* Handler for SIGUSR1 *
*************************************************/
clocks that go backwards.
Arguments:
- tgt_tv A timeval which was used to create uniqueness; its usec field
+ prev_tv A timeval which was used to create uniqueness; its usec field
has been rounded down to the value of the resolution.
We want to be sure the current time is greater than this.
+ On return, updated to current (rounded down).
resolution The resolution that was used to divide the microseconds
(1 for maildir, larger for message ids)
*/
void
-exim_wait_tick(struct timeval * tgt_tv, int resolution)
+exim_wait_tick(struct timeval * prev_tv, int resolution)
{
struct timeval now_tv;
long int now_true_usec;
now_true_usec = now_tv.tv_usec;
now_tv.tv_usec = (now_true_usec/resolution) * resolution;
-while (exim_tvcmp(&now_tv, tgt_tv) <= 0)
+while (exim_tvcmp(&now_tv, prev_tv) <= 0)
{
struct itimerval itval;
itval.it_interval.tv_sec = 0;
itval.it_interval.tv_usec = 0;
- itval.it_value.tv_sec = tgt_tv->tv_sec - now_tv.tv_sec;
- itval.it_value.tv_usec = tgt_tv->tv_usec + resolution - now_true_usec;
+ itval.it_value.tv_sec = prev_tv->tv_sec - now_tv.tv_sec;
+ itval.it_value.tv_usec = prev_tv->tv_usec + resolution - now_true_usec;
/* We know that, overall, "now" is less than or equal to "then". Therefore, a
negative value for the microseconds is possible only in the case when "now"
if (!f.running_in_test_harness)
{
debug_printf("tick check: " TIME_T_FMT ".%06lu " TIME_T_FMT ".%06lu\n",
- tgt_tv->tv_sec, (long) tgt_tv->tv_usec,
+ prev_tv->tv_sec, (long) prev_tv->tv_usec,
now_tv.tv_sec, (long) now_tv.tv_usec);
debug_printf("waiting " TIME_T_FMT ".%06lu sec\n",
itval.it_value.tv_sec, (long) itval.it_value.tv_usec);
now_true_usec = now_tv.tv_usec;
now_tv.tv_usec = (now_true_usec/resolution) * resolution;
}
+*prev_tv = now_tv;
}
BOOL list_options = FALSE;
BOOL list_config = FALSE;
BOOL local_queue_only;
-BOOL more = TRUE;
BOOL one_msg_action = FALSE;
BOOL opt_D_used = FALSE;
BOOL queue_only_set = FALSE;
process_info = store_get(PROCESS_INFO_SIZE, TRUE); /* tainted */
set_process_info("initializing");
-os_restarting_signal(SIGUSR1, usr1_handler);
+os_restarting_signal(SIGUSR1, usr1_handler); /* exiwhat */
+signal(SIGSEGV, segv_handler); /* log faults */
/* If running in a dockerized environment, the TERM signal is only
delegated to the PID 1 if we request it by setting an signal handler */
{
struct rlimit rlp;
- #ifdef RLIMIT_NOFILE
+#ifdef RLIMIT_NOFILE
if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
{
log_write(0, LOG_MAIN|LOG_PANIC, "getrlimit(RLIMIT_NOFILE) failed: %s",
strerror(errno));
}
}
- #endif
+#endif
- #ifdef RLIMIT_NPROC
+#ifdef RLIMIT_NPROC
if (getrlimit(RLIMIT_NPROC, &rlp) < 0)
{
log_write(0, LOG_MAIN|LOG_PANIC, "getrlimit(RLIMIT_NPROC) failed: %s",
rlp.rlim_cur = rlp.rlim_max = 0;
}
- #ifdef RLIM_INFINITY
+# ifdef RLIM_INFINITY
if (rlp.rlim_cur != RLIM_INFINITY && rlp.rlim_cur < 1000)
{
rlp.rlim_cur = rlp.rlim_max = RLIM_INFINITY;
- #else
+# else
if (rlp.rlim_cur < 1000)
{
rlp.rlim_cur = rlp.rlim_max = 1000;
- #endif
+# endif
if (setrlimit(RLIMIT_NPROC, &rlp) < 0)
log_write(0, LOG_MAIN|LOG_PANIC, "setrlimit(RLIMIT_NPROC) failed: %s",
strerror(errno));
}
- #endif
+#endif
}
/* Exim is normally entered as root (but some special configurations are
This needs to happen before we read the main configuration. */
init_lookup_list();
+/*XXX this excrescence could move to the testsuite standard config setup file */
#ifdef SUPPORT_I18N
if (f.running_in_test_harness) smtputf8_advertise_hosts = NULL;
#endif
defined) */
{
+ int old_pool = store_pool;
#ifdef MEASURE_TIMING
struct timeval t0, diff;
(void)gettimeofday(&t0, NULL);
#endif
+ store_pool = POOL_CONFIG;
readconf_main(checking || list_options);
+ store_pool = old_pool;
#ifdef MEASURE_TIMING
report_time_since(&t0, US"readconf_main (delta)");
#endif
}
-
/* Now in directory "/" */
if (cleanup_environment() == FALSE)
event_action gets expanded */
if (msg_action == MSG_REMOVE)
+ {
+ int old_pool = store_pool;
+ store_pool = POOL_CONFIG;
readconf_rest();
+ store_pool = old_pool;
+ store_writeprotect(POOL_CONFIG);
+ }
if (!one_msg_action)
{
needed in transports so we lost the optimisation. */
{
+ int old_pool = store_pool;
#ifdef MEASURE_TIMING
struct timeval t0, diff;
(void)gettimeofday(&t0, NULL);
#endif
+ store_pool = POOL_CONFIG;
readconf_rest();
+ store_pool = old_pool;
+ store_writeprotect(POOL_CONFIG);
#ifdef MEASURE_TIMING
report_time_since(&t0, US"readconf_rest (delta)");
if (!f.synchronous_delivery)
{
- #ifdef SA_NOCLDWAIT
+#ifdef SA_NOCLDWAIT
struct sigaction act;
act.sa_handler = SIG_IGN;
sigemptyset(&(act.sa_mask));
act.sa_flags = SA_NOCLDWAIT;
sigaction(SIGCHLD, &act, NULL);
- #else
+#else
signal(SIGCHLD, SIG_IGN);
- #endif
+#endif
}
/* Save the current store pool point, for resetting at the start of
messages to be read (SMTP input), or FALSE otherwise (not SMTP, or SMTP channel
collapsed). */
-while (more)
+for (BOOL more = TRUE; more; )
{
rmark reset_point = store_mark();
message_id[0] = 0;
/* Now get the data for the message */
more = receive_msg(extract_recipients);
- if (message_id[0] == 0)
+ if (!message_id[0])
{
cancel_cutthrough_connection(TRUE, US"receive dropped");
- if (more) goto moreloop;
+ if (more) goto MORELOOP;
smtp_log_no_mail(); /* Log no mail if configured */
exim_exit(EXIT_FAILURE);
}
parse_extract_address(s, &errmess, &start, &end, &domain, FALSE);
#ifdef SUPPORT_I18N
- if (string_is_utf8(recipient))
- message_smtputf8 = TRUE;
- else
- allow_utf8_domains = b;
+ if (recipient)
+ if (string_is_utf8(recipient)) message_smtputf8 = TRUE;
+ else allow_utf8_domains = b;
}
+#else
+ ;
#endif
if (domain == 0 && !f.allow_unqualified_recipient)
{
for real; when reading the headers of a message for filter testing,
it is TRUE if the headers were terminated by '.' and FALSE otherwise. */
- if (message_id[0] == 0) exim_exit(EXIT_FAILURE);
+ if (!message_id[0]) exim_exit(EXIT_FAILURE);
} /* Non-SMTP message reception */
/* If this is a filter testing run, there are headers in store, but
finished subprocesses here, in case there are lots of messages coming in
from the same source. */
- #ifndef SIG_IGN_WORKS
+#ifndef SIG_IGN_WORKS
while (waitpid(-1, NULL, WNOHANG) > 0);
- #endif
+#endif
-moreloop:
+MORELOOP:
return_path = sender_address = NULL;
authenticated_sender = NULL;
deliver_localpart_orig = NULL;