Beispiel #1
0
wchar_t *
__fgetws_chk (wchar_t *buf, size_t size, int n, _IO_FILE *fp)
{
  _IO_size_t count;
  wchar_t *result;
  int old_error;
  CHECK_FILE (fp, NULL);
  if (n <= 0)
    return NULL;
  _IO_acquire_lock (fp);
  /* This is very tricky since a file descriptor may be in the
     non-blocking mode. The error flag doesn't mean much in this
     case. We return an error only when there is a new error. */
  old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
  fp->_IO_file_flags &= ~_IO_ERR_SEEN;
  count = _IO_getwline (fp, buf, MIN ((size_t) n - 1, size), L'\n', 1);
  /* If we read in some bytes and errno is EAGAIN, that error will
     be reported for next read. */
  if (count == 0 || (_IO_ferror_unlocked (fp) && errno != EAGAIN))
    result = NULL;
  else if (count >= size)
    __chk_fail ();
  else
    {
      buf[count] = '\0';
      result = buf;
    }
  fp->_IO_file_flags |= old_error;
  _IO_release_lock (fp);
  return result;
}
Beispiel #2
0
/* Print a line on stderr consisting of the text in S, a colon, a space,
   a message describing the meaning of the contents of `errno' and a newline.
   If S is NULL or "", the colon and space are omitted.  */
void
perror (const char *s)
{
  int errnum = errno;
  FILE *fp;
  int fd = -1;


  /* The standard says that 'perror' must not change the orientation
     of the stream.  What is supposed to happen when the stream isn't
     oriented yet?  In this case we'll create a new stream which is
     using the same underlying file descriptor.  */
  if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1)
      || (fd = fileno (stderr)) == -1
      || (fd = __dup (fd)) == -1
      || (fp = fdopen (fd, "w+")) == NULL)
    {
      if (__glibc_unlikely (fd != -1))
	__close (fd);

      /* Use standard error as is.  */
      perror_internal (stderr, s, errnum);
    }
  else
    {
      /* We don't have to do any special hacks regarding the file
	 position.  Since the stderr stream wasn't used so far we just
	 write to the descriptor.  */
      perror_internal (fp, s, errnum);

      if (_IO_ferror_unlocked (fp))
	stderr->_flags |= _IO_ERR_SEEN;

      /* Close the stream.  */
      fclose (fp);
    }
}
Beispiel #3
0
wchar_t *
fgetws (wchar_t *buf, int n, _IO_FILE *fp)
{
  _IO_size_t count;
  wchar_t *result;
  int old_error;
  CHECK_FILE (fp, NULL);
  if (n <= 0)
    return NULL;
  if (__glibc_unlikely (n == 1))
    {
      /* Another irregular case: since we have to store a NUL byte and
	 there is only room for exactly one byte, we don't have to
	 read anything.  */
      buf[0] = L'\0';
      return buf;
    }
  _IO_acquire_lock (fp);
  /* This is very tricky since a file descriptor may be in the
     non-blocking mode. The error flag doesn't mean much in this
     case. We return an error only when there is a new error. */
  old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
  fp->_IO_file_flags &= ~_IO_ERR_SEEN;
  count = _IO_getwline (fp, buf, n - 1, L'\n', 1);
  /* If we read in some bytes and errno is EAGAIN, that error will
     be reported for next read. */
  if (count == 0 || (_IO_ferror_unlocked (fp) && errno != EAGAIN))
    result = NULL;
  else
    {
      buf[count] = '\0';
      result = buf;
    }
  fp->_IO_file_flags |= old_error;
  _IO_release_lock (fp);
  return result;
}
Beispiel #4
0
int
__ferror_unlocked (FILE *fp)
{
  CHECK_FILE (fp, EOF);
  return _IO_ferror_unlocked (fp);
}
Beispiel #5
0
_IO_ssize_t
_IO_getdelim(char **lineptr, _IO_size_t *n, int delimiter, _IO_FILE *fp)
{
	_IO_ssize_t result;
	_IO_ssize_t cur_len = 0;
	_IO_ssize_t len;

	if (lineptr == NULL || n == NULL)
	{
		MAYBE_SET_EINVAL;
		return -1;
	}
	CHECK_FILE (fp, -1);
	_IO_acquire_lock(fp);
	if (_IO_ferror_unlocked(fp))
	{
		result = -1;
		goto unlock_return;
	}

	if (*lineptr == NULL || *n == 0)
	{
		*n = 120;
		*lineptr = (char *) malloc(*n);
		if (*lineptr == NULL)
		{
			result = -1;
			goto unlock_return;
		}
	}

	len = fp->_IO_read_end - fp->_IO_read_ptr;
	if (len <= 0)
	{
		if (__underflow(fp) == EOF)
		{
			result = -1;
			goto unlock_return;
		}
		len = fp->_IO_read_end - fp->_IO_read_ptr;
	}

	for (;;)
	{
		_IO_size_t needed;
		char *t;
		t = (char *) memchr((void *) fp->_IO_read_ptr, delimiter, len);
		if (t != NULL)
			len = (t - fp->_IO_read_ptr) + 1;
		if (__glibc_unlikely(len >= SSIZE_MAX - cur_len))
		{
			__set_errno(EOVERFLOW);
			result = -1;
			goto unlock_return;
		}
		/* Make enough space for len+1 (for final NUL) bytes.  */
		needed = cur_len + len + 1;
		if (needed > *n)
		{
			char *new_lineptr;

			if (needed < 2 * *n)
				needed = 2 * *n; /* Be generous. */
			new_lineptr = (char *) realloc(*lineptr, needed);
			if (new_lineptr == NULL)
			{
				result = -1;
				goto unlock_return;
			}
			*lineptr = new_lineptr;
			*n = needed;
		}
		memcpy(*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
		fp->_IO_read_ptr += len;
		cur_len += len;
		if (t != NULL || __underflow(fp) == EOF)
			break;
		len = fp->_IO_read_end - fp->_IO_read_ptr;
	}
	(*lineptr)[cur_len] = '\0';
	result = cur_len;

	unlock_return:
	_IO_release_lock(fp);
	return result;
}