示例#1
0
文件: io.c 项目: xianjimli/datasafe
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;
}
示例#2
0
文件: io.c 项目: NaiyanXu/gitroot
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;
}
示例#3
0
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;
}
示例#4
0
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);
    }
}