static isc_result_t read_more(perf_datafile_t *dfile) { unsigned char *data; size_t size; ssize_t n; isc_result_t result; if (!dfile->is_file && dfile->pipe_fd >= 0) { result = perf_os_waituntilreadable(dfile->fd, dfile->pipe_fd, -1); if (result != ISC_R_SUCCESS) return (result); } isc_buffer_compact(&dfile->data); data = isc_buffer_used(&dfile->data); size = isc_buffer_availablelength(&dfile->data); n = read(dfile->fd, data, size); if (n < 0) return (ISC_R_FAILURE); isc_buffer_add(&dfile->data, n); nul_terminate(dfile); if (dfile->is_file && isc_buffer_usedlength(&dfile->data) == dfile->size) dfile->cached = ISC_TRUE; return (ISC_R_SUCCESS); }
perf_datafile_t * perf_datafile_open(isc_mem_t *mctx, const char *filename) { perf_datafile_t *dfile; struct stat buf; dfile = isc_mem_get(mctx, sizeof(*dfile)); if (dfile == NULL) perf_log_fatal("out of memory"); dfile->mctx = mctx; MUTEX_INIT(&dfile->lock); dfile->pipe_fd = -1; dfile->is_file = ISC_FALSE; dfile->size = 0; dfile->cached = ISC_FALSE; dfile->maxruns = 1; dfile->nruns = 0; dfile->read_any = ISC_FALSE; isc_buffer_init(&dfile->data, dfile->databuf, BUFFER_SIZE); if (filename == NULL) { dfile->fd = STDIN_FILENO; } else { dfile->fd = open(filename, O_RDONLY); if (dfile->fd < 0) perf_log_fatal("unable to open file: %s", filename); if (fstat(dfile->fd, &buf) == 0 && S_ISREG(buf.st_mode)) { dfile->is_file = ISC_TRUE; dfile->size = buf.st_size; } } nul_terminate(dfile); return dfile; }
static void reopen_file(perf_datafile_t *dfile) { if (dfile->cached) { isc_buffer_first(&dfile->data); } else { if (lseek(dfile->fd, 0L, SEEK_SET) < 0) perf_log_fatal("cannot reread input"); isc_buffer_clear(&dfile->data); nul_terminate(dfile); } }
/* Check if the file DIRNAME really exists. Get the size and save it in FILEMAX. */ int tftp_dir (char *dirname) { int ch; #ifdef TFTP_DEBUG grub_printf ("tftp_dir (%s)\n", dirname); #endif /* In TFTP, there is no way to know what files exist. */ if (print_possibilities) return 1; /* Don't know the size yet. */ filemax = -1; reopen: /* Construct the TFTP request packet. */ tp.opcode = htons (TFTP_RRQ); /* Terminate the filename. */ ch = nul_terminate (dirname); /* Make the request string (octet, blksize and tsize). */ len = (grub_sprintf ((char *) tp.u.rrq, "%s%coctet%cblksize%c%d%ctsize%c0", dirname, 0, 0, 0, TFTP_MAX_PACKET, 0, 0) + sizeof (tp.ip) + sizeof (tp.udp) + sizeof (tp.opcode) + 1); /* Restore the original DIRNAME. */ dirname[grub_strlen (dirname)] = ch; /* Save the TFTP packet so that we can reopen the file later. */ grub_memmove ((char *) &saved_tp, (char *) &tp, len); saved_len = len; if (! send_rrq ()) { errnum = ERR_WRITE; return 0; } /* Read the data. */ if (! buf_fill (0)) { errnum = ERR_FILE_NOT_FOUND; return 0; } if (filemax == -1) { /* The server doesn't support the "tsize" option, so we must read the file twice... */ /* Zero the size of the file. */ filemax = 0; do { /* Add the length of the downloaded data. */ filemax += buf_read; /* Reset the offset. Just discard the contents of the buffer. */ buf_read = 0; /* Read the data. */ if (! buf_fill (0)) { errnum = ERR_READ; return 0; } } while (! buf_eof); /* Maybe a few amounts of data remains. */ filemax += buf_read; /* Retry the open instruction. */ goto reopen; } return 1; }