diff --git a/hawk/lib/fnc.c b/hawk/lib/fnc.c index 21e6c84d..7c6ba4ec 100644 --- a/hawk/lib/fnc.c +++ b/hawk/lib/fnc.c @@ -405,7 +405,7 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) } } - n = hawk_rtx_closeio (rtx, name, opt); + n = hawk_rtx_closeio(rtx, name, opt); /* failure to close is not a critical error. instead, that is * flagged by the return value of close(). if (n <= -1 && rtx->errinf.num != HAWK_EIONMNF) @@ -430,7 +430,7 @@ static int flush_io (hawk_rtx_t* rtx, int rio, const hawk_ooch_t* name, int n) { int n2; - if (rtx->rio.handler[rio] != HAWK_NULL) + if (rtx->rio.handler[rio]) { n2 = hawk_rtx_flushio(rtx, rio, name); if (n2 <= -1) @@ -484,8 +484,8 @@ static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) { hawk_ooch_t* ptr, * end; - a0 = hawk_rtx_getarg (rtx, 0); - str0 = hawk_rtx_getvaloocstr (rtx, a0, &len0); + a0 = hawk_rtx_getarg(rtx, 0); + str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0); if (str0 == HAWK_NULL) return -1; /* the target name contains a null character. @@ -521,21 +521,13 @@ static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) * } */ - n = flush_io ( - rtx, HAWK_OUT_FILE, - ((len0 == 0)? HAWK_NULL: str0), 1); + n = flush_io(rtx, HAWK_OUT_FILE, ((len0 == 0)? HAWK_NULL: str0), 1); /*if (n == -99) return -1;*/ - n = flush_io ( - rtx, HAWK_OUT_APFILE, - ((len0 == 0)? HAWK_NULL: str0), n); + n = flush_io(rtx, HAWK_OUT_APFILE, ((len0 == 0)? HAWK_NULL: str0), n); /*if (n == -99) return -1;*/ - n = flush_io ( - rtx, HAWK_OUT_PIPE, - ((len0 == 0)? HAWK_NULL: str0), n); + n = flush_io(rtx, HAWK_OUT_PIPE, ((len0 == 0)? HAWK_NULL: str0), n); /*if (n == -99) return -1;*/ - n = flush_io ( - rtx, HAWK_OUT_RWPIPE, - ((len0 == 0)? HAWK_NULL: str0), n); + n = flush_io(rtx, HAWK_OUT_RWPIPE, ((len0 == 0)? HAWK_NULL: str0), n); /*if (n == -99) return -1;*/ /* if n remains 1, no io handlers have been defined for diff --git a/hawk/lib/rio-prv.h b/hawk/lib/rio-prv.h index bb44eacf..c3ee06cf 100644 --- a/hawk/lib/rio-prv.h +++ b/hawk/lib/rio-prv.h @@ -32,41 +32,42 @@ extern "C" { #endif int hawk_rtx_readio ( - hawk_rtx_t* run, int in_type, + hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk_ooecs_t* buf); int hawk_rtx_readiobytes ( - hawk_rtx_t* run, int in_type, + hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk_becs_t* buf); int hawk_rtx_writeioval ( - hawk_rtx_t* run, int out_type, + hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name, hawk_val_t* v); int hawk_rtx_writeiostr ( - hawk_rtx_t* run, int out_type, + hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name, hawk_ooch_t* str, hawk_oow_t len); int hawk_rtx_writeiobytes ( - hawk_rtx_t* run, int out_type, + hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name, hawk_bch_t* str, hawk_oow_t len); int hawk_rtx_flushio ( - hawk_rtx_t* run, int out_type, const hawk_ooch_t* name); + hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name); int hawk_rtx_nextio_read ( - hawk_rtx_t* run, int in_type, const hawk_ooch_t* name); + hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name); int hawk_rtx_nextio_write ( - hawk_rtx_t* run, int out_type, const hawk_ooch_t* name); + hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name); int hawk_rtx_closeio ( - hawk_rtx_t* run, + hawk_rtx_t* rtx, const hawk_ooch_t* name, const hawk_ooch_t* opt ); -void hawk_rtx_cleario (hawk_rtx_t* run); +void hawk_rtx_flushallios (hawk_rtx_t* rtx); +void hawk_rtx_clearallios (hawk_rtx_t* rtx); #if defined(__cplusplus) } diff --git a/hawk/lib/rio.c b/hawk/lib/rio.c index e1de7a9d..109eec8c 100644 --- a/hawk/lib/rio.c +++ b/hawk/lib/rio.c @@ -1039,7 +1039,7 @@ static int prepare_for_write_io_data (hawk_rtx_t* rtx, int out_type, const hawk_ io_mask = out_mask_map[out_type]; handler = rtx->rio.handler[io_type]; - if (handler == HAWK_NULL) + if (HAWK_UNLIKELY(!handler)) { /* no I/O handler provided */ hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOUSER); @@ -1067,12 +1067,12 @@ static int prepare_for_write_io_data (hawk_rtx_t* rtx, int out_type, const hawk_ if (p == HAWK_NULL) { p = (hawk_rio_arg_t*)hawk_rtx_allocmem(rtx, HAWK_SIZEOF(hawk_rio_arg_t)); - if (p == HAWK_NULL) return -1; + if (HAWK_UNLIKELY(!p)) return -1; HAWK_MEMSET (p, 0, HAWK_SIZEOF(*p)); p->name = hawk_rtx_dupoocstr(rtx, name, HAWK_NULL); - if (p->name == HAWK_NULL) + if (HAWK_UNLIKELY(!p->name)) { hawk_rtx_freemem (rtx, p); return -1; @@ -1422,7 +1422,7 @@ int hawk_rtx_closio_write (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* nam io_mask = out_mask_map[out_type]; handler = rtx->rio.handler[io_type]; - if (!handler) + if (HAWK_UNLIKELY(!handler)) { /* no io handler provided */ hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOUSER); @@ -1434,7 +1434,7 @@ int hawk_rtx_closio_write (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* nam if (p->type == (io_type | io_mask) && hawk_comp_oocstr(p->name, name, 0) == 0) { hawk_rio_impl_t handler; - + handler = rtx->rio.handler[p->type & IO_MASK_CLEAR]; if (handler && handler(rtx, HAWK_RIO_CMD_CLOSE, p, HAWK_NULL, 0) <= -1) return -1; @@ -1525,7 +1525,7 @@ int hawk_rtx_closeio (hawk_rtx_t* rtx, const hawk_ooch_t* name, const hawk_ooch_ } } - if (px != HAWK_NULL) px->next = p->next; + if (px) px->next = p->next; else rtx->rio.chain = p->next; hawk_rtx_freemem (rtx, p->name); @@ -1543,7 +1543,22 @@ int hawk_rtx_closeio (hawk_rtx_t* rtx, const hawk_ooch_t* name, const hawk_ooch_ return -1; } -void hawk_rtx_cleario (hawk_rtx_t* rtx) +void hawk_rtx_flushallios (hawk_rtx_t* rtx) +{ + hawk_rio_arg_t* rio; + hawk_rio_impl_t handler; + + for (rio = rtx->rio.chain; rio; rio = rio->next) + { + handler = rtx->rio.handler[rio->type & IO_MASK_CLEAR]; + if (handler) + { + handler (rtx, HAWK_RIO_CMD_FLUSH, rio, HAWK_NULL, 0); + } + } +} + +void hawk_rtx_clearallios (hawk_rtx_t* rtx) { hawk_rio_arg_t* next; hawk_rio_impl_t handler; diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 312f697c..40223c2e 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -1158,7 +1158,7 @@ static void fini_rtx (hawk_rtx_t* rtx, int fini_globals) /* close all pending io's */ /* TODO: what if this operation fails? */ - hawk_rtx_cleario (rtx); + hawk_rtx_clearallios (rtx); HAWK_ASSERT (rtx->rio.chain == HAWK_NULL); if (rtx->gbl.rs[0]) @@ -1672,8 +1672,8 @@ hawk_val_t* hawk_rtx_loop (hawk_rtx_t* rtx) /* reset the exit level */ rtx->exit_level = EXIT_NONE; - /* clear any pending io's */ - hawk_rtx_cleario (rtx); + /* flush all buffered io data */ + hawk_rtx_flushallios (rtx); return retv; } @@ -1829,8 +1829,8 @@ hawk_val_t* hawk_rtx_callfun (hawk_rtx_t* rtx, hawk_fun_t* fun, hawk_val_t* args hawk_rtx_refupval (rtx, v); } - /* clear any pending io's */ - hawk_rtx_cleario (rtx); + /* flush all buffered io data */ + hawk_rtx_flushallios (rtx); /* return the return value with its reference count at least 1. * the caller of this function should count down its reference. */ diff --git a/hawk/lib/std.c b/hawk/lib/std.c index e6b0889f..0da89358 100644 --- a/hawk/lib/std.c +++ b/hawk/lib/std.c @@ -2020,7 +2020,19 @@ static hawk_ooi_t awk_rio_file (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_ar return hawk_sio_putbchars((hawk_sio_t*)riod->handle, data, size); case HAWK_RIO_CMD_FLUSH: - return hawk_sio_flush((hawk_sio_t*)riod->handle); + { + int n; + + n = hawk_sio_flush((hawk_sio_t*)riod->handle); + if (HAWK_UNLIKELY(n <= -1)) + { + /* if flushing fails, discard the buffered data + * keeping the unflushed data causes causes subsequent write or close() to + * flush again and again */ + hawk_sio_drain ((hawk_sio_t*)riod->handle); + } + return n; + } case HAWK_RIO_CMD_NEXT: return -1; @@ -2376,7 +2388,19 @@ static hawk_ooi_t awk_rio_console (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio return hawk_sio_putbchars((hawk_sio_t*)riod->handle, data, size); case HAWK_RIO_CMD_FLUSH: - return hawk_sio_flush((hawk_sio_t*)riod->handle); + { + int n; + + n = hawk_sio_flush((hawk_sio_t*)riod->handle); + if (HAWK_UNLIKELY(n <= -1)) + { + /* if flushing fails, discard the buffered data + * keeping the unflushed data causes causes subsequent write or close() to + * flush again and again */ + hawk_sio_drain ((hawk_sio_t*)riod->handle); + } + return n; + } case HAWK_RIO_CMD_NEXT: {