Пример #1
0
/*
 * __sinit() is called whenever stdio's internal variables must be set up.
 */
void
__sinit(void)
{
	_THREAD_PRIVATE_MUTEX(__sinit_mutex);

	_THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
	if (__sdidinit) {
		/* bail out if caller lost the race */
		_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
		return;
	}

	/* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */
	for (size_t i = 0; i < 3; ++i) {
		_FILEEXT_SETUP(__sF+i, __sFext+i);
	}
	/* Initialize the pre-allocated (but initially unused) streams. */
	for (size_t i = 0; i < FOPEN_MAX - 3; ++i) {
		_FILEEXT_SETUP(usual+i, usualext+i);
	}

	/* make sure we clean up on exit */
	__atexit_register_cleanup(_cleanup); /* conservative */
	__sdidinit = 1;

	_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
}
Пример #2
0
/*
 * Helper function for `fprintf to unbuffered unix file': creates a
 * temporary buffer.  We only work on write-only files; this avoids
 * worries about ungetc buffers and so forth.
 */
static int
__sbprintf(FILE *fp, locale_t locale, const wchar_t *fmt, va_list ap)
{
	int ret;
	FILE fake;
	struct __sfileext fakeext;
	unsigned char buf[BUFSIZ];

	_FILEEXT_SETUP(&fake, &fakeext);
	/* copy the important variables */
	fake._flags = fp->_flags & ~__SNBF;
	fake._file = fp->_file;
	fake._cookie = fp->_cookie;
	fake._write = fp->_write;
#ifdef notyet
	fake._orientation = fp->_orientation;
	fake._mbstate = fp->_mbstate;
#endif

	/* set up the buffer */
	fake._bf._base = fake._p = buf;
	fake._bf._size = fake._w = sizeof(buf);
	fake._lbfsize = 0;	/* not actually used, but Just In Case */

	/* do the work, then copy any error status */
	ret = __vfwprintf(&fake, locale, fmt, ap);
	if (ret >= 0 && __sflush(&fake))
		ret = WEOF;
	if (fake._flags & __SERR)
		fp->_flags |= __SERR;
	return (ret);
}
Пример #3
0
int
vsnprintf(char *str, size_t n, const char *fmt, __va_list ap)
{
	int ret;
	char dummy;
	FILE f;
	struct __sfileext fext;

	_FILEEXT_SETUP(&f, &fext);

	/* While snprintf(3) specifies size_t stdio uses an int internally */
	if (n > INT_MAX)
		n = INT_MAX;
	/* Stdio internals do not deal correctly with zero length buffer */
	if (n == 0) {
		str = &dummy;
		n = 1;
	}
	f._file = -1;
	f._flags = __SWR | __SSTR;
	f._bf._base = f._p = (unsigned char *)str;
	f._bf._size = f._w = n - 1;
	ret = vfprintf(&f, fmt, ap);
	*f._p = '\0';
	return (ret);
}
Пример #4
0
static struct glue *
moreglue(int n)
{
	struct glue *g;
	FILE *p;
	struct __sfileext *pext;
	static FILE empty;
	char *data;

	data = malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)
	    + n * sizeof(struct __sfileext));
	if (data == NULL)
		return (NULL);
	g = (struct glue *)data;
	p = (FILE *)ALIGN(data + sizeof(*g));
	pext = (struct __sfileext *)
	    (ALIGN(data + sizeof(*g)) + n * sizeof(FILE));
	g->next = NULL;
	g->niobs = n;
	g->iobs = p;
	while (--n >= 0) {
		*p = empty;
		_FILEEXT_SETUP(p, pext);
		p++;
		pext++;
	}
	return (g);
}
Пример #5
0
int
vasprintf_l(char **str, locale_t locale, const char *fmt, __va_list ap)
{
	int ret;
	FILE f;
	struct __sfileext fext;
	unsigned char *_base;
	FIX_LOCALE(locale);

	_FILEEXT_SETUP(&f, &fext);
	f._file = -1;
	f._flags = __SWR | __SSTR | __SALC;
	f._bf._base = f._p = (unsigned char *)malloc(128);
	if (f._bf._base == NULL)
		goto err;
	f._bf._size = f._w = 127;		/* Leave room for the NUL */
	ret = __vfprintf(&f, locale, fmt, ap);
	if (ret == -1)
		goto err;
	*f._p = '\0';
	_base = realloc(f._bf._base, ret + 1);
	if (_base == NULL)
		goto err;
	*str = (char *)_base;
	return (ret);

err:
	if (f._bf._base) {
		free(f._bf._base);
		f._bf._base = NULL;
	}
	*str = NULL;
	errno = ENOMEM;
	return (-1);
}
Пример #6
0
static struct glue *
moreglue(int n)
{
  struct glue *g;
  FILE *p;
  struct __sfileext *pext;
  static FILE empty;

  g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)
    + n * sizeof(struct __sfileext));
  if (g == NULL)
    return (NULL);
  p = (FILE *)ALIGN((g + 1));
  g->next = NULL;
  g->niobs = n;
  g->iobs = p;
  pext = (void *)(p + n);
  while (--n >= 0) {
    *p = empty;
    _FILEEXT_SETUP(p, pext);
    p++;
    pext++;
  }
  return (g);
}
Пример #7
0
int
snprintf(char *str, size_t n, char const *fmt, ...)
{
	int ret;
	va_list ap;
	FILE f;
	struct __sfileext fext;
	unsigned char dummy[1];

	_DIAGASSERT(n == 0 || str != NULL);
	_DIAGASSERT(fmt != NULL);

	if ((int)n < 0) {
		errno = EINVAL;
		return (-1);
	}
	va_start(ap, fmt);
	_FILEEXT_SETUP(&f, &fext);
	f._file = -1;
	f._flags = __SWR | __SSTR;
	if (n == 0) {
		f._bf._base = f._p = dummy;
		f._bf._size = f._w = 0;
	} else {
		f._bf._base = f._p = (unsigned char *)str;
		f._bf._size = f._w = n - 1;
	}
	ret = __vfprintf_unlocked(&f, fmt, ap);
	*f._p = 0;
	va_end(ap);
	return (ret);
}
Пример #8
0
float_type wcstod(const wchar_t* str, wchar_t** end, float_type strtod_fn(const char*, char**)) {
  const wchar_t* original_str = str;
  while (iswspace(*str)) {
    str++;
  }

  // What's the longest span of the input that might be part of the float?
  size_t max_len = wcsspn(str, L"-+0123456789.xXeEpP()nNaAiIfFtTyY");

  // We know the only valid characters are ASCII, so convert them by brute force.
  char* ascii_str = new char[max_len + 1];
  if (!ascii_str) return float_type();
  for (size_t i = 0; i < max_len; ++i) {
    ascii_str[i] = str[i] & 0xff;
  }
  ascii_str[max_len] = 0;

  // Set up a fake FILE that points to those ASCII characters, for `parsefloat`.
  FILE f;
  __sfileext fext;
  _FILEEXT_SETUP(&f, &fext);
  f._flags = __SRD;
  f._bf._base = f._p = reinterpret_cast<unsigned char*>(ascii_str);
  f._bf._size = f._r = max_len;
  f._read = [](void*, char*, int) { return 0; }; // aka `eofread`, aka "no more data".
  f._lb._base = NULL;

  // Ask `parsefloat` to look at the same data more carefully.

  // We can't just do this straight away because we can't construct a suitable FILE*
  // in the absence of any `fwmemopen` analogous to `fmemopen`. And we don't want to
  // duplicate the `parsefloat` logic. We also don't want to actually have to have wchar_t
  // implementations of the ASCII `strtod` logic (though if you were designing a libc
  // from scratch, you'd probably want to just make that more generic and lose all the
  // cruft on top).
  size_t actual_len = parsefloat(&f, ascii_str, ascii_str + max_len);

  // Finally let the ASCII conversion function do the work.
  char* ascii_end;
  float_type result = strtod_fn(ascii_str, &ascii_end);
  if (ascii_end != ascii_str + actual_len) abort();

  if (end) {
    if (actual_len == 0) {
      // There was an error. We need to set the end pointer back to the original string, not the
      // one we advanced past the leading whitespace.
      *end = const_cast<wchar_t*>(original_str);
    } else {
      *end = const_cast<wchar_t*>(str) + actual_len;
    }
  }

  delete[] ascii_str;
  return result;
}
Пример #9
0
/*
 * __sinit() is called whenever stdio's internal variables must be set up.
 */
