static bool sip (struct file_data *current, bool skip_test) { /* If we have a nonexistent file at this stage, treat it as empty. */ if (current->desc < 0) { /* Leave room for a sentinel. */ current->bufsize = sizeof (word); current->buffer = xmalloc (current->bufsize); } else { current->bufsize = buffer_lcm (sizeof (word), STAT_BLOCKSIZE (current->stat), PTRDIFF_MAX - 2 * sizeof (word)); current->buffer = xmalloc (current->bufsize); if (! skip_test) { /* Check first part of file to see if it's a binary file. */ /* FIXME: if O_BINARY, this should revert to text mode if the file is not binary. */ file_block_read (current, current->bufsize); return binary_file_p (current->buffer, current->buffered); } } current->buffered = 0; current->eof = false; return false; }
static bool sip (struct file_data *current, bool skip_test) { /* If we have a nonexistent file at this stage, treat it as empty. */ if (current->desc < 0) { /* Leave room for a sentinel. */ current->bufsize = sizeof (word); current->buffer = xmalloc (current->bufsize); } else { current->bufsize = buffer_lcm (sizeof (word), STAT_BLOCKSIZE (current->stat), PTRDIFF_MAX - 2 * sizeof (word)); current->buffer = xmalloc (current->bufsize); #ifdef __KLIBC__ /* Skip test if seek is not possible */ skip_test = skip_test || (lseek (current->desc, 0, SEEK_CUR) < 0 && errno == ESPIPE); #endif if (! skip_test) { /* Check first part of file to see if it's a binary file. */ int prev_mode = set_binary_mode (current->desc, O_BINARY); off_t buffered; file_block_read (current, current->bufsize); buffered = current->buffered; if (prev_mode != O_BINARY) { /* Revert to text mode and seek back to the start to reread the file. Use relative seek, since file descriptors like stdin might not start at offset zero. */ if (lseek (current->desc, - buffered, SEEK_CUR) < 0) pfatal_with_name (current->name); set_binary_mode (current->desc, prev_mode); current->buffered = 0; current->eof = false; } return binary_file_p (current->buffer, buffered); } } current->buffered = 0; current->eof = false; return false; }
static bool sip (struct file_data *current, bool skip_test) { /* If we have a nonexistent file at this stage, treat it as empty. */ if (current->desc < 0) { /* Leave room for a sentinel. */ current->bufsize = sizeof (word); current->buffer = xmalloc (current->bufsize); } else { current->bufsize = buffer_lcm (sizeof (word), STAT_BLOCKSIZE (current->stat), PTRDIFF_MAX - 2 * sizeof (word)); current->buffer = xmalloc (current->bufsize); if (! skip_test) { /* Check first part of file to see if it's a binary file. */ bool was_binary = set_binary_mode (current->desc, true); off_t buffered; file_block_read (current, current->bufsize); buffered = current->buffered; if (! was_binary) { /* Revert to text mode and seek back to the beginning to reread the file. Use relative seek, since file descriptors like stdin might not start at offset zero. */ if (lseek (current->desc, - buffered, SEEK_CUR) == -1) pfatal_with_name (current->name); set_binary_mode (current->desc, false); current->buffered = 0; current->eof = false; } return binary_file_p (current->buffer, buffered); } } current->buffered = 0; current->eof = false; return false; }
static void slurp (struct file_data *current) { size_t cc; if (current->desc < 0) { /* The file is nonexistent. */ return; } if (S_ISREG (current->stat.st_mode)) { /* It's a regular file; slurp in the rest all at once. */ /* Get the size out of the stat block. Allocate just enough room for appended newline plus word sentinel, plus word-alignment since we want the buffer word-aligned. */ size_t file_size = current->stat.st_size; cc = file_size + 2 * sizeof (word) - file_size % sizeof (word); if (file_size != current->stat.st_size || cc < file_size || PTRDIFF_MAX <= cc) xalloc_die (); if (current->bufsize < cc) { current->bufsize = cc; current->buffer = xrealloc (current->buffer, cc); } /* Try to read at least 1 more byte than the size indicates, to detect whether the file is growing. This is a nicety for users who run 'diff' on files while they are changing. */ if (current->buffered <= file_size) { file_block_read (current, file_size + 1 - current->buffered); if (current->buffered <= file_size) return; } } /* It's not a regular file, or it's a growing regular file; read it, growing the buffer as needed. */ file_block_read (current, current->bufsize - current->buffered); if (current->buffered) { while (current->buffered == current->bufsize) { if (PTRDIFF_MAX / 2 - sizeof (word) < current->bufsize) xalloc_die (); current->bufsize *= 2; current->buffer = xrealloc (current->buffer, current->bufsize); file_block_read (current, current->bufsize - current->buffered); } /* Allocate just enough room for appended newline plus word sentinel, plus word-alignment. */ cc = current->buffered + 2 * sizeof (word); current->bufsize = cc - cc % sizeof (word); current->buffer = xrealloc (current->buffer, current->bufsize); } }