On Thursday 11 December 2008 06:14:36 François PERRAD wrote: > Since the merge of the branch ppd22io, the mode of the stdin stream has > changed. Currently, it isn't possible to peek on stdin. > > $ cat peek.pir > .sub 'main' > $P0 = getstdin > $S0 = peek $S0 > .end > > $ ./parrot peek.pir < peek.pir > Can't peek at unbuffered I/O > > The issue was detected with I/O library of Lua (see > languages/lua/t/io.t#17).
We should support this; how about upgrading the IO PMC to buffered reads when we detect a peek? Here's a patch that makes the test pass for me. Any objections, anyone else? -- c
=== src/io/buffer.c ================================================================== --- src/io/buffer.c (revision 34326) +++ src/io/buffer.c (local) @@ -395,14 +395,12 @@ Parrot_io_peek_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle), ARGOUT(STRING **buf)) { - UINTVAL len = 1; - size_t avail = 0; - + unsigned char *buffer_next, *buffer_end; + STRING * const s = Parrot_io_make_string(interp, buf, 1); + UINTVAL len = 1; + size_t avail = 0; INTVAL buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle); - unsigned char *buffer_next, *buffer_end; - STRING * const s = Parrot_io_make_string(interp, buf, 1); - /* write buffer flush */ if (buffer_flags & PIO_BF_WRITEBUF) { Parrot_io_flush(interp, filehandle); @@ -419,7 +417,7 @@ /* if we have data available, copy out the next byte */ if (avail) { ret_string: - memcpy(s->strstart, buffer_next, len); + memmove(s->strstart, buffer_next, len); s->bufused = s->strlen = len; return len; } @@ -428,11 +426,13 @@ /* (re)fill the buffer */ if (! (buffer_flags & PIO_BF_READBUF)) { size_t got; - /* exception if we're unbuffered */ - if (Parrot_io_get_buffer_size(interp, filehandle) == 0) - Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, - "Can't peek at unbuffered I/O"); + /* promote to buffered if unbuffered */ + if (Parrot_io_get_buffer_size(interp, filehandle) == 0) { + Parrot_io_setbuf(interp, filehandle, 1); + return Parrot_io_peek_buffer(interp, filehandle, buf); + } + /* Parrot_io_fill_readbuf() can return -1, but len should be positive */ got = Parrot_io_fill_readbuf(interp, filehandle); @@ -449,6 +449,7 @@ goto ret_string; } + /* =item C<size_t Parrot_io_readline_buffer> === src/io/portable.c ================================================================== --- src/io/portable.c (revision 34326) +++ src/io/portable.c (local) @@ -170,7 +170,7 @@ =item C<PMC * Parrot_io_fdopen_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -204,7 +204,7 @@ =item C<INTVAL Parrot_io_close_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -245,7 +245,7 @@ =item C<static INTVAL io_is_tty_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -297,7 +297,7 @@ =item C<INTVAL Parrot_io_getblksize_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -317,7 +317,7 @@ =item C<INTVAL Parrot_io_flush_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -334,7 +334,7 @@ =item C<size_t Parrot_io_read_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -368,7 +368,7 @@ =item C<size_t Parrot_io_write_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -386,7 +386,7 @@ =item C<PIOOFF_T Parrot_io_seek_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut @@ -413,7 +413,7 @@ =item C<PIOOFF_T Parrot_io_tell_portable> -RT#48260: Not yet documented!!! +RT #48260: Not yet documented!!! =cut