void
__sinit( void )
{
  int i;

  for (i = 0; i < FOPEN_MAX - 3; i++)
    _FILEEXT_SETUP(&usual[i], &usualext[i]);

  /* make sure we clean up on exit */
  gMD->cleanup = _cleanup;   /* conservative */
  __sdidinit = 1;
}
Пример #10
0
int
vsscanf(const char *str, const char *fmt, __va_list ap)
{
	FILE f;
	struct __sfileext fext;

	_FILEEXT_SETUP((&f), &fext);
	f._flags = __SRD;
	f._bf._base = f._p = (unsigned char *)str;
	f._bf._size = f._r = strlen(str);
	f._read = eofread;
	f._lb._base = NULL;
	return (vfscanf(&f, fmt, ap));
}
Пример #11
0
int
vsprintf(char *str, const char *fmt, __va_list ap)
{
	int ret;
	FILE f;
	struct __sfileext fext;

	_FILEEXT_SETUP(&f, &fext);
	f._file = -1;
	f._flags = __SWR | __SSTR;
	f._bf._base = f._p = (unsigned char *)str;
	f._bf._size = f._w = INT_MAX;
	ret = vfprintf(&f, fmt, ap);
	*f._p = '\0';
	return (ret);
}
Пример #12
0
/*
 * __sinit() is called whenever stdio's internal variables must be set up.
 */
