// Callback invoked by libuv after it copies the data into the buffer provided // by `alloc_cb`. This is also called on EOF or when `alloc_cb` returns a // 0-length buffer. static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf) { RStream *rstream = stream->data; if (cnt <= 0) { if (cnt != UV_ENOBUFS) { // Read error or EOF, either way stop the stream and invoke the callback // with eof == true uv_read_stop(stream); emit_read_event(rstream, true); } return; } // at this point we're sure that cnt is positive, no error occurred size_t nread = (size_t) cnt; // Data was already written, so all we need is to update 'wpos' to reflect // the space actually used in the buffer. rstream->wpos += nread; if (rstream->wpos == rstream->buffer_size) { // The last read filled the buffer, stop reading for now rstream_stop(rstream); } rstream->reading = false; emit_read_event(rstream, false); }
// Stop listening for input void input_stop(void) { if (embedded_mode) { return; } rstream_stop(read_stream); }
void input_stop(void) { if (read_stream.closed) { return; } rstream_stop(&read_stream); stream_close(&read_stream, NULL); }
void input_stop_stdin(void) { if (!read_stream) { return; } rstream_stop(read_stream); rstream_free(read_stream); read_stream = NULL; }
/// Advances `rbuffer` write pointers. If the internal buffer becomes full, /// this will stop the associated RStream instance. void rbuffer_produced(RBuffer *rbuffer, size_t count) { rbuffer->wpos += count; DLOG("Received %u bytes from RStream(%p)", (size_t)count, rbuffer->rstream); rbuffer_relocate(rbuffer); if (rbuffer->rstream && rbuffer->wpos == rbuffer->capacity) { // The last read filled the buffer, stop reading for now // rstream_stop(rbuffer->rstream); DLOG("Buffer for RStream(%p) is full, stopping it", rbuffer->rstream); } }
static void stderr_switch() { int mode = cur_tmode; // We probably set the wrong file descriptor to raw mode. Switch back to // cooked mode settmode(TMODE_COOK); // Stop the idle handle rstream_stop(read_stream); // Use stderr for stdin, also works for shell commands. read_cmd_fd = 2; // Initialize and start the input stream rstream_set_file(read_stream, read_cmd_fd); rstream_start(read_stream); // Set the mode back to what it was settmode(mode); }
// Called by the by the 'idle' handle to emulate a reading event static void fread_idle_cb(uv_idle_t *handle) { uv_fs_t req; RStream *rstream = handle->data; rstream->uvbuf.base = rstream->buffer + rstream->wpos; rstream->uvbuf.len = rstream->buffer_size - rstream->wpos; // the offset argument to uv_fs_read is int64_t, could someone really try // to read more than 9 quintillion (9e18) bytes? // upcast is meant to avoid tautological condition warning on 32 bits uintmax_t fpos_intmax = rstream->fpos; assert(fpos_intmax <= INT64_MAX); // Synchronous read uv_fs_read( uv_default_loop(), &req, rstream->fd, &rstream->uvbuf, 1, (int64_t) rstream->fpos, NULL); uv_fs_req_cleanup(&req); if (req.result <= 0) { uv_idle_stop(rstream->fread_idle); emit_read_event(rstream, true); return; } // no errors (req.result (ssize_t) is positive), it's safe to cast. size_t nread = (size_t) req.result; rstream->wpos += nread; rstream->fpos += nread; if (rstream->wpos == rstream->buffer_size) { // The last read filled the buffer, stop reading for now rstream_stop(rstream); } emit_read_event(rstream, false); }
// Called by the by the 'idle' handle to emulate a reading event static void fread_idle_cb(uv_idle_t *handle) { uv_fs_t req; RStream *rstream = handle->data; rstream->uvbuf.base = rstream->buffer + rstream->wpos; rstream->uvbuf.len = rstream->buffer_size - rstream->wpos; // the offset argument to uv_fs_read is int64_t, could someone really try // to read more than 9 quintillion (9e18) bytes? // DISABLED TO FIX BROKEN BUILD ON 32bit // TODO(elmart): Review types to allow assertion // assert(rstream->fpos <= INT64_MAX); // Synchronous read uv_fs_read( uv_default_loop(), &req, rstream->fd, &rstream->uvbuf, 1, (int64_t) rstream->fpos, NULL); uv_fs_req_cleanup(&req); if (req.result <= 0) { uv_idle_stop(rstream->fread_idle); emit_read_event(rstream, true); return; } // no errors (req.result (ssize_t) is positive), it's safe to cast. size_t nread = (size_t) req.result; rstream->wpos += nread; rstream->fpos += nread; if (rstream->wpos == rstream->buffer_size) { // The last read filled the buffer, stop reading for now rstream_stop(rstream); } emit_read_event(rstream, false); }
// Stop listening for input void input_stop() { rstream_stop(read_stream); }