/* Our nb input read callback */ static void f__input_read_cb(INT32 args) { int avail_size = 0, len; struct pike_string *str; input *inp = THIS->inputs; if(inp == NULL) { Pike_error("Input read callback without inputs."); } if(args != 2) Pike_error("Invalid number of arguments to read callback."); if(ARG(2).type != T_STRING) { SIMPLE_BAD_ARG_ERROR("_Caudium.nbio()->_input_read_cb", 2, "string"); } str = ARG(2).u.string; len = str->len << str->size_shift; inp->pos += len; if(inp->len != -1 && inp->pos >= inp->len) { len -= inp->pos - inp->len; /* Don't "read" too much */ DERR(fprintf(stderr, "Read all wanted input data.\n")); free_input(inp); } DERR(fprintf(stderr, "Input read callback (got %d bytes).\n", len)); if(THIS->buf_size) { avail_size = THIS->buf_size - (THIS->buf_len + THIS->buf_pos); } if(avail_size < len) { alloc_data_buf(THIS->buf_size + (len - avail_size)); } DERR(fprintf(stderr, "Copying %d bytes to buf starting at 0x%x (pos %d).\n", len, (int)(THIS->buf + THIS->buf_pos + THIS->buf_len), THIS->buf_pos + THIS->buf_len)); memcpy(THIS->buf + THIS->buf_pos + THIS->buf_len, str->str, len); THIS->buf_len += len; if((THIS->buf_len + THIS->buf_pos) > READ_BUFFER_SIZE) { DERR(fprintf(stderr, "Read buffer full (%d bytes).\n", THIS->buf_size)); push_int(0); push_int(0); push_int(0); apply_low(inp->u.file, inp->set_nb_off, 3); pop_stack(); inp->mode = SLEEPING; } pop_n_elems(args); if(THIS->outp->mode == IDLE) { DERR(fprintf(stderr, "Waking up output.\n")); THIS->outp->mode = ACTIVE; f__output_write_cb(0); } else { DERR(fprintf(stderr, "Output is awake.\n")); } }
static void *send_thread_main(void *p) { while (true) { int sock = await_sender_socket(); size_t buf_size = 0; char *buf = alloc_data_buf(sock, &buf_size); while (true) { ssize_t nr = read(sock, buf, buf_size); if (nr < 0) { report_sender_error(LOG_ERR, "read from sender failed"); break; // XXX stop daemon and clean up } if (nr == 0) { syslog(LOG_INFO, "EOF on sender"); break; // XXX stop daemon and clean up } if (whatever_transmit(buf, nr)) report_sender_error(LOG_ERR, "serial transmit failed"); } free(buf); disconnect_sender(NULL); } return NULL; }
/* This function reads some data from the current input (file object) */ static INLINE int read_data(void) { int buf_size = READ_BUFFER_SIZE; NBIO_INT_T to_read = 0; char *rd; input *inp; redo: DERR(fprintf(stderr, "Reading from blocking input.\n")); THIS->buf_pos = 0; inp = THIS->inputs; if(inp == NULL) return -1; /* No more inputs */ if(inp->type != NBIO_BLOCK_OBJ) return -2; /* invalid input for read_data */ if(inp->fd != -1) { char * ptr; DERR(fprintf(stderr, "Reading from real fd.\n")); if(inp->len != -1) to_read = MIN(buf_size, inp->len - inp->pos); else to_read = buf_size; if(THIS->buf == NULL || THIS->buf_size < to_read) { alloc_data_buf(to_read); } ptr = THIS->buf; THREADS_ALLOW(); to_read = fd_read(inp->fd, ptr, to_read); THREADS_DISALLOW(); DERR(fprintf(stderr, "read %ld from file\n", (long)to_read)); } else { DERR(fprintf(stderr, "Reading from fake fd.\n")); if(inp->len != -1 && inp->pos >= inp->len) { /* We are done reading from this one */ DERR(fprintf(stderr, "Data done from fake fd.\n")); free_input(inp); goto redo; /* goto == ugly, but we want to read the next input * if any */ } to_read = READ_BUFFER_SIZE; push_int(to_read); push_int(1); apply_low(inp->u.file, inp->read_off, 2); if(Pike_sp[-1].type == T_STRING) { if(Pike_sp[-1].u.string->len == 0) { DERR(fprintf(stderr, "Read zero bytes from fake fd (EOF).\n")); to_read = 0; } else { new_input(Pike_sp[-1], 0, 1); to_read = THIS->inputs->len; inp->pos += to_read; DERR(fprintf(stderr, "read %ld bytes from fake file\n", (long)to_read)); pop_stack(); return -3; /* Got a string buffer appended to the input list */ } } else if(Pike_sp[-1].type == T_INT && Pike_sp[-1].u.integer == 0) { to_read = 0; } else { Pike_error("Incorrect result from read, expected string.\n"); } pop_stack(); } switch(to_read) { case 0: /* EOF */ DERR(fprintf(stderr, "read zero blocking bytes == EOF\n")); free_input(inp); break; case -1: if(errno != EAGAIN) { /* Got an error. Free input and continue */ DERR(perror("Error while reading:")); free_input(inp); } goto redo; default: inp->pos += to_read; if(inp->pos == inp->len) { DERR(fprintf(stderr, "Done reading (position == length).\n")); free_input(inp); } THIS->buf_len = to_read; break; } return to_read; }