diff options
Diffstat (limited to 'byterun')
| -rw-r--r-- | byterun/interp.c | 6 | ||||
| -rw-r--r-- | byterun/io.c | 9 | ||||
| -rw-r--r-- | byterun/signals.c | 8 | ||||
| -rw-r--r-- | byterun/sys.c | 9 |
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) |
