Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add in linebuffering logic, stolen in all it's hacky glory from the o…

…ld system. Set up block buffering on stdin and line buffering on stdout. Make sure to flush stdout on io finish so we don't lose any data if we exit without having written a final newline.
  • Loading branch information...
commit 2037433553cdb010efbc730a640d37bcd6aea4e6 1 parent de4b042
@Whiteknight Whiteknight authored
View
5 include/parrot/io.h
@@ -573,9 +573,6 @@ IO_VTABLE * Parrot_io_get_vtable(PARROT_INTERP,
ARGIN_NULLOK(const char * name))
__attribute__nonnull__(1);
-void Parrot_io_init_buffer(PARROT_INTERP)
- __attribute__nonnull__(1);
-
PARROT_WARN_UNUSED_RESULT
PIOOFF_T Parrot_io_make_offset_pmc(PARROT_INTERP, ARGMOD(PMC *pmc))
__attribute__nonnull__(1)
@@ -749,8 +746,6 @@ INTVAL Parrot_io_write_byte_buffer_pmc(PARROT_INTERP,
, PARROT_ASSERT_ARG(handle))
#define ASSERT_ARGS_Parrot_io_get_vtable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_io_init_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_io_make_offset_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pmc))
View
2  src/dynext.c
@@ -651,7 +651,7 @@ Parrot_dyn_load_lib(PARROT_INTERP,
ARGIN_NULLOK(PMC *parameters))
{
ASSERT_ARGS(Parrot_dyn_load_lib)
- /* NULL intializa handle to protect against pitfalls in called functions.
+ /* NULL intialize handle to protect against pitfalls in called functions.
* This function should not be so speed critical that this has any impact.
*/
void *handle = NULL;
View
30 src/io/api.c
@@ -65,16 +65,19 @@ Parrot_io_init(PARROT_INTERP)
/* memsub system is up and running: */
/* Init IO stacks and handles for interp instance. */
PIOHANDLE os_handle;
+ PMC *handle;
io_setup_vtables(interp);
- os_handle = Parrot_io_internal_std_os_handle(interp, PIO_STDIN_FILENO);
- _PIO_STDIN(interp) = Parrot_io_fdopen_flags(interp, PMCNULL,
- os_handle, PIO_F_READ);
+ os_handle = Parrot_io_internal_std_os_handle(interp, PIO_STDIN_FILENO);
+ handle = Parrot_io_fdopen_flags(interp, PMCNULL, os_handle, PIO_F_READ);
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_READ_BUFFER, BUFFER_SIZE_ANY, PIO_F_BLKBUF);
+ _PIO_STDIN(interp) = handle;
- os_handle = Parrot_io_internal_std_os_handle(interp, PIO_STDOUT_FILENO);
- _PIO_STDOUT(interp) = Parrot_io_fdopen_flags(interp, PMCNULL,
- os_handle, PIO_F_WRITE);
+ os_handle = Parrot_io_internal_std_os_handle(interp, PIO_STDOUT_FILENO);
+ handle = Parrot_io_fdopen_flags(interp, PMCNULL, os_handle, PIO_F_WRITE);
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY, PIO_F_LINEBUF);
+ _PIO_STDOUT(interp) = handle;
os_handle = Parrot_io_internal_std_os_handle(interp, PIO_STDERR_FILENO);
_PIO_STDERR(interp) = Parrot_io_fdopen_flags(interp, PMCNULL,
@@ -100,20 +103,6 @@ Parrot_io_init(PARROT_INTERP)
}
void
-Parrot_io_init_buffer(PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_io_init_buffer)
-
- // TODO: Merge this buffering logic into where-ever we set up these handles
- /*if (Parrot_io_STDOUT(interp))
- Parrot_io_setlinebuf(interp, Parrot_io_STDOUT(interp));
-
- if (Parrot_io_STDIN(interp))
- Parrot_io_setbuf(interp, Parrot_io_STDIN(interp), PIO_UNBOUND);
- */
-}
-
-void
io_setup_vtables(PARROT_INTERP)
{
ASSERT_ARGS(io_setup_vtables);
@@ -188,6 +177,7 @@ Parrot_io_finish(PARROT_INTERP)
/*
* TODO free IO of std-handles
*/
+ Parrot_io_flush(interp, _PIO_STDOUT(interp));
mem_gc_free(interp, interp->piodata->table);
interp->piodata->table = NULL;
mem_gc_free(interp, interp->piodata);
View
20 src/io/buffer.c
@@ -111,6 +111,7 @@ Parrot_io_buffer_add_to_handle(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL idx,
Parrot_io_buffer_resize(interp, buffer, length);
else {
buffer = Parrot_io_buffer_allocate(interp, handle, flags, NULL, length);
+ PARROT_ASSERT(buffer);
VTABLE_set_pointer_keyed_int(interp, handle, idx, buffer);
}
if (flags != BUFFER_FLAGS_ANY)
@@ -280,13 +281,30 @@ Parrot_io_buffer_write_b(PARROT_INTERP, ARGMOD_NULLOK(IO_BUFFER *buffer),
size_t total_size = buffer->buffer_size;
size_t used_size = BUFFER_USED_SIZE(buffer);
size_t avail_size = BUFFER_AVAILABLE_SIZE(buffer);
+ INTVAL needs_flush = 0;
+
+ /* This is something of an ugly hack, ported from the old system. We
+ do this because stdhandles don't automatically flush and data
+ written can be lost if the program exits too early. */
+ if (buffer->flags & PIO_F_LINEBUF) {
+ size_t i;
+ for (i = 0; i < length; i++) {
+ if (s[i] == '\n') {
+ needs_flush = 1;
+ break;
+ }
+ }
+ }
/* If the data fits in the buffer, copy it there and move on. */
if (length <= avail_size) {
io_buffer_add_bytes(interp, buffer, s, length);
+ if (needs_flush)
+ Parrot_io_buffer_flush(interp, buffer, handle, vtable, 0);
return length;
}
+
/* If the total data to write is larger than the buffer, flush and
write directly through to the handle */
if (length > total_size) {
@@ -298,6 +316,8 @@ Parrot_io_buffer_write_b(PARROT_INTERP, ARGMOD_NULLOK(IO_BUFFER *buffer),
be able to cover any overflow */
Parrot_io_buffer_flush(interp, buffer, handle, vtable, 0);
io_buffer_add_bytes(interp, buffer, s, length);
+ if (needs_flush)
+ Parrot_io_buffer_flush(interp, buffer, handle, vtable, 0);
return length;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.