void
__sinit(void)
{
	_THREAD_PRIVATE_MUTEX(__sinit_mutex);
	int i;

	_THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
	if (__sdidinit)
		goto out;	/* bail out if caller lost the race */
	for (i = 0; i < FOPEN_MAX - 3; i++) {
		_FILEEXT_SETUP(usual+i, usualext+i);
	}
	/* make sure we clean up on exit */
	__atexit_register_cleanup(_cleanup); /* conservative */
	__sdidinit = 1;
out: 
	_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
}
Пример #13
0
int
sscanf(const char *str, const char *fmt, ...)
{
	int ret;
	va_list ap;
	FILE f;
	struct __sfileext fext;

	_FILEEXT_SETUP(&f, &fext);
	f._flags = __SRD;
	f._bf._base = f._p = (unsigned char *)str;
	f._bf._size = f._r = strlen(str);
	f._read = eofread;
	f._lb._base = NULL;
	va_start(ap, fmt);
	ret = vfscanf(&f, fmt, ap);
	va_end(ap);
	return (ret);
}
Пример #14
0
int
sprintf(char *str, char const *fmt, ...)
{
	int ret;
	va_list ap;
	FILE f;
	struct __sfileext fext;

	_DIAGASSERT(str != NULL);
	_DIAGASSERT(fmt != NULL);

	_FILEEXT_SETUP(&f, &fext);
	f._file = -1;
	f._flags = __SWR | __SSTR;
	f._bf._base = f._p = (unsigned char *)str;
	f._bf._size = f._w = INT_MAX;
	va_start(ap, fmt);
	ret = __vfprintf_unlocked(&f, fmt, ap);
	va_end(ap);
	*f._p = 0;
	return (ret);
}
Пример #15
0
int
asprintf(char **str, const char *fmt, ...)
{
	int ret;
	va_list ap;
	FILE f;
	struct __sfileext fext;
	unsigned char *_base;

	_FILEEXT_SETUP(&f, &fext);
	f._file = -1;
	f._flags = __SWR | __SSTR | __SALC;
	f._bf._base = f._p = (unsigned char *)malloc(128);
	if (f._bf._base == NULL)
		goto err;
	f._bf._size = f._w = 127;		/* Leave room for the NUL */
	va_start(ap, fmt);
	ret = vfprintf(&f, fmt, ap);
	va_end(ap);
	if (ret == -1)
		goto err;
	*f._p = '\0';
	_base = realloc(f._bf._base, ret + 1);
	if (_base == NULL)
		goto err;
	*str = (char *)_base;
	return (ret);

err:
	if (f._bf._base) {
		free(f._bf._base);
		f._bf._base = NULL;
	}
	*str = NULL;
	errno = ENOMEM;
	return (-1);
}
Пример #16
0
int
asprintf(char **str, char const *fmt, ...)
{
	int ret;
	va_list ap;
	FILE f;
	struct __sfileext fext;
	unsigned char *_base;

	_DIAGASSERT(str != NULL);

	_FILEEXT_SETUP(&f, &fext);
	f._file = -1;
	f._flags = __SWR | __SSTR | __SALC;
	f._bf._base = f._p = malloc((size_t)128);
	if (f._bf._base == NULL)
		goto err;
	f._bf._size = f._w = 127;		/* Leave room for the NUL */
	va_start(ap, fmt);
	ret = __vfprintf_unlocked(&f, fmt, ap);
	va_end(ap);
	if (ret < 0)
		goto err;
	*f._p = '\0';
	_base = realloc(f._bf._base, (size_t)ret + 1);
	if (_base == NULL)
		goto err;
	*str = (char *)_base;
	return (ret);

err:
	if (f._bf._base)
		free(f._bf._base);
	*str = NULL;
	errno = ENOMEM;
	return (-1);
}