summaryrefslogtreecommitdiff
path: root/byterun
diff options
context:
space:
mode:
Diffstat (limited to 'byterun')
-rw-r--r--byterun/interp.c6
-rw-r--r--byterun/io.c9
-rw-r--r--byterun/signals.c8
-rw-r--r--byterun/sys.c9
4 files changed, 24 insertions, 8 deletions
diff --git a/byterun/interp.c b/byterun/interp.c
index 599218e487..aed6c053f5 100644
--- a/byterun/interp.c
+++ b/byterun/interp.c
@@ -790,13 +790,13 @@ value interprete(code_t prog, asize_t prog_size)
raise_exception:
if (trapsp >= trap_barrier) debugger(TRAP_BARRIER);
if (backtrace_active) stash_backtrace(accu, pc, sp);
- sp = trapsp;
- if ((char *) sp >= (char *) stack_high - initial_sp_offset) {
+ if ((char *) trapsp >= (char *) stack_high - initial_sp_offset) {
external_raise = initial_external_raise;
- extern_sp = sp;
+ extern_sp = (value *) ((char *) stack_high - initial_sp_offset);
callback_depth--;
return Make_exception_result(accu);
}
+ sp = trapsp;
pc = Trap_pc(sp);
trapsp = Trap_link(sp);
env = sp[2];
diff --git a/byterun/io.c b/byterun/io.c
index f473ce7d2b..85f162aa23 100644
--- a/byterun/io.c
+++ b/byterun/io.c
@@ -172,12 +172,19 @@ again:
/* Attempt to flush the buffer. This will make room in the buffer for
at least one character. Returns true if the buffer is empty at the
- end of the flush, or false if some data remains in the buffer. */
+ end of the flush, or false if some data remains in the buffer.
+
+ If the channel is closed, DO NOT raise a "bad file descriptor"
+ exception, but do nothing (the buffer is already empty). See
+ the "at_exit" line of stdlib/format.ml for a good reason to avoid
+ the exception.
+ */
CAMLexport int flush_partial(struct channel *channel)
{
int towrite, written;
+ if (channel->fd == -1) return 1;
towrite = channel->curr - channel->buff;
if (towrite > 0) {
written = do_write(channel->fd, channel->buff, towrite);
diff --git a/byterun/signals.c b/byterun/signals.c
index 727b87aff7..6fce2115a3 100644
--- a/byterun/signals.c
+++ b/byterun/signals.c
@@ -134,16 +134,20 @@ CAMLexport void enter_blocking_section(void)
CAMLexport void leave_blocking_section(void)
{
#ifdef _WIN32
+ int signal_number;
+#endif
+
+ if (leave_blocking_section_hook != NULL) leave_blocking_section_hook();
+#ifdef _WIN32
/* Under Win32, asynchronous signals such as ctrl-C are not processed
immediately (see ctrl_handler in win32.c), but simply set
pending_signal and let the system call run to completion.
Hence, test pending_signal here and act upon it, before we get
a chance to process the result of the system call. */
- int signal_number = pending_signal;
+ signal_number = pending_signal;
pending_signal = 0;
if (signal_number) execute_signal(signal_number, 1);
#endif
- if (leave_blocking_section_hook != NULL) leave_blocking_section_hook();
Assert(async_signal_mode);
async_signal_mode = 0;
}
diff --git a/byterun/sys.c b/byterun/sys.c
index f82fce4b3f..6ac6cdbce7 100644
--- a/byterun/sys.c
+++ b/byterun/sys.c
@@ -302,13 +302,18 @@ CAMLprim value sys_time(value unit)
CAMLprim value sys_random_seed (value unit)
{
+ long seed;
#ifdef HAS_GETTIMEOFDAY
struct timeval tv;
gettimeofday(&tv, NULL);
- return Val_int(tv.tv_sec ^ tv.tv_usec);
+ seed = tv.tv_sec ^ tv.tv_usec;
#else
- return Val_int(time (NULL));
+ seed = time (NULL);
#endif
+#ifdef HAS_UNISTD
+ seed ^= getppid() << 16 | getpid();
+#endif
+ return Val_long(seed);
}
CAMLprim value sys_get_config(value unit)