示例#1
0
int
vasprintf (char **resultp, const char *format, va_list args)
{
  size_t length;
  char *result = vasnprintf (NULL, &length, format, args);
  if (result == NULL)
    return -1;

  if (length > INT_MAX)
    {
      free (result);
      errno = EOVERFLOW;
      return -1;
    }

  *resultp = result;
  /* Return the number of resulting bytes, excluding the trailing NUL.  */
  return length;
}
示例#2
0
/* Print formatted output to the stream FP.
   Return string length of formatted string.  On error, return a negative
   value.  */
int
fprintf (FILE *fp, const char *format, ...)
{
  char buf[2000];
  char *output;
  size_t len;
  size_t lenbuf = sizeof (buf);
  va_list args;

  va_start (args, format);
  output = vasnprintf (buf, &lenbuf, format, args);
  len = lenbuf;
  va_end (args);

  if (!output)
    {
      fseterr (fp);
      return -1;
    }

  if (fwrite (output, 1, len, fp) < len)
    {
      if (output != buf)
        {
          int saved_errno = errno;
          free (output);
          errno = saved_errno;
        }
      return -1;
    }

  if (output != buf)
    free (output);

  if (len > INT_MAX)
    {
      errno = EOVERFLOW;
      fseterr (fp);
      return -1;
    }

  return len;
}
示例#3
0
/* Print formatted output to string STR.
   Return string length of formatted string.  On error, return a negative
   value.  */
int
sprintf (char *str, const char *format, ...)
{
  char *output;
  size_t len;
  size_t lenbuf;
  va_list args;

  /* vasnprintf fails with EOVERFLOW when the buffer size argument is larger
     than INT_MAX (if that fits into a 'size_t' at all).
     Also note that glibc's iconv fails with E2BIG when we pass a length that
     is so large that str + lenbuf wraps around, i.e.
     (uintptr_t) (str + lenbuf) < (uintptr_t) str.
     Therefore set lenbuf = min (SIZE_MAX, INT_MAX, - (uintptr_t) str - 1).  */
  lenbuf = (SIZE_MAX < INT_MAX ? SIZE_MAX : INT_MAX);
  if (lenbuf > ~ (uintptr_t) str)
    lenbuf = ~ (uintptr_t) str;

  va_start (args, format);
  output = vasnprintf (str, &lenbuf, format, args);
  len = lenbuf;
  va_end (args);

  if (!output)
    return -1;

  if (output != str)
    {
      /* len is near SIZE_MAX.  */
      free (output);
      errno = EOVERFLOW;
      return -1;
    }

  if (len > INT_MAX)
    {
      errno = EOVERFLOW;
      return -1;
    }

  return len;
}
示例#4
0
/* Print formatted output to string STR.  Similar to vsprintf, but
   additional length SIZE limit how much is written into STR.  Returns
   string length of formatted string (which may be larger than SIZE).
   STR may be NULL, in which case nothing will be written.  On error,
   return a negative value. */
int
vsnprintf (char *str, size_t size, const char *format, va_list args)
{
  char *output;
  size_t len;

  len = size;
  output = vasnprintf (str, &len, format, args);

  if (!output)
    return -1;

  if (str != NULL)
    if (len > size - 1) /* equivalent to: (size > 0 && len >= size) */
      str[size - 1] = '\0';

  if (output != str)
    free (output);

  return len;
}
示例#5
0
/* Grow an obstack with formatted output.  Return the number of bytes
   added to OBS.  No trailing nul byte is added, and the object should
   be closed with obstack_finish before use.

   Upon memory allocation error, call obstack_alloc_failed_handler.
   Upon other error, return -1.  */
int
obstack_vprintf (struct obstack *obs, const char *format, va_list args)
{
  /* If we are close to the end of the current obstack chunk, use a
     stack-allocated buffer and copy, to reduce the likelihood of a
     small-size malloc.  Otherwise, print directly into the
     obstack.  */
  enum { CUTOFF = 1024 };
  char buf[CUTOFF];
  char *base = obstack_next_free (obs);
  size_t len = obstack_room (obs);
  char *str;

  if (len < CUTOFF)
    {
      base = buf;
      len = CUTOFF;
    }
  str = vasnprintf (base, &len, format, args);
  if (!str)
    {
      if (errno == ENOMEM)
        obstack_alloc_failed_handler ();
      return -1;
    }
  if (str == base && str != buf)
    /* The output was already computed in place, but we need to
       account for its size.  */
    obstack_blank_fast (obs, len);
  else
    {
      /* The output exceeded available obstack space or we used buf;
         copy the resulting string.  */
      obstack_grow (obs, str, len);
      if (str != buf)
        free (str);
    }
  return len;
}
示例#6
0
int rpl_vfprintf( FILE *fp, char *format, va_list args )
{
  int eax;
  char buf[2000];
  char *output;
  size_t len;
  size_t lenbuf = 2000;
  output = vasnprintf( buf, &lenbuf, format, args );
  len = lenbuf;
  if ( output == 0 )
  {
    fseterr( fp );
    return -1;
  }
  else
  {
    if ( fwrite( output, 1, len, fp ) < len )
    {
      if ( output != buf[0] )
      {
        int saved_errno = *(int*)(__errno_location( ));
        free( output );
        *(int*)(__errno_location( )) = saved_errno;
      }
      return -1;
    }
    else
    {
      if ( (int)len < 0 )
      {
        *(int*)(__errno_location( )) = 75;
        fseterr( fp );
        return -1;
      }
      else
        return (int)len;
    }
  }
}
示例#7
0
int
dprintf (int fd, const char *format, ...)
{
  char buf[2000];
  char *output;
  size_t len;
  size_t lenbuf = sizeof (buf);
  va_list args;

  va_start (args, format);
  output = vasnprintf (buf, &lenbuf, format, args);
  len = lenbuf;
  va_end (args);

  if (!output)
    return -1;

  if (full_write (fd, output, len) < len)
    {
      if (output != buf)
        {
          int saved_errno = errno;
          free (output);
          errno = saved_errno;
        }
      return -1;
    }

  if (output != buf)
    free (output);

  if (len > INT_MAX)
    {
      errno = EOVERFLOW;
      return -1;
    }

  return len;
}
示例#8
0
文件: snprintf.c 项目: dezelin/maily
/* Print formatted output to string STR.  Similar to sprintf, but
   additional length SIZE limit how much is written into STR.  Returns
   string length of formatted string (which may be larger than SIZE).
   STR may be NULL, in which case nothing will be written.  On error,
   return a negative value.  */
int
snprintf (char *str, size_t size, const char *format, ...)
{
  char *output;
  size_t len;
  size_t lenbuf = size;
  va_list args;

  va_start (args, format);
  output = vasnprintf (str, &lenbuf, format, args);
  len = lenbuf;
  va_end (args);

  if (!output)
    return -1;

  if (output != str)
    {
      if (size)
        {
          size_t pruned_len = (len < size ? len : size - 1);
          memcpy (str, output, pruned_len);
          str[pruned_len] = '\0';
        }

      free (output);
    }

  if (INT_MAX < len)
    {
      errno = EOVERFLOW;
      return -1;
    }

  return len;
}