newlib-2.1.0

git-svn-id: svn://kolibrios.org@4921 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge)
2014-05-10 22:12:19 +00:00
parent 914e67bd24
commit 7315bb05c0
204 changed files with 10781 additions and 3986 deletions

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* This code was copied from asprintf.c */
/* doc in siprintf.c */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
#include "local.h"
int
_DEFUN(_asiprintf_r, (ptr, strp, fmt),
struct _reent *ptr _AND
char **strp _AND
const char *fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
f._bf._base = f._p = NULL;
f._bf._size = f._w = 0;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfiprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret >= 0)
{
*f._p = 0;
*strp = (char *) f._bf._base;
}
return (ret);
}
#ifndef _REENT_ONLY
int
_DEFUN(asiprintf, (strp, fmt),
char **strp _AND
const char *fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
f._bf._base = f._p = NULL;
f._bf._size = f._w = 0;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfiprintf_r (_REENT, &f, fmt, ap);
va_end (ap);
if (ret >= 0)
{
*f._p = 0;
*strp = (char *) f._bf._base;
}
return (ret);
}
#endif /* ! _REENT_ONLY */

View File

@@ -0,0 +1,108 @@
/* Copyright (C) 2007, 2008 Eric Blake
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
/* This code was derived from asprintf.c */
/* doc in siprintf.c */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
#include <errno.h>
#include "local.h"
char *
_DEFUN(_asniprintf_r, (ptr, buf, lenp, fmt),
struct _reent *ptr _AND
char *buf _AND
size_t *lenp _AND
const char *fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
size_t len = *lenp;
if (buf && len)
{
/* mark an existing buffer, but allow allocation of larger string */
f._flags = __SWR | __SSTR | __SOPT;
}
else
{
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
len = 0;
buf = NULL;
}
f._bf._base = f._p = (unsigned char *) buf;
/* For now, inherit the 32-bit signed limit of FILE._bf._size.
FIXME - it would be nice to rewrite sys/reent.h to support size_t
for _size. */
if (len > INT_MAX)
{
ptr->_errno = EOVERFLOW;
return NULL;
}
f._bf._size = f._w = len;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfiprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret < 0)
return NULL;
*lenp = ret;
*f._p = '\0';
return (char *) f._bf._base;
}
#ifndef _REENT_ONLY
char *
_DEFUN(asniprintf, (buf, lenp, fmt),
char *buf _AND
size_t *lenp _AND
const char *fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
size_t len = *lenp;
struct _reent *ptr = _REENT;
if (buf && len)
{
/* mark an existing buffer, but allow allocation of larger string */
f._flags = __SWR | __SSTR | __SOPT;
}
else
{
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
len = 0;
buf = NULL;
}
f._bf._base = f._p = (unsigned char *) buf;
/* For now, inherit the 32-bit signed limit of FILE._bf._size.
FIXME - it would be nice to rewrite sys/reent.h to support size_t
for _size. */
if (len > INT_MAX)
{
ptr->_errno = EOVERFLOW;
return NULL;
}
f._bf._size = f._w = len;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfiprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret < 0)
return NULL;
*lenp = ret;
*f._p = '\0';
return (char *) f._bf._base;
}
#endif /* ! _REENT_ONLY */

View File

@@ -0,0 +1,108 @@
/* Copyright (C) 2007, 2008 Eric Blake
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
/* This code was derived from asprintf.c */
/* doc in sprintf.c */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
#include <errno.h>
#include "local.h"
char *
_DEFUN(_asnprintf_r, (ptr, buf, lenp, fmt),
struct _reent *__restrict ptr _AND
char *buf _AND
size_t *lenp _AND
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
size_t len = *lenp;
if (buf && len)
{
/* mark an existing buffer, but allow allocation of larger string */
f._flags = __SWR | __SSTR | __SOPT;
}
else
{
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
len = 0;
buf = NULL;
}
f._bf._base = f._p = (unsigned char *) buf;
/* For now, inherit the 32-bit signed limit of FILE._bf._size.
FIXME - it would be nice to rewrite sys/reent.h to support size_t
for _size. */
if (len > INT_MAX)
{
ptr->_errno = EOVERFLOW;
return NULL;
}
f._bf._size = f._w = len;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret < 0)
return NULL;
*lenp = ret;
*f._p = '\0';
return (char *) f._bf._base;
}
#ifndef _REENT_ONLY
char *
_DEFUN(asnprintf, (buf, lenp, fmt),
char *__restrict buf _AND
size_t *__restrict lenp _AND
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
size_t len = *lenp;
struct _reent *ptr = _REENT;
if (buf && len)
{
/* mark an existing buffer, but allow allocation of larger string */
f._flags = __SWR | __SSTR | __SOPT;
}
else
{
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
len = 0;
buf = NULL;
}
f._bf._base = f._p = (unsigned char *) buf;
/* For now, inherit the 32-bit signed limit of FILE._bf._size.
FIXME - it would be nice to rewrite sys/reent.h to support size_t
for _size. */
if (len > INT_MAX)
{
ptr->_errno = EOVERFLOW;
return NULL;
}
f._bf._size = f._w = len;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret < 0)
return NULL;
*lenp = ret;
*f._p = '\0';
return (char *) f._bf._base;
}
#endif /* ! _REENT_ONLY */

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 1990, 2007 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* This code was copied from sprintf.c */
/* doc in sprintf.c */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
#include "local.h"
int
_DEFUN(_asprintf_r, (ptr, strp, fmt),
struct _reent *ptr _AND
char **__restrict strp _AND
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
f._bf._base = f._p = NULL;
f._bf._size = f._w = 0;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret >= 0)
{
*f._p = 0;
*strp = (char *) f._bf._base;
}
return (ret);
}
#ifndef _REENT_ONLY
int
_DEFUN(asprintf, (strp, fmt),
char **__restrict strp _AND
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
/* mark a zero-length reallocatable buffer */
f._flags = __SWR | __SSTR | __SMBF;
f._bf._base = f._p = NULL;
f._bf._size = f._w = 0;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfprintf_r (_REENT, &f, fmt, ap);
va_end (ap);
if (ret >= 0)
{
*f._p = 0;
*strp = (char *) f._bf._base;
}
return (ret);
}
#endif /* ! _REENT_ONLY */

View File

@@ -65,7 +65,7 @@ _DEFUN(clearerr, (fp),
FILE * fp)
{
CHECK_INIT(_REENT, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
__sclearerr (fp);
_funlockfile (fp);
_newlib_flockfile_end (fp);
}

View File

@@ -19,12 +19,13 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
#include <stdarg.h>
int dprintf(int <[fd]>, const char *<[format]>, ...);
int vdprintf(int <[fd]>, const char *<[format]>, va_list <[ap]>);
int dprintf(int <[fd]>, const char *restrict <[format]>, ...);
int vdprintf(int <[fd]>, const char *restrict <[format]>,
va_list <[ap]>);
int _dprintf_r(struct _reent *<[ptr]>, int <[fd]>,
const char *<[format]>, ...);
const char *restrict <[format]>, ...);
int _vdprintf_r(struct _reent *<[ptr]>, int <[fd]>,
const char *<[format]>, va_list <[ap]>);
const char *restrict <[format]>, va_list <[ap]>);
DESCRIPTION
<<dprintf>> and <<vdprintf>> allow printing a format, similarly to
@@ -55,7 +56,7 @@ int
_DEFUN(_dprintf_r, (ptr, fd, format),
struct _reent *ptr _AND
int fd _AND
const char *format _DOTS)
const char *__restrict format _DOTS)
{
va_list ap;
int n;
@@ -71,7 +72,7 @@ _DEFUN(_dprintf_r, (ptr, fd, format),
int
_DEFUN(dprintf, (fd, format),
int fd _AND
const char *format _DOTS)
const char *__restrict format _DOTS)
{
va_list ap;
int n;

View File

@@ -76,11 +76,20 @@ _DEFUN(_fclose_r, (rptr, fp),
CHECK_INIT (rptr, fp);
/* We can't use the _newlib_flockfile_XXX macros here due to the
interlocked locking with the sfp_lock. */
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
int __oldcancel;
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
#endif
_flockfile (fp);
if (fp->_flags == 0) /* not open! */
{
_funlockfile (fp);
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
pthread_setcancelstate (__oldcancel, &__oldcancel);
#endif
return (0);
}
/* Unconditionally flush to allow special handling for seekable read
@@ -103,6 +112,9 @@ _DEFUN(_fclose_r, (rptr, fp),
#endif
__sfp_lock_release ();
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
pthread_setcancelstate (__oldcancel, &__oldcancel);
#endif
return (r);
}

View File

@@ -93,7 +93,7 @@ _DEFUN(_fdopen_r, (ptr, fd, mode),
if ((fp = __sfp (ptr)) == 0)
return 0;
_flockfile (fp);
_newlib_flockfile_start (fp);
fp->_flags = flags;
/* POSIX recommends setting the O_APPEND bit on fd to match append
@@ -127,7 +127,7 @@ _DEFUN(_fdopen_r, (ptr, fd, mode),
fp->_flags |= __SCLE;
#endif
_funlockfile (fp);
_newlib_flockfile_end (fp);
return fp;
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
FUNCTION
<<feof>>---test for end of file
INDEX
feof
ANSI_SYNOPSIS
#include <stdio.h>
int feof(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int feof(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
<<feof>> tests whether or not the end of the file identified by <[fp]>
has been reached.
RETURNS
<<feof>> returns <<0>> if the end of file has not yet been reached; if
at end of file, the result is nonzero.
PORTABILITY
<<feof>> is required by ANSI C.
No supporting OS subroutines are required.
*/
#include <stdio.h>
#include "local.h"
/* A subroutine version of the macro feof. */
#undef feof
int
_DEFUN(feof, (fp),
FILE * fp)
{
int result;
CHECK_INIT(_REENT, fp);
_newlib_flockfile_start (fp);
result = __sfeof (fp);
_newlib_flockfile_end (fp);
return result;
}

View File

@@ -75,15 +75,19 @@ _DEFUN(__sflush_r, (ptr, fp),
register FILE * fp)
{
register unsigned char *p;
register int n, t;
register _READ_WRITE_BUFSIZE_TYPE n;
register _READ_WRITE_RETURN_TYPE t;
short flags;
t = fp->_flags;
if ((t & __SWR) == 0)
flags = fp->_flags;
if ((flags & __SWR) == 0)
{
#ifdef _FSEEK_OPTIMIZATION
/* For a read stream, an fflush causes the next seek to be
unoptimized (i.e. forces a system-level seek). This conforms
to the POSIX and SUSv3 standards. */
fp->_flags |= __SNPT;
#endif
/* For a seekable stream with buffered read characters, we will attempt
a seek to the current position now. A subsequent read will then get
@@ -152,7 +156,9 @@ _DEFUN(__sflush_r, (ptr, fp),
{
/* Seek successful or ignorable error condition.
We can clear read buffer now. */
#ifdef _FSEEK_OPTIMIZATION
fp->_flags &= ~__SNPT;
#endif
fp->_r = 0;
fp->_p = fp->_bf._base;
if ((fp->_flags & __SOFF) && (curoff != -1 || ptr->_errno == 0))
@@ -182,7 +188,7 @@ _DEFUN(__sflush_r, (ptr, fp),
* write function.
*/
fp->_p = p;
fp->_w = t & (__SLBF | __SNBF) ? 0 : fp->_bf._size;
fp->_w = flags & (__SLBF | __SNBF) ? 0 : fp->_bf._size;
while (n > 0)
{
@@ -226,9 +232,9 @@ _DEFUN(_fflush_r, (ptr, fp),
if (!fp->_flags)
return 0;
_flockfile (fp);
_newlib_flockfile_start (fp);
ret = __sflush_r (ptr, fp);
_funlockfile (fp);
_newlib_flockfile_end (fp);
return ret;
}

View File

@@ -78,9 +78,9 @@ _DEFUN(_fgetc_r, (ptr, fp),
{
int result;
CHECK_INIT(ptr, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
result = __sgetc_r (ptr, fp);
_funlockfile (fp);
_newlib_flockfile_end (fp);
return result;
}
@@ -92,10 +92,12 @@ _DEFUN(fgetc, (fp),
{
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
int result;
CHECK_INIT(_REENT, fp);
_flockfile (fp);
result = __sgetc_r (_REENT, fp);
_funlockfile (fp);
struct _reent *reent = _REENT;
CHECK_INIT(reent, fp);
_newlib_flockfile_start (fp);
result = __sgetc_r (reent, fp);
_newlib_flockfile_end (fp);
return result;
#else
return _fgetc_r (_REENT, fp);

View File

@@ -26,10 +26,10 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
char *fgets(char *<[buf]>, int <[n]>, FILE *<[fp]>);
char *fgets(char *restrict <[buf]>, int <[n]>, FILE *restrict <[fp]>);
#include <stdio.h>
char *_fgets_r(struct _reent *<[ptr]>, char *<[buf]>, int <[n]>, FILE *<[fp]>);
char *_fgets_r(struct _reent *<[ptr]>, char *restrict <[buf]>, int <[n]>, FILE *restrict <[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
@@ -83,9 +83,9 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
char *
_DEFUN(_fgets_r, (ptr, buf, n, fp),
struct _reent * ptr _AND
char *buf _AND
char *__restrict buf _AND
int n _AND
FILE * fp)
FILE *__restrict fp)
{
size_t len;
char *s;
@@ -98,11 +98,11 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
CHECK_INIT(ptr, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
int c;
int c = 0;
/* Sorry, have to do it the slow way */
while (--n > 0 && (c = __sgetc_r (ptr, fp)) != EOF)
{
@@ -112,11 +112,11 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
}
if (c == EOF && s == buf)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return NULL;
}
*s = 0;
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return buf;
}
#endif
@@ -134,7 +134,7 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
/* EOF: stop with partial or no line */
if (s == buf)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return 0;
}
break;
@@ -159,7 +159,7 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
fp->_p = t;
_CAST_VOID memcpy ((_PTR) s, (_PTR) p, len);
s[len] = 0;
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return (buf);
}
fp->_r -= len;
@@ -169,7 +169,7 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
}
while ((n -= len) != 0);
*s = 0;
_funlockfile (fp);
_newlib_flockfile_end (fp);
return buf;
}
@@ -177,9 +177,9 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
char *
_DEFUN(fgets, (buf, n, fp),
char *buf _AND
char *__restrict buf _AND
int n _AND
FILE * fp)
FILE *__restrict fp)
{
return _fgets_r (_REENT, buf, n, fp);
}

View File

@@ -47,6 +47,7 @@ Supporting OS subroutines required: none.
#include <_ansi.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
int
@@ -55,8 +56,14 @@ _DEFUN(fileno, (f),
{
int result;
CHECK_INIT (_REENT, f);
_flockfile (f);
_newlib_flockfile_start (f);
if (f->_flags)
result = __sfileno (f);
_funlockfile (f);
else
{
result = -1;
_REENT->_errno = EBADF;
}
_newlib_flockfile_end (f);
return result;
}

View File

@@ -62,7 +62,11 @@ _DEFUN(std, (ptr, flags, file, data),
ptr->_flags |= __SL64;
#endif /* __LARGE64_FILES */
ptr->_seek = __sseek;
#ifdef _STDIO_CLOSE_PER_REENT_STD_STREAMS
ptr->_close = __sclose;
#else /* _STDIO_CLOSE_STD_STREAMS */
ptr->_close = NULL;
#endif /* _STDIO_CLOSE_STD_STREAMS */
#if !defined(__SINGLE_THREAD__) && !defined(_REENT_SMALL)
__lock_init_recursive (ptr->_lock);
/*
@@ -77,23 +81,27 @@ _DEFUN(std, (ptr, flags, file, data),
#endif
}
struct glue_with_file {
struct _glue glue;
FILE file;
};
struct _glue *
_DEFUN(__sfmoreglue, (d, n),
struct _reent *d _AND
register int n)
{
struct _glue *g;
FILE *p;
struct glue_with_file *g;
g = (struct _glue *) _malloc_r (d, sizeof (*g) + n * sizeof (FILE));
g = (struct glue_with_file *)
_malloc_r (d, sizeof (*g) + (n - 1) * sizeof (FILE));
if (g == NULL)
return NULL;
p = (FILE *) (g + 1);
g->_next = NULL;
g->_niobs = n;
g->_iobs = p;
memset (p, 0, n * sizeof (FILE));
return g;
g->glue._next = NULL;
g->glue._niobs = n;
g->glue._iobs = &g->file;
memset (&g->file, 0, n * sizeof (FILE));
return &g->glue;
}
/*
@@ -108,7 +116,7 @@ _DEFUN(__sfp, (d),
int n;
struct _glue *g;
__sfp_lock_acquire ();
_newlib_sfp_lock_start ();
if (!_GLOBAL_REENT->__sdidinit)
__sinit (_GLOBAL_REENT);
@@ -121,7 +129,7 @@ _DEFUN(__sfp, (d),
(g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL)
break;
}
__sfp_lock_release ();
_newlib_sfp_lock_exit ();
d->_errno = ENOMEM;
return NULL;
@@ -132,7 +140,7 @@ found:
#ifndef __SINGLE_THREAD__
__lock_init_recursive (fp->_lock);
#endif
__sfp_lock_release ();
_newlib_sfp_lock_end ();
fp->_p = NULL; /* no current pointer */
fp->_w = 0; /* nothing to read or write */
@@ -192,7 +200,6 @@ _DEFUN(__sinit, (s),
/* make sure we clean up on exit */
s->__cleanup = _cleanup_r; /* conservative */
s->__sdidinit = 1;
s->__sglue._next = NULL;
#ifndef _REENT_SMALL
@@ -201,6 +208,11 @@ _DEFUN(__sinit, (s),
#else
s->__sglue._niobs = 0;
s->__sglue._iobs = NULL;
/* Avoid infinite recursion when calling __sfp for _GLOBAL_REENT. The
problem is that __sfp checks for _GLOBAL_REENT->__sdidinit and calls
__sinit if it's 0. */
if (s == _GLOBAL_REENT)
s->__sdidinit = 1;
s->_stdin = __sfp(s);
s->_stdout = __sfp(s);
s->_stderr = __sfp(s);
@@ -224,6 +236,8 @@ _DEFUN(__sinit, (s),
when the underlying fd 2 is write-only. */
std (s->_stderr, __SRW | __SNBF, 2, s);
s->__sdidinit = 1;
__sinit_lock_release ();
}
@@ -235,25 +249,25 @@ __LOCK_INIT_RECURSIVE(static, __sinit_lock);
_VOID
_DEFUN_VOID(__sfp_lock_acquire)
{
__lock_acquire_recursive (__sfp_lock);
//__lock_acquire_recursive (__sfp_lock);
}
_VOID
_DEFUN_VOID(__sfp_lock_release)
{
__lock_release_recursive (__sfp_lock);
//__lock_release_recursive (__sfp_lock);
}
_VOID
_DEFUN_VOID(__sinit_lock_acquire)
{
__lock_acquire_recursive (__sinit_lock);
//__lock_acquire_recursive (__sinit_lock);
}
_VOID
_DEFUN_VOID(__sinit_lock_release)
{
__lock_release_recursive (__sinit_lock);
//__lock_release_recursive (__sinit_lock);
}
/* Walkable file locking routine. */

View File

@@ -60,27 +60,40 @@ _DEFUN(__sflags, (ptr, mode, optr),
ptr->_errno = EINVAL;
return (0);
}
if (mode[1] && (mode[1] == '+' || mode[2] == '+'))
while (*++mode)
{
switch (*mode)
{
case '+':
ret = (ret & ~(__SRD | __SWR)) | __SRW;
m = O_RDWR;
}
if (mode[1] && (mode[1] == 'b' || mode[2] == 'b'))
{
m = (m & ~O_ACCMODE) | O_RDWR;
break;
case 'b':
#ifdef O_BINARY
m |= O_BINARY;
#endif
}
break;
#ifdef __CYGWIN__
else if (mode[1] && (mode[1] == 't' || mode[2] == 't'))
#else
else
case 't':
m |= O_TEXT;
break;
#endif
{
#ifdef O_TEXT
#if defined (O_CLOEXEC) && defined (_GLIBC_EXTENSION)
case 'e':
m |= O_CLOEXEC;
break;
#endif
case 'x':
m |= O_EXCL;
break;
default:
break;
}
}
#if defined (O_TEXT) && !defined (__CYGWIN__)
if (!(m | O_BINARY))
m |= O_TEXT;
#endif
}
*optr = m | o;
return ret;
}

View File

@@ -126,8 +126,8 @@ static char sccsid[] = "%W% (Berkeley) %G%";
FILE *
_DEFUN(_fopen_r, (ptr, file, mode),
struct _reent *ptr _AND
_CONST char *file _AND
_CONST char *mode)
_CONST char *__restrict file _AND
_CONST char *__restrict mode)
{
register FILE *fp;
register int f;
@@ -140,16 +140,16 @@ _DEFUN(_fopen_r, (ptr, file, mode),
if ((f = _open_r (ptr, file, oflags, 0666)) < 0)
{
__sfp_lock_acquire ();
_newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
__sfp_lock_release ();
_newlib_sfp_lock_end ();
return NULL;
}
_flockfile (fp);
_newlib_flockfile_start (fp);
fp->_file = f;
fp->_flags = flags;
@@ -167,7 +167,7 @@ _DEFUN(_fopen_r, (ptr, file, mode),
fp->_flags |= __SCLE;
#endif
_funlockfile (fp);
_newlib_flockfile_end (fp);
return fp;
}

View File

@@ -24,8 +24,8 @@
int
_DEFUN(_fprintf_r, (ptr, fp, fmt),
struct _reent *ptr _AND
FILE *fp _AND
const char *fmt _DOTS)
FILE *__restrict fp _AND
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;
@@ -40,8 +40,8 @@ _DEFUN(_fprintf_r, (ptr, fp, fmt),
int
_DEFUN(fprintf, (fp, fmt),
FILE *fp _AND
const char *fmt _DOTS)
FILE *__restrict fp _AND
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;

View File

@@ -83,9 +83,9 @@ _DEFUN(_fputc_r, (ptr, ch, file),
{
int result;
CHECK_INIT(ptr, file);
_flockfile (file);
_newlib_flockfile_start (file);
result = _putc_r (ptr, ch, file);
_funlockfile (file);
_newlib_flockfile_end (file);
return result;
}
@@ -97,10 +97,12 @@ _DEFUN(fputc, (ch, file),
{
#if !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
int result;
CHECK_INIT(_REENT, file);
_flockfile (file);
result = _putc_r (_REENT, ch, file);
_funlockfile (file);
struct _reent *reent = _REENT;
CHECK_INIT(reent, file);
_newlib_flockfile_start (file);
result = _putc_r (reent, ch, file);
_newlib_flockfile_end (file);
return result;
#else
return _fputc_r (_REENT, ch, file);

View File

@@ -26,10 +26,10 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
int fputs(const char *<[s]>, FILE *<[fp]>);
int fputs(const char *restrict <[s]>, FILE *restrict <[fp]>);
#include <stdio.h>
int _fputs_r(struct _reent *<[ptr]>, const char *<[s]>, FILE *<[fp]>);
int _fputs_r(struct _reent *<[ptr]>, const char *restrict <[s]>, FILE *restrict <[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
@@ -74,9 +74,10 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
int
_DEFUN(_fputs_r, (ptr, s, fp),
struct _reent * ptr _AND
char _CONST * s _AND
FILE * fp)
char _CONST *__restrict s _AND
FILE *__restrict fp)
{
#ifdef _FVWRITE_IN_STREAMIO
int result;
struct __suio uio;
struct __siov iov;
@@ -88,18 +89,41 @@ _DEFUN(_fputs_r, (ptr, s, fp),
CHECK_INIT(ptr, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
result = __sfvwrite_r (ptr, fp, &uio);
_funlockfile (fp);
_newlib_flockfile_end (fp);
return result;
#else
_CONST char *p = s;
CHECK_INIT(ptr, fp);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
/* Make sure we can write. */
if (cantwrite (ptr, fp))
goto error;
while (*p)
{
if (__sputc_r (ptr, *p++, fp) == EOF)
goto error;
}
_newlib_flockfile_exit (fp);
return 0;
error:
_newlib_flockfile_end (fp);
return EOF;
#endif
}
#ifndef _REENT_ONLY
int
_DEFUN(fputs, (s, fp),
char _CONST * s _AND
FILE * fp)
char _CONST *__restrict s _AND
FILE *__restrict fp)
{
return _fputs_r (_REENT, s, fp);
}

View File

@@ -160,10 +160,10 @@ _DEFUN(_fputwc_r, (ptr, wc, fp),
{
wint_t r;
_flockfile (fp);
_newlib_flockfile_start (fp);
ORIENT(fp, 1);
r = __fputwc(ptr, wc, fp);
_funlockfile (fp);
_newlib_flockfile_end (fp);
return r;
}
@@ -172,6 +172,8 @@ _DEFUN(fputwc, (wc, fp),
wchar_t wc _AND
FILE *fp)
{
CHECK_INIT(_REENT, fp);
return _fputwc_r (_REENT, wc, fp);
struct _reent *reent = _REENT;
CHECK_INIT(reent, fp);
return _fputwc_r (reent, wc, fp);
}

View File

@@ -26,12 +26,12 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>,
FILE *<[fp]>);
size_t fread(void *restrict <[buf]>, size_t <[size]>, size_t <[count]>,
FILE *restrict <[fp]>);
#include <stdio.h>
size_t _fread_r(struct _reent *<[ptr]>, void *<[buf]>,
size_t <[size]>, size_t <[count]>, FILE *<[fp]>);
size_t _fread_r(struct _reent *<[ptr]>, void *restrict <[buf]>,
size_t <[size]>, size_t <[count]>, FILE *restrict <[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
@@ -131,10 +131,10 @@ _DEFUN(crlf_r, (ptr, fp, buf, count, eof),
size_t
_DEFUN(_fread_r, (ptr, buf, size, count, fp),
struct _reent * ptr _AND
_PTR buf _AND
_PTR __restrict buf _AND
size_t size _AND
size_t count _AND
FILE * fp)
FILE * __restrict fp)
{
register size_t resid;
register char *p;
@@ -146,7 +146,7 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
CHECK_INIT(ptr, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
if (fp->_r < 0)
fp->_r = 0;
@@ -195,11 +195,11 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return crlf_r (ptr, fp, buf, total-resid, 1) / size;
}
#endif
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return (total - resid) / size;
}
}
@@ -220,11 +220,11 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return crlf_r (ptr, fp, buf, total-resid, 1) / size;
}
#endif
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return (total - resid) / size;
}
}
@@ -237,21 +237,21 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return crlf_r(ptr, fp, buf, total, 0) / size;
}
#endif
_funlockfile (fp);
_newlib_flockfile_end (fp);
return count;
}
#ifndef _REENT_ONLY
size_t
_DEFUN(fread, (buf, size, count, fp),
_PTR buf _AND
_PTR __restrict buf _AND
size_t size _AND
size_t count _AND
FILE * fp)
FILE *__restrict fp)
{
return _fread_r (_REENT, buf, size, count, fp);
}

View File

@@ -26,10 +26,10 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
FILE *freopen(const char *<[file]>, const char *<[mode]>,
FILE *<[fp]>);
FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>,
const char *<[mode]>, FILE *<[fp]>);
FILE *freopen(const char *restrict <[file]>, const char *restrict <[mode]>,
FILE *restrict <[fp]>);
FILE *_freopen_r(struct _reent *<[ptr]>, const char *restrict <[file]>,
const char *restrict <[mode]>, FILE *restrict <[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
@@ -90,9 +90,9 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
FILE *
_DEFUN(_freopen_r, (ptr, file, mode, fp),
struct _reent *ptr _AND
const char *file _AND
const char *mode _AND
register FILE *fp)
const char *__restrict file _AND
const char *__restrict mode _AND
register FILE *__restrict fp)
{
register int f;
int flags, oflags;
@@ -100,11 +100,20 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
CHECK_INIT (ptr, fp);
/* We can't use the _newlib_flockfile_XXX macros here due to the
interlocked locking with the sfp_lock. */
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
int __oldcancel;
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
#endif
_flockfile (fp);
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
_funlockfile (fp);
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
pthread_setcancelstate (__oldcancel, &__oldcancel);
#endif
_fclose_r (ptr, fp);
return NULL;
}
@@ -199,7 +208,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
if (HASLB (fp))
FREELB (ptr, fp);
fp->_lb._size = 0;
fp->_flags & ~__SORD;
fp->_flags &= ~__SORD;
fp->_flags2 = 0;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
@@ -213,6 +222,9 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
__lock_close_recursive (fp->_lock);
#endif
__sfp_lock_release ();
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
pthread_setcancelstate (__oldcancel, &__oldcancel);
#endif
return NULL;
}
@@ -230,6 +242,9 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
#endif
_funlockfile (fp);
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
pthread_setcancelstate (__oldcancel, &__oldcancel);
#endif
return fp;
}
@@ -237,9 +252,9 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
FILE *
_DEFUN(freopen, (file, mode, fp),
_CONST char *file _AND
_CONST char *mode _AND
register FILE *fp)
_CONST char *__restrict file _AND
_CONST char *__restrict mode _AND
register FILE *__restrict fp)
{
return _freopen_r (_REENT, file, mode, fp);
}

View File

@@ -29,7 +29,7 @@
int
#ifdef _HAVE_STDC
fscanf(FILE *fp, _CONST char *fmt, ...)
fscanf(FILE *__restrict fp, _CONST char *__restrict fmt, ...)
#else
fscanf(FILE *fp, fmt, va_alist)
FILE *fp;
@@ -54,7 +54,7 @@ fscanf(FILE *fp, fmt, va_alist)
int
#ifdef _HAVE_STDC
_fscanf_r(struct _reent *ptr, FILE *fp, _CONST char *fmt, ...)
_fscanf_r(struct _reent *ptr, FILE *__restrict fp, _CONST char *__restrict fmt, ...)
#else
_fscanf_r(ptr, FILE *fp, fmt, va_alist)
struct _reent *ptr;

View File

@@ -101,21 +101,9 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include "local.h"
#define POS_ERR (-(_fpos_t)1)
/*
* Seek the given file to the given offset.
* `Whence' must be one of the three SEEK_* macros.
*/
int
_DEFUN(_fseek_r, (ptr, fp, offset, whence),
struct _reent *ptr _AND
@@ -123,264 +111,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
long offset _AND
int whence)
{
_fpos_t _EXFNPTR(seekfn, (struct _reent *, _PTR, _fpos_t, int));
_fpos_t target;
_fpos_t curoff = 0;
size_t n;
#ifdef __USE_INTERNAL_STAT64
struct stat64 st;
#else
struct stat st;
#endif
int havepos;
/* Make sure stdio is set up. */
CHECK_INIT (ptr, fp);
_flockfile (fp);
/* If we've been doing some writing, and we're in append mode
then we don't really know where the filepos is. */
if (fp->_flags & __SAPP && fp->_flags & __SWR)
{
/* So flush the buffer and seek to the end. */
_fflush_r (ptr, fp);
}
/* Have to be able to seek. */
if ((seekfn = fp->_seek) == NULL)
{
ptr->_errno = ESPIPE; /* ??? */
_funlockfile (fp);
return EOF;
}
/*
* Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
* After this, whence is either SEEK_SET or SEEK_END.
*/
switch (whence)
{
case SEEK_CUR:
/*
* In order to seek relative to the current stream offset,
* we have to first find the current stream offset a la
* ftell (see ftell for details).
*/
_fflush_r (ptr, fp); /* may adjust seek offset on append stream */
if (fp->_flags & __SOFF)
curoff = fp->_offset;
else
{
curoff = seekfn (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
if (curoff == -1L)
{
_funlockfile (fp);
return EOF;
}
}
if (fp->_flags & __SRD)
{
curoff -= fp->_r;
if (HASUB (fp))
curoff -= fp->_ur;
}
else if (fp->_flags & __SWR && fp->_p != NULL)
curoff += fp->_p - fp->_bf._base;
offset += curoff;
whence = SEEK_SET;
havepos = 1;
break;
case SEEK_SET:
case SEEK_END:
havepos = 0;
break;
default:
ptr->_errno = EINVAL;
_funlockfile (fp);
return (EOF);
}
/*
* Can only optimise if:
* reading (and not reading-and-writing);
* not unbuffered; and
* this is a `regular' Unix file (and hence seekfn==__sseek).
* We must check __NBF first, because it is possible to have __NBF
* and __SOPT both set.
*/
if (fp->_bf._base == NULL)
__smakebuf_r (ptr, fp);
if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
goto dumb;
if ((fp->_flags & __SOPT) == 0)
{
if (seekfn != __sseek
|| fp->_file < 0
#ifdef __USE_INTERNAL_STAT64
|| _fstat64_r (ptr, fp->_file, &st)
#else
|| _fstat_r (ptr, fp->_file, &st)
#endif
|| (st.st_mode & S_IFMT) != S_IFREG)
{
fp->_flags |= __SNPT;
goto dumb;
}
#ifdef HAVE_BLKSIZE
fp->_blksize = st.st_blksize;
#else
fp->_blksize = 1024;
#endif
fp->_flags |= __SOPT;
}
/*
* We are reading; we can try to optimise.
* Figure out where we are going and where we are now.
*/
if (whence == SEEK_SET)
target = offset;
else
{
#ifdef __USE_INTERNAL_STAT64
if (_fstat64_r (ptr, fp->_file, &st))
#else
if (_fstat_r (ptr, fp->_file, &st))
#endif
goto dumb;
target = st.st_size + offset;
}
if ((long)target != target)
{
ptr->_errno = EOVERFLOW;
_funlockfile (fp);
return EOF;
}
if (!havepos)
{
if (fp->_flags & __SOFF)
curoff = fp->_offset;
else
{
curoff = seekfn (ptr, fp->_cookie, 0L, SEEK_CUR);
if (curoff == POS_ERR)
goto dumb;
}
curoff -= fp->_r;
if (HASUB (fp))
curoff -= fp->_ur;
}
/*
* Compute the number of bytes in the input buffer (pretending
* that any ungetc() input has been discarded). Adjust current
* offset backwards by this count so that it represents the
* file offset for the first byte in the current input buffer.
*/
if (HASUB (fp))
{
curoff += fp->_r; /* kill off ungetc */
n = fp->_up - fp->_bf._base;
curoff -= n;
n += fp->_ur;
}
else
{
n = fp->_p - fp->_bf._base;
curoff -= n;
n += fp->_r;
}
/*
* If the target offset is within the current buffer,
* simply adjust the pointers, clear EOF, undo ungetc(),
* and return.
*/
if (target >= curoff && target < curoff + n)
{
register int o = target - curoff;
fp->_p = fp->_bf._base + o;
fp->_r = n - o;
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_flags &= ~__SEOF;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_funlockfile (fp);
return 0;
}
/*
* The place we want to get to is not within the current buffer,
* but we can still be kind to the kernel copyout mechanism.
* By aligning the file offset to a block boundary, we can let
* the kernel use the VM hardware to map pages instead of
* copying bytes laboriously. Using a block boundary also
* ensures that we only read one block, rather than two.
*/
curoff = target & ~(fp->_blksize - 1);
if (seekfn (ptr, fp->_cookie, curoff, SEEK_SET) == POS_ERR)
goto dumb;
fp->_r = 0;
fp->_p = fp->_bf._base;
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_flags &= ~__SEOF;
n = target - curoff;
if (n)
{
if (__srefill_r (ptr, fp) || fp->_r < n)
goto dumb;
fp->_p += n;
fp->_r -= n;
}
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_funlockfile (fp);
return 0;
/*
* We get here if we cannot optimise the seek ... just
* do it. Allow the seek function to change fp->_bf._base.
*/
dumb:
if (_fflush_r (ptr, fp)
|| seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR)
{
_funlockfile (fp);
return EOF;
}
/* success: clear EOF indicator and discard ungetc() data */
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_p = fp->_bf._base;
fp->_r = 0;
/* fp->_w = 0; *//* unnecessary (I think...) */
fp->_flags &= ~__SEOF;
/* Reset no-optimization flag after successful seek. The
no-optimization flag may be set in the case of a read
stream that is flushed which by POSIX/SUSv3 standards,
means that a corresponding seek must not optimize. The
optimization is then allowed if no subsequent flush
is performed. */
fp->_flags &= ~__SNPT;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_funlockfile (fp);
return 0;
return _fseeko_r (ptr, fp, offset, whence);
}
#ifndef _REENT_ONLY

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, Red Hat Inc.
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
@@ -15,9 +15,106 @@
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
FUNCTION
<<fseek>>, <<fseeko>>---set file position
INDEX
fseek
INDEX
fseeko
INDEX
_fseek_r
INDEX
_fseeko_r
ANSI_SYNOPSIS
#include <stdio.h>
int fseek(FILE *<[fp]>, long <[offset]>, int <[whence]>)
int fseeko(FILE *<[fp]>, off_t <[offset]>, int <[whence]>)
int _fseek_r(struct _reent *<[ptr]>, FILE *<[fp]>,
long <[offset]>, int <[whence]>)
int _fseeko_r(struct _reent *<[ptr]>, FILE *<[fp]>,
off_t <[offset]>, int <[whence]>)
TRAD_SYNOPSIS
#include <stdio.h>
int fseek(<[fp]>, <[offset]>, <[whence]>)
FILE *<[fp]>;
long <[offset]>;
int <[whence]>;
int fseeko(<[fp]>, <[offset]>, <[whence]>)
FILE *<[fp]>;
off_t <[offset]>;
int <[whence]>;
int _fseek_r(<[ptr]>, <[fp]>, <[offset]>, <[whence]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
long <[offset]>;
int <[whence]>;
int _fseeko_r(<[ptr]>, <[fp]>, <[offset]>, <[whence]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
off_t <[offset]>;
int <[whence]>;
DESCRIPTION
Objects of type <<FILE>> can have a ``position'' that records how much
of the file your program has already read. Many of the <<stdio>> functions
depend on this position, and many change it as a side effect.
You can use <<fseek>>/<<fseeko>> to set the position for the file identified by
<[fp]>. The value of <[offset]> determines the new position, in one
of three ways selected by the value of <[whence]> (defined as macros
in `<<stdio.h>>'):
<<SEEK_SET>>---<[offset]> is the absolute file position (an offset
from the beginning of the file) desired. <[offset]> must be positive.
<<SEEK_CUR>>---<[offset]> is relative to the current file position.
<[offset]> can meaningfully be either positive or negative.
<<SEEK_END>>---<[offset]> is relative to the current end of file.
<[offset]> can meaningfully be either positive (to increase the size
of the file) or negative.
See <<ftell>>/<<ftello>> to determine the current file position.
RETURNS
<<fseek>>/<<fseeko>> return <<0>> when successful. On failure, the
result is <<EOF>>. The reason for failure is indicated in <<errno>>:
either <<ESPIPE>> (the stream identified by <[fp]> doesn't support
repositioning) or <<EINVAL>> (invalid file position).
PORTABILITY
ANSI C requires <<fseek>>.
<<fseeko>> is defined by the Single Unix specification.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include "local.h"
#define POS_ERR (-(_fpos_t)1)
/*
* Seek the given file to the given offset.
* `Whence' must be one of the three SEEK_* macros.
*/
int
_DEFUN(_fseeko_r, (ptr, fp, offset, whence),
@@ -26,7 +123,261 @@ _DEFUN(_fseeko_r, (ptr, fp, offset, whence),
_off_t offset _AND
int whence)
{
return _fseek_r (ptr, fp, (long)offset, whence);
_fpos_t _EXFNPTR(seekfn, (struct _reent *, _PTR, _fpos_t, int));
_fpos_t target;
_fpos_t curoff = 0;
size_t n;
#ifdef __USE_INTERNAL_STAT64
struct stat64 st;
#else
struct stat st;
#endif
int havepos;
/* Make sure stdio is set up. */
CHECK_INIT (ptr, fp);
_newlib_flockfile_start (fp);
/* If we've been doing some writing, and we're in append mode
then we don't really know where the filepos is. */
if (fp->_flags & __SAPP && fp->_flags & __SWR)
{
/* So flush the buffer and seek to the end. */
_fflush_r (ptr, fp);
}
/* Have to be able to seek. */
if ((seekfn = fp->_seek) == NULL)
{
ptr->_errno = ESPIPE; /* ??? */
_newlib_flockfile_exit (fp);
return EOF;
}
/*
* Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
* After this, whence is either SEEK_SET or SEEK_END.
*/
switch (whence)
{
case SEEK_CUR:
/*
* In order to seek relative to the current stream offset,
* we have to first find the current stream offset a la
* ftell (see ftell for details).
*/
_fflush_r (ptr, fp); /* may adjust seek offset on append stream */
if (fp->_flags & __SOFF)
curoff = fp->_offset;
else
{
curoff = seekfn (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
if (curoff == -1L)
{
_newlib_flockfile_exit (fp);
return EOF;
}
}
if (fp->_flags & __SRD)
{
curoff -= fp->_r;
if (HASUB (fp))
curoff -= fp->_ur;
}
else if (fp->_flags & __SWR && fp->_p != NULL)
curoff += fp->_p - fp->_bf._base;
offset += curoff;
whence = SEEK_SET;
havepos = 1;
break;
case SEEK_SET:
case SEEK_END:
havepos = 0;
break;
default:
ptr->_errno = EINVAL;
_newlib_flockfile_exit (fp);
return (EOF);
}
/*
* Can only optimise if:
* reading (and not reading-and-writing);
* not unbuffered; and
* this is a `regular' Unix file (and hence seekfn==__sseek).
* We must check __NBF first, because it is possible to have __NBF
* and __SOPT both set.
*/
if (fp->_bf._base == NULL)
__smakebuf_r (ptr, fp);
#ifdef _FSEEK_OPTIMIZATION
if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
goto dumb;
if ((fp->_flags & __SOPT) == 0)
{
if (seekfn != __sseek
|| fp->_file < 0
#ifdef __USE_INTERNAL_STAT64
|| _fstat64_r (ptr, fp->_file, &st)
#else
|| _fstat_r (ptr, fp->_file, &st)
#endif
|| (st.st_mode & S_IFMT) != S_IFREG)
{
fp->_flags |= __SNPT;
goto dumb;
}
#ifdef HAVE_BLKSIZE
fp->_blksize = st.st_blksize;
#else
fp->_blksize = 1024;
#endif
fp->_flags |= __SOPT;
}
/*
* We are reading; we can try to optimise.
* Figure out where we are going and where we are now.
*/
if (whence == SEEK_SET)
target = offset;
else
{
#ifdef __USE_INTERNAL_STAT64
if (_fstat64_r (ptr, fp->_file, &st))
#else
if (_fstat_r (ptr, fp->_file, &st))
#endif
goto dumb;
target = st.st_size + offset;
}
if (!havepos)
{
if (fp->_flags & __SOFF)
curoff = fp->_offset;
else
{
curoff = seekfn (ptr, fp->_cookie, 0L, SEEK_CUR);
if (curoff == POS_ERR)
goto dumb;
}
curoff -= fp->_r;
if (HASUB (fp))
curoff -= fp->_ur;
}
/*
* Compute the number of bytes in the input buffer (pretending
* that any ungetc() input has been discarded). Adjust current
* offset backwards by this count so that it represents the
* file offset for the first byte in the current input buffer.
*/
if (HASUB (fp))
{
curoff += fp->_r; /* kill off ungetc */
n = fp->_up - fp->_bf._base;
curoff -= n;
n += fp->_ur;
}
else
{
n = fp->_p - fp->_bf._base;
curoff -= n;
n += fp->_r;
}
/*
* If the target offset is within the current buffer,
* simply adjust the pointers, clear EOF, undo ungetc(),
* and return.
*/
if (target >= curoff && target < curoff + n)
{
register int o = target - curoff;
fp->_p = fp->_bf._base + o;
fp->_r = n - o;
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_flags &= ~__SEOF;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_newlib_flockfile_exit (fp);
return 0;
}
/*
* The place we want to get to is not within the current buffer,
* but we can still be kind to the kernel copyout mechanism.
* By aligning the file offset to a block boundary, we can let
* the kernel use the VM hardware to map pages instead of
* copying bytes laboriously. Using a block boundary also
* ensures that we only read one block, rather than two.
*/
curoff = target & ~(fp->_blksize - 1);
if (seekfn (ptr, fp->_cookie, curoff, SEEK_SET) == POS_ERR)
goto dumb;
fp->_r = 0;
fp->_p = fp->_bf._base;
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_flags &= ~__SEOF;
n = target - curoff;
if (n)
{
if (__srefill_r (ptr, fp) || fp->_r < n)
goto dumb;
fp->_p += n;
fp->_r -= n;
}
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_newlib_flockfile_exit (fp);
return 0;
/*
* We get here if we cannot optimise the seek ... just
* do it. Allow the seek function to change fp->_bf._base.
*/
#endif
dumb:
if (_fflush_r (ptr, fp)
|| seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR)
{
_newlib_flockfile_exit (fp);
return EOF;
}
/* success: clear EOF indicator and discard ungetc() data */
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_p = fp->_bf._base;
fp->_r = 0;
/* fp->_w = 0; *//* unnecessary (I think...) */
fp->_flags &= ~__SEOF;
/* Reset no-optimization flag after successful seek. The
no-optimization flag may be set in the case of a read
stream that is flushed which by POSIX/SUSv3 standards,
means that a corresponding seek must not optimize. The
optimization is then allowed if no subsequent flush
is performed. */
fp->_flags &= ~__SNPT;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_newlib_flockfile_end (fp);
return 0;
}
#ifndef _REENT_ONLY
@@ -37,8 +388,7 @@ _DEFUN(fseeko, (fp, offset, whence),
_off_t offset _AND
int whence)
{
/* for now we simply cast since off_t should be long */
return _fseek_r (_REENT, fp, (long)offset, whence);
return _fseeko_r (_REENT, fp, offset, whence);
}
#endif /* !_REENT_ONLY */

View File

@@ -105,64 +105,13 @@ _DEFUN(_ftell_r, (ptr, fp),
{
_fpos_t pos;
/* Ensure stdio is set up. */
CHECK_INIT (ptr, fp);
_flockfile (fp);
if (fp->_seek == NULL)
{
ptr->_errno = ESPIPE;
_funlockfile (fp);
return -1L;
}
/* Find offset of underlying I/O object, then adjust for buffered
bytes. Flush a write stream, since the offset may be altered if
the stream is appending. Do not flush a read stream, since we
must not lose the ungetc buffer. */
if (fp->_flags & __SWR)
_fflush_r (ptr, fp);
if (fp->_flags & __SOFF)
pos = fp->_offset;
else
{
pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
if (pos == -1L)
{
_funlockfile (fp);
return pos;
}
}
if (fp->_flags & __SRD)
{
/*
* Reading. Any unread characters (including
* those from ungetc) cause the position to be
* smaller than that in the underlying object.
*/
pos -= fp->_r;
if (HASUB (fp))
pos -= fp->_ur;
}
else if ((fp->_flags & __SWR) && fp->_p != NULL)
{
/*
* Writing. Any buffered characters cause the
* position to be greater than that in the
* underlying object.
*/
pos += fp->_p - fp->_bf._base;
}
_funlockfile (fp);
pos = _ftello_r (ptr, fp);
if ((long)pos != pos)
{
pos = -1;
ptr->_errno = EOVERFLOW;
}
return pos;
return (long)pos;
}
#ifndef _REENT_ONLY

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, Red Hat Inc.
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
@@ -15,17 +15,149 @@
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
FUNCTION
<<ftell>>, <<ftello>>---return position in a stream or file
INDEX
ftell
INDEX
ftello
INDEX
_ftell_r
INDEX
_ftello_r
ANSI_SYNOPSIS
#include <stdio.h>
long ftell(FILE *<[fp]>);
off_t ftello(FILE *<[fp]>);
long _ftell_r(struct _reent *<[ptr]>, FILE *<[fp]>);
off_t _ftello_r(struct _reent *<[ptr]>, FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
long ftell(<[fp]>)
FILE *<[fp]>;
off_t ftello(<[fp]>)
FILE *<[fp]>;
long _ftell_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
off_t _ftello_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
DESCRIPTION
Objects of type <<FILE>> can have a ``position'' that records how much
of the file your program has already read. Many of the <<stdio>> functions
depend on this position, and many change it as a side effect.
The result of <<ftell>>/<<ftello>> is the current position for a file
identified by <[fp]>. If you record this result, you can later
use it with <<fseek>>/<<fseeko>> to return the file to this
position. The difference between <<ftell>> and <<ftello>> is that
<<ftell>> returns <<long>> and <<ftello>> returns <<off_t>>.
In the current implementation, <<ftell>>/<<ftello>> simply uses a character
count to represent the file position; this is the same number that
would be recorded by <<fgetpos>>.
RETURNS
<<ftell>>/<<ftello>> return the file position, if possible. If they cannot do
this, they return <<-1L>>. Failure occurs on streams that do not support
positioning; the global <<errno>> indicates this condition with the
value <<ESPIPE>>.
PORTABILITY
<<ftell>> is required by the ANSI C standard, but the meaning of its
result (when successful) is not specified beyond requiring that it be
acceptable as an argument to <<fseek>>. In particular, other
conforming C implementations may return a different result from
<<ftell>> than what <<fgetpos>> records.
<<ftello>> is defined by the Single Unix specification.
No supporting OS subroutines are required.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
/*
* ftello: return current offset.
*/
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
_off_t
_DEFUN(_ftello_r, (ptr, fp),
struct _reent * ptr _AND
register FILE * fp)
{
/* for now we simply cast since off_t should be long */
return (_off_t)_ftell_r (ptr, fp);
_fpos_t pos;
/* Ensure stdio is set up. */
CHECK_INIT (ptr, fp);
_newlib_flockfile_start (fp);
if (fp->_seek == NULL)
{
ptr->_errno = ESPIPE;
_newlib_flockfile_exit (fp);
return -1L;
}
/* Find offset of underlying I/O object, then adjust for buffered
bytes. Flush a write stream, since the offset may be altered if
the stream is appending. Do not flush a read stream, since we
must not lose the ungetc buffer. */
if (fp->_flags & __SWR)
_fflush_r (ptr, fp);
if (fp->_flags & __SOFF)
pos = fp->_offset;
else
{
pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
if (pos == -1L)
{
_newlib_flockfile_exit (fp);
return pos;
}
}
if (fp->_flags & __SRD)
{
/*
* Reading. Any unread characters (including
* those from ungetc) cause the position to be
* smaller than that in the underlying object.
*/
pos -= fp->_r;
if (HASUB (fp))
pos -= fp->_ur;
}
else if ((fp->_flags & __SWR) && fp->_p != NULL)
{
/*
* Writing. Any buffered characters cause the
* position to be greater than that in the
* underlying object.
*/
pos += fp->_p - fp->_bf._base;
}
_newlib_flockfile_end (fp);
return pos;
}
#ifndef _REENT_ONLY
@@ -34,7 +166,7 @@ _off_t
_DEFUN(ftello, (fp),
register FILE * fp)
{
return (_off_t)_ftell_r (_REENT, fp);
return _ftello_r (_REENT, fp);
}
#endif /* !_REENT_ONLY */

View File

@@ -21,6 +21,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include "local.h"
#include "fvwrite.h"
@@ -52,7 +53,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
register size_t len;
register _CONST char *p = NULL;
register struct __siov *iov;
register int w, s;
register _READ_WRITE_RETURN_TYPE w, s;
char *nl;
int nlknown, nldist;
@@ -89,12 +90,14 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
if (fp->_flags & __SNBF)
{
/*
* Unbuffered: write up to BUFSIZ bytes at a time.
* Unbuffered: Split buffer in the largest multiple of BUFSIZ < INT_MAX
* as some legacy code may expect int instead of size_t.
*/
do
{
GETIOV (;);
w = fp->_write (ptr, fp->_cookie, p, MIN (len, BUFSIZ));
w = fp->_write (ptr, fp->_cookie, p,
MIN (len, INT_MAX - INT_MAX % BUFSIZ));
if (w <= 0)
goto err;
p += w;
@@ -155,8 +158,10 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
newsize);
if (!str)
{
/* Free buffer which is no longer used. */
/* Free buffer which is no longer used and clear
__SMBF flag to avoid double free in fclose. */
_free_r (ptr, fp->_bf._base);
fp->_flags &= ~__SMBF;
/* Ensure correct errno, even if free changed it. */
ptr->_errno = ENOMEM;
goto err;
@@ -175,29 +180,23 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
fp->_p += w;
w = len; /* but pretend copied all */
}
else if (fp->_p > fp->_bf._base && len > w)
else if (fp->_p > fp->_bf._base || len < fp->_bf._size)
{
/* fill and flush */
/* pass through the buffer */
w = MIN (len, w);
COPY (w);
/* fp->_w -= w; *//* unneeded */
fp->_w -= w;
fp->_p += w;
if (_fflush_r (ptr, fp))
goto err;
}
else if (len >= (w = fp->_bf._size))
{
/* write directly */
w = fp->_write (ptr, fp->_cookie, p, w);
if (w <= 0)
if (fp->_w == 0 && _fflush_r (ptr, fp))
goto err;
}
else
{
/* fill and done */
w = len;
COPY (w);
fp->_w -= w;
fp->_p += w;
/* write directly */
w = ((int)MIN (len, INT_MAX)) / fp->_bf._size * fp->_bf._size;
w = fp->_write (ptr, fp->_cookie, p, w);
if (w <= 0)
goto err;
}
p += w;
len -= w;

View File

@@ -28,7 +28,7 @@ struct __siov {
struct __suio {
struct __siov *uio_iov;
int uio_iovcnt;
int uio_resid;
size_t uio_resid;
};

View File

@@ -46,11 +46,8 @@ _DEFUN(_fwalk, (ptr, function),
*/
for (g = &ptr->__sglue; g != NULL; g = g->_next)
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
if (fp->_flags != 0)
{
if (fp->_flags != 0 && fp->_flags != 1 && fp->_file != -1)
ret |= (*function) (fp);
}
return ret;
}

View File

@@ -26,12 +26,12 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
size_t fwrite(const void *<[buf]>, size_t <[size]>,
size_t <[count]>, FILE *<[fp]>);
size_t fwrite(const void *restrict <[buf]>, size_t <[size]>,
size_t <[count]>, FILE *restrict <[fp]>);
#include <stdio.h>
size_t _fwrite_r(struct _reent *<[ptr]>, const void *<[buf]>, size_t <[size]>,
size_t <[count]>, FILE *<[fp]>);
size_t _fwrite_r(struct _reent *<[ptr]>, const void *restrict <[buf]>, size_t <[size]>,
size_t <[count]>, FILE *restrict <[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
@@ -97,12 +97,13 @@ static char sccsid[] = "%W% (Berkeley) %G%";
size_t
_DEFUN(_fwrite_r, (ptr, buf, size, count, fp),
struct _reent * ptr _AND
_CONST _PTR buf _AND
_CONST _PTR __restrict buf _AND
size_t size _AND
size_t count _AND
FILE * fp)
FILE * __restrict fp)
{
size_t n;
#ifdef _FVWRITE_IN_STREAMIO
struct __suio uio;
struct __siov iov;
@@ -119,21 +120,45 @@ _DEFUN(_fwrite_r, (ptr, buf, size, count, fp),
CHECK_INIT(ptr, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
if (__sfvwrite_r (ptr, fp, &uio) == 0)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return count;
}
_funlockfile (fp);
_newlib_flockfile_end (fp);
return (n - uio.uio_resid) / size;
#else
size_t i = 0;
_CONST char *p = buf;
n = count * size;
CHECK_INIT (ptr, fp);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
/* Make sure we can write. */
if (cantwrite (ptr, fp))
goto ret;
while (i < n)
{
if (__sputc_r (ptr, p[i], fp) == EOF)
break;
i++;
}
ret:
_newlib_flockfile_end (fp);
return i / size;
#endif
}
#ifndef _REENT_ONLY
size_t
_DEFUN(fwrite, (buf, size, count, fp),
_CONST _PTR buf _AND
_CONST _PTR __restrict buf _AND
size_t size _AND
size_t count _AND
FILE * fp)

View File

@@ -32,6 +32,98 @@
# include <io.h>
#endif
/* The following define determines if the per-reent stdin, stdout and stderr
streams are closed during _reclaim_reent(). The stdin, stdout and stderr
streams are initialized to use file descriptors 0, 1 and 2 respectively. In
case _STDIO_CLOSE_PER_REENT_STD_STREAMS is defined these file descriptors
will be closed via close() provided the owner of the reent structure
triggerd the on demand reent initilization, see CHECK_INIT(). */
#ifndef __rtems__
#define _STDIO_CLOSE_PER_REENT_STD_STREAMS
#endif
/* The following macros are supposed to replace calls to _flockfile/_funlockfile
and __sfp_lock_acquire/__sfp_lock_release. In case of multi-threaded
environments using pthreads, it's not sufficient to lock the stdio functions
against concurrent threads accessing the same data, the locking must also be
secured against thread cancellation.
The below macros have to be used in pairs. The _newlib_XXX_start macro
starts with a opening curly brace, the _newlib_XXX_end macro ends with a
closing curly brace, so the start macro and the end macro mark the code
start and end of a critical section. In case the code leaves the critical
section before reaching the end of the critical section's code end, use
the appropriate _newlib_XXX_exit macro. */
#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS) \
&& !defined (__rtems__)
#define _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
#endif
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
#include <pthread.h>
/* Start a stream oriented critical section: */
# define _newlib_flockfile_start(_fp) \
{ \
int __oldfpcancel; \
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldfpcancel); \
_flockfile (_fp)
/* Exit from a stream oriented critical section prematurely: */
# define _newlib_flockfile_exit(_fp) \
_funlockfile (_fp); \
pthread_setcancelstate (__oldfpcancel, &__oldfpcancel);
/* End a stream oriented critical section: */
# define _newlib_flockfile_end(_fp) \
_funlockfile (_fp); \
pthread_setcancelstate (__oldfpcancel, &__oldfpcancel); \
}
/* Start a stream list oriented critical section: */
# define _newlib_sfp_lock_start() \
{ \
int __oldsfpcancel; \
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldsfpcancel); \
__sfp_lock_acquire ()
/* Exit from a stream list oriented critical section prematurely: */
# define _newlib_sfp_lock_exit() \
__sfp_lock_release (); \
pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel);
/* End a stream list oriented critical section: */
# define _newlib_sfp_lock_end() \
__sfp_lock_release (); \
pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel); \
}
#else /* !_STDIO_WITH_THREAD_CANCELLATION_SUPPORT */
# define _newlib_flockfile_start(_fp) \
{ \
_flockfile(_fp)
# define _newlib_flockfile_exit(_fp) \
_funlockfile(_fp); \
# define _newlib_flockfile_end(_fp) \
_funlockfile(_fp); \
}
# define _newlib_sfp_lock_start() \
{ \
__sfp_lock_acquire ()
# define _newlib_sfp_lock_exit() \
__sfp_lock_release ();
# define _newlib_sfp_lock_end() \
__sfp_lock_release (); \
}
#endif /* _STDIO_WITH_THREAD_CANCELLATION_SUPPORT */
extern u_char *_EXFUN(__sccl, (char *, u_char *fmt));
extern int _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list));
@@ -42,26 +134,28 @@ extern int _EXFUN(__svfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_
extern int _EXFUN(__ssvfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list));
extern int _EXFUN(__svfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list));
extern int _EXFUN(__ssvfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list));
int _EXFUN(_svfprintf_r,(struct _reent *, FILE *, const char *,
int _EXFUN(_svfprintf_r,(struct _reent *, FILE *, const char *,
va_list)
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
int _EXFUN(_svfiprintf_r,(struct _reent *, FILE *, const char *,
int _EXFUN(_svfiprintf_r,(struct _reent *, FILE *, const char *,
va_list)
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
int _EXFUN(_svfwprintf_r,(struct _reent *, FILE *, const wchar_t *,
int _EXFUN(_svfwprintf_r,(struct _reent *, FILE *, const wchar_t *,
va_list));
int _EXFUN(_svfiwprintf_r,(struct _reent *, FILE *, const wchar_t *,
int _EXFUN(_svfiwprintf_r,(struct _reent *, FILE *, const wchar_t *,
va_list));
extern FILE *_EXFUN(__sfp,(struct _reent *));
extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*));
extern int _EXFUN(__sflush_r,(struct _reent *,FILE *));
extern int _EXFUN(__srefill_r,(struct _reent *,FILE *));
extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *,
int));
_READ_WRITE_BUFSIZE_TYPE));
extern _READ_WRITE_RETURN_TYPE _EXFUN(__seofread,(struct _reent *, void *,
char *, int));
char *,
_READ_WRITE_BUFSIZE_TYPE));
extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, void *,
const char *, int));
const char *,
_READ_WRITE_BUFSIZE_TYPE));
extern _fpos_t _EXFUN(__sseek,(struct _reent *, void *, _fpos_t, int));
extern int _EXFUN(__sclose,(struct _reent *, void *));
extern int _EXFUN(__stextmode,(int));
@@ -76,7 +170,8 @@ extern int _EXFUN(__submore, (struct _reent *, FILE *));
#ifdef __LARGE64_FILES
extern _fpos64_t _EXFUN(__sseek64,(struct _reent *, void *, _fpos64_t, int));
extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
const char *, int));
const char *,
_READ_WRITE_BUFSIZE_TYPE));
#endif
/* Called by the main entry point fns to ensure stdio has been initialized. */
@@ -85,22 +180,24 @@ extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
#define CHECK_INIT(ptr, fp) \
do \
{ \
if ((ptr) && !(ptr)->__sdidinit) \
__sinit (ptr); \
struct _reent *_check_init_ptr = (ptr); \
if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit) \
__sinit (_check_init_ptr); \
if ((fp) == (FILE *)&__sf_fake_stdin) \
(fp) = _stdin_r(ptr); \
(fp) = _stdin_r(_check_init_ptr); \
else if ((fp) == (FILE *)&__sf_fake_stdout) \
(fp) = _stdout_r(ptr); \
(fp) = _stdout_r(_check_init_ptr); \
else if ((fp) == (FILE *)&__sf_fake_stderr) \
(fp) = _stderr_r(ptr); \
(fp) = _stderr_r(_check_init_ptr); \
} \
while (0)
#else /* !_REENT_SMALL */
#define CHECK_INIT(ptr, fp) \
do \
{ \
if ((ptr) && !(ptr)->__sdidinit) \
__sinit (ptr); \
struct _reent *_check_init_ptr = (ptr); \
if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit) \
__sinit (_check_init_ptr); \
} \
while (0)
#endif /* !_REENT_SMALL */
@@ -108,8 +205,9 @@ extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
#define CHECK_STD_INIT(ptr) \
do \
{ \
if ((ptr) && !(ptr)->__sdidinit) \
__sinit (ptr); \
struct _reent *_check_init_ptr = (ptr); \
if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit) \
__sinit (_check_init_ptr); \
} \
while (0)
@@ -136,6 +234,7 @@ extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
#define FREELB(ptr, fp) { _free_r(ptr,(char *)(fp)->_lb._base); \
(fp)->_lb._base = NULL; }
#ifdef _WIDE_ORIENT
/*
* Set the orientation for a stream. If o > 0, the stream has wide-
* orientation. If o < 0, the stream has byte-orientation.
@@ -153,6 +252,9 @@ extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
} \
} \
while (0)
#else
#define ORIENT(fp,ori)
#endif
/* WARNING: _dcvt is defined in the stdlib directory, not here! */

View File

@@ -65,8 +65,10 @@ _DEFUN(__smakebuf_r, (ptr, fp),
size = _DEFAULT_ASPRINTF_BUFSIZE;
else
size = BUFSIZ;
#ifdef _FSEEK_OPTIMIZATION
/* do not try to optimise fseek() */
fp->_flags |= __SNPT;
#endif
}
else
{
@@ -76,6 +78,7 @@ _DEFUN(__smakebuf_r, (ptr, fp),
#else
size = BUFSIZ;
#endif
#ifdef _FSEEK_OPTIMIZATION
/*
* Optimize fseek() only if it is a regular file.
* (The test for __sseek is mainly paranoia.)
@@ -91,6 +94,7 @@ _DEFUN(__smakebuf_r, (ptr, fp),
}
else
fp->_flags |= __SNPT;
#endif
}
if ((p = _malloc_r (ptr, size)) == NULL)
{

View File

@@ -25,7 +25,7 @@
int
_DEFUN(_printf_r, (ptr, fmt),
struct _reent *ptr _AND
const char *fmt _DOTS)
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;
@@ -41,7 +41,7 @@ _DEFUN(_printf_r, (ptr, fmt),
int
_DEFUN(printf, (fmt),
const char *fmt _DOTS)
const char *__restrict fmt _DOTS)
{
int ret;
va_list ap;

View File

@@ -97,9 +97,9 @@ _DEFUN(_putc_r, (ptr, c, fp),
{
int result;
CHECK_INIT (ptr, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
result = __sputc_r (ptr, c, fp);
_funlockfile (fp);
_newlib_flockfile_end (fp);
return result;
}
@@ -111,10 +111,12 @@ _DEFUN(putc, (c, fp),
{
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
int result;
CHECK_INIT (_REENT, fp);
_flockfile (fp);
result = __sputc_r (_REENT, c, fp);
_funlockfile (fp);
struct _reent *reent = _REENT;
CHECK_INIT (reent, fp);
_newlib_flockfile_start (fp);
result = __sputc_r (reent, c, fp);
_newlib_flockfile_end (fp);
return result;
#else
return _putc_r (_REENT, c, fp);

View File

@@ -90,8 +90,10 @@ int
_DEFUN(putchar, (c),
int c)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return _putc_r (_REENT, c, _stdout_r (_REENT));
struct _reent *reent = _REENT;
_REENT_SMALL_CHECK_INIT (reent);
return _putc_r (reent, c, _stdout_r (reent));
}
#endif

View File

@@ -78,9 +78,12 @@ _DEFUN(_puts_r, (ptr, s),
struct _reent *ptr _AND
_CONST char * s)
{
#ifdef _FVWRITE_IN_STREAMIO
int result;
size_t c = strlen (s);
struct __suio uio;
struct __siov iov[2];
FILE *fp;
iov[0].iov_base = s;
iov[0].iov_len = c;
@@ -89,9 +92,41 @@ _DEFUN(_puts_r, (ptr, s),
uio.uio_resid = c + 1;
uio.uio_iov = &iov[0];
uio.uio_iovcnt = 2;
_REENT_SMALL_CHECK_INIT (ptr);
ORIENT (stdout, -1);
return (__sfvwrite_r (ptr, _stdout_r (ptr), &uio) ? EOF : '\n');
fp = _stdout_r (ptr);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
result = (__sfvwrite_r (ptr, fp, &uio) ? EOF : '\n');
_newlib_flockfile_end (fp);
return result;
#else
int result = EOF;
const char *p = s;
FILE *fp;
_REENT_SMALL_CHECK_INIT (ptr);
fp = _stdout_r (ptr);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
/* Make sure we can write. */
if (cantwrite (ptr, fp))
goto err;
while (*p)
{
if (__sputc_r (ptr, *p++, fp) == EOF)
goto err;
}
if (__sputc_r (ptr, '\n', fp) == EOF)
goto err;
result = '\n';
err:
_newlib_flockfile_end (fp);
return result;
#endif
}
#ifndef _REENT_ONLY

View File

@@ -66,15 +66,16 @@ Supporting OS subroutine required: <<unlink>>.
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <sys/kos_io.h>
int
_DEFUN(_remove_r, (ptr, filename),
struct _reent *ptr _AND
_CONST char *filename)
{
return delete_file(filename)==0 ? 0: -1;
if (_unlink_r (ptr, filename) == -1)
return -1;
return 0;
}
#ifndef _REENT_ONLY
@@ -83,9 +84,7 @@ int
_DEFUN(remove, (filename),
_CONST char *filename)
{
return delete_file(filename)==0 ? 0: -1;
return _remove_r (_REENT, filename);
}
#endif

View File

@@ -57,16 +57,6 @@ Supporting OS subroutines required: <<link>>, <<unlink>>, or <<rename>>.
#include <stdio.h>
#include <sys/unistd.h>
int
_DEFUN (_rename_r, (ptr, old, new),
struct _reent *ptr _AND
_CONST char *old _AND
_CONST char *new)
{
return -1;
}
#ifndef _REENT_ONLY
int
@@ -74,7 +64,7 @@ _DEFUN(rename, (old, new),
_CONST char *old _AND
_CONST char *new)
{
return -1;
return _rename_r (_REENT, old, new);
}
#endif

View File

@@ -103,10 +103,11 @@ _DEFUN(setvbuf, (fp, buf, mode, size),
register size_t size)
{
int ret = 0;
struct _reent *reent = _REENT;
CHECK_INIT (_REENT, fp);
CHECK_INIT (reent, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
/*
* Verify arguments. The `int' limit on `size' is due to this
@@ -115,7 +116,7 @@ _DEFUN(setvbuf, (fp, buf, mode, size),
if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return (EOF);
}
@@ -126,11 +127,11 @@ _DEFUN(setvbuf, (fp, buf, mode, size),
* non buffer flags, and clear malloc flag.
*/
_fflush_r (_REENT, fp);
_fflush_r (reent, fp);
fp->_r = 0;
fp->_lbfsize = 0;
if (fp->_flags & __SMBF)
_free_r (_REENT, (_PTR) fp->_bf._base);
_free_r (reent, (_PTR) fp->_bf._base);
fp->_flags &= ~(__SLBF | __SNBF | __SMBF);
if (mode == _IONBF)
@@ -158,7 +159,7 @@ nbf:
fp->_w = 0;
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return (ret);
}
fp->_flags |= __SMBF;
@@ -180,7 +181,7 @@ nbf:
case _IOFBF:
/* no flag */
_REENT->__cleanup = _cleanup_r;
reent->__cleanup = _cleanup_r;
fp->_bf._base = fp->_p = (unsigned char *) buf;
fp->_bf._size = size;
break;
@@ -193,6 +194,6 @@ nbf:
if (fp->_flags & __SWR)
fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size;
_funlockfile (fp);
_newlib_flockfile_end (fp);
return 0;
}

View File

@@ -33,9 +33,9 @@ int
#ifdef _HAVE_STDC
_DEFUN(_snprintf_r, (ptr, str, size, fmt),
struct _reent *ptr _AND
char *str _AND
char *__restrict str _AND
size_t size _AND
_CONST char *fmt _DOTS)
_CONST char *__restrict fmt _DOTS)
#else
_snprintf_r(ptr, str, size, fmt, va_alist)
struct _reent *ptr;
@@ -77,9 +77,9 @@ _snprintf_r(ptr, str, size, fmt, va_alist)
int
#ifdef _HAVE_STDC
_DEFUN(snprintf, (str, size, fmt),
char *str _AND
char *__restrict str _AND
size_t size _AND
_CONST char *fmt _DOTS)
_CONST char *__restrict fmt _DOTS)
#else
snprintf(str, size, fmt, va_alist)
char *str;

View File

@@ -47,26 +47,26 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
int printf(const char *<[format]>, ...);
int fprintf(FILE *<[fd]>, const char *<[format]>, ...);
int sprintf(char *<[str]>, const char *<[format]>, ...);
int snprintf(char *<[str]>, size_t <[size]>, const char *<[format]>,
int printf(const char *restrict <[format]>, ...);
int fprintf(FILE *restrict <[fd]>, const char *restrict <[format]>, ...);
int sprintf(char *restrict <[str]>, const char *restrict <[format]>, ...);
int snprintf(char *restrict <[str]>, size_t <[size]>, const char *restrict <[format]>,
...);
int asprintf(char **<[strp]>, const char *<[format]>, ...);
char *asnprintf(char *<[str]>, size_t *<[size]>, const char *<[format]>,
int asprintf(char **restrict <[strp]>, const char *restrict <[format]>, ...);
char *asnprintf(char *restrict <[str]>, size_t *restrict <[size]>, const char *restrict <[format]>,
...);
int _printf_r(struct _reent *<[ptr]>, const char *<[format]>, ...);
int _fprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>,
const char *<[format]>, ...);
int _sprintf_r(struct _reent *<[ptr]>, char *<[str]>,
const char *<[format]>, ...);
int _snprintf_r(struct _reent *<[ptr]>, char *<[str]>, size_t <[size]>,
const char *<[format]>, ...);
int _asprintf_r(struct _reent *<[ptr]>, char **<[strp]>,
const char *<[format]>, ...);
char *_asnprintf_r(struct _reent *<[ptr]>, char *<[str]>,
size_t *<[size]>, const char *<[format]>, ...);
int _printf_r(struct _reent *<[ptr]>, const char *restrict <[format]>, ...);
int _fprintf_r(struct _reent *<[ptr]>, FILE *restrict <[fd]>,
const char *restrict <[format]>, ...);
int _sprintf_r(struct _reent *<[ptr]>, char *restrict <[str]>,
const char *restrict <[format]>, ...);
int _snprintf_r(struct _reent *<[ptr]>, char *restrict <[str]>, size_t <[size]>,
const char *restrict <[format]>, ...);
int _asprintf_r(struct _reent *<[ptr]>, char **restrict <[strp]>,
const char *restrict <[format]>, ...);
char *_asnprintf_r(struct _reent *<[ptr]>, char *restrict <[str]>,
size_t *restrict <[size]>, const char *restrict <[format]>, ...);
DESCRIPTION
<<printf>> accepts a series of arguments, applies to each a
@@ -518,6 +518,10 @@ DESCRIPTION
implementation is similar to <<%#tx>>), except
that <<0x>> appears even for the NULL pointer.
o m
Prints the output of <<strerror(errno)>>; no
argument is required. A GNU extension.
o-
O-
@@ -575,13 +579,13 @@ int
#ifdef _HAVE_STDC
_DEFUN(_sprintf_r, (ptr, str, fmt),
struct _reent *ptr _AND
char *str _AND
_CONST char *fmt _DOTS)
char *__restrict str _AND
_CONST char *__restrict fmt _DOTS)
#else
_sprintf_r(ptr, str, fmt, va_alist)
struct _reent *ptr;
char *str;
_CONST char *fmt;
char *__restrict str;
_CONST char *__restrict fmt;
va_dcl
#endif
{
@@ -609,8 +613,8 @@ _sprintf_r(ptr, str, fmt, va_alist)
int
#ifdef _HAVE_STDC
_DEFUN(sprintf, (str, fmt),
char *str _AND
_CONST char *fmt _DOTS)
char *__restrict str _AND
_CONST char *__restrict fmt _DOTS)
#else
sprintf(str, fmt, va_alist)
char *str;

View File

@@ -35,15 +35,15 @@ INDEX
ANSI_SYNOPSIS
#include <stdio.h>
int scanf(const char *<[format]>, ...);
int fscanf(FILE *<[fd]>, const char *<[format]>, ...);
int sscanf(const char *<[str]>, const char *<[format]>, ...);
int scanf(const char *restrict <[format]>, ...);
int fscanf(FILE *restrict <[fd]>, const char *restrict <[format]>, ...);
int sscanf(const char *restrict <[str]>, const char *restrict <[format]>, ...);
int _scanf_r(struct _reent *<[ptr]>, const char *<[format]>, ...);
int _fscanf_r(struct _reent *<[ptr]>, FILE *<[fd]>,
const char *<[format]>, ...);
int _sscanf_r(struct _reent *<[ptr]>, const char *<[str]>,
const char *<[format]>, ...);
int _scanf_r(struct _reent *<[ptr]>, const char *restrict <[format]>, ...);
int _fscanf_r(struct _reent *<[ptr]>, FILE *restrict <[fd]>,
const char *restrict <[format]>, ...);
int _sscanf_r(struct _reent *<[ptr]>, const char *restrict <[str]>,
const char *restrict <[format]>, ...);
TRAD_SYNOPSIS
@@ -399,8 +399,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
#ifdef _HAVE_STDC
int
_DEFUN(sscanf, (str, fmt),
_CONST char *str _AND
_CONST char *fmt _DOTS)
_CONST char *__restrict str _AND
_CONST char * fmt _DOTS)
#else
int
sscanf(str, fmt, va_alist)
@@ -436,14 +436,14 @@ sscanf(str, fmt, va_alist)
int
_DEFUN(_sscanf_r, (ptr, str, fmt),
struct _reent *ptr _AND
_CONST char *str _AND
_CONST char *fmt _DOTS)
_CONST char *__restrict str _AND
_CONST char *__restrict fmt _DOTS)
#else
int
_sscanf_r(ptr, str, fmt, va_alist)
struct _reent *ptr;
_CONST char *str;
_CONST char *fmt;
_CONST char *__restrict str;
_CONST char *__restrict fmt;
va_dcl
#endif
{

View File

@@ -34,10 +34,10 @@ _DEFUN(__sread, (ptr, cookie, buf, n),
struct _reent *ptr _AND
void *cookie _AND
char *buf _AND
int n)
_READ_WRITE_BUFSIZE_TYPE n)
{
register FILE *fp = (FILE *) cookie;
register int ret;
register ssize_t ret;
#ifdef __SCLE
int oldmode = 0;
@@ -67,7 +67,7 @@ _DEFUN(__seofread, (ptr, cookie, buf, len),
struct _reent *_ptr _AND
_PTR cookie _AND
char *buf _AND
int len)
_READ_WRITE_BUFSIZE_TYPE len)
{
return 0;
}
@@ -77,10 +77,10 @@ _DEFUN(__swrite, (ptr, cookie, buf, n),
struct _reent *ptr _AND
void *cookie _AND
char const *buf _AND
int n)
_READ_WRITE_BUFSIZE_TYPE n)
{
register FILE *fp = (FILE *) cookie;
int w;
ssize_t w;
#ifdef __SCLE
int oldmode=0;
#endif

View File

@@ -125,7 +125,7 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
CHECK_INIT (rptr, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
@@ -140,14 +140,14 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
*/
if ((fp->_flags & __SRW) == 0)
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return EOF;
}
if (fp->_flags & __SWR)
{
if (_fflush_r (rptr, fp))
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return EOF;
}
fp->_flags &= ~__SWR;
@@ -167,12 +167,12 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
{
if (fp->_r >= fp->_ub._size && __submore (rptr, fp))
{
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return EOF;
}
*--fp->_p = c;
fp->_r++;
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return c;
}
@@ -186,7 +186,7 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
{
fp->_p--;
fp->_r++;
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return c;
}
@@ -202,7 +202,7 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
fp->_ubuf[sizeof (fp->_ubuf) - 1] = c;
fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1];
fp->_r = 1;
_funlockfile (fp);
_newlib_flockfile_end (fp);
return c;
}

View File

@@ -16,7 +16,7 @@ int
_DEFUN(_vdprintf_r, (ptr, fd, format, ap),
struct _reent *ptr _AND
int fd _AND
const char *format _AND
const char *__restrict format _AND
va_list ap)
{
char *p;
@@ -38,7 +38,7 @@ _DEFUN(_vdprintf_r, (ptr, fd, format, ap),
int
_DEFUN(vdprintf, (fd, format, ap),
int fd _AND
const char *format _AND
const char *__restrict format _AND
va_list ap)
{
return _vdprintf_r (_REENT, fd, format, ap);

View File

@@ -131,7 +131,7 @@ struct ldieee
unsigned manh:32;
unsigned manl:32;
unsigned manl2:32;
unsigned manl3;16;
unsigned manl3:16;
};
#endif /* LDBL_MANT_DIG */
#endif /* !IEEE_8087 */

View File

@@ -178,9 +178,17 @@ static char *rcsid = "$Id: vfprintf.c,v 1.43 2002/08/13 02:40:06 fitzsim Exp $";
#endif
#ifdef STRING_ONLY
#define __SPRINT __ssprint_r
# ifdef _FVWRITE_IN_STREAMIO
# define __SPRINT __ssprint_r
# else
# define __SPRINT __ssputs_r
# endif
#else
#define __SPRINT __sprint_r
# ifdef _FVWRITE_IN_STREAMIO
# define __SPRINT __sprint_r
# else
# define __SPRINT __sfputs_r
# endif
#endif
/* The __sprint_r/__ssprint_r functions are shared between all versions of
@@ -188,6 +196,76 @@ static char *rcsid = "$Id: vfprintf.c,v 1.43 2002/08/13 02:40:06 fitzsim Exp $";
the INTEGER_ONLY versions here. */
#ifdef STRING_ONLY
#ifdef INTEGER_ONLY
#ifndef _FVWRITE_IN_STREAMIO
int
_DEFUN(__ssputs_r, (ptr, fp, buf, len),
struct _reent *ptr _AND
FILE *fp _AND
_CONST char *buf _AND
size_t len)
{
register int w;
w = fp->_w;
if (len >= w && fp->_flags & (__SMBF | __SOPT)) {
/* must be asprintf family */
unsigned char *str;
int curpos = (fp->_p - fp->_bf._base);
/* Choose a geometric growth factor to avoid
* quadratic realloc behavior, but use a rate less
* than (1+sqrt(5))/2 to accomodate malloc
* overhead. asprintf EXPECTS us to overallocate, so
* that it can add a trailing \0 without
* reallocating. The new allocation should thus be
* max(prev_size*1.5, curpos+len+1). */
int newsize = fp->_bf._size * 3 / 2;
if (newsize < curpos + len + 1)
newsize = curpos + len + 1;
if (fp->_flags & __SOPT)
{
/* asnprintf leaves original buffer alone. */
str = (unsigned char *)_malloc_r (ptr, newsize);
if (!str)
{
ptr->_errno = ENOMEM;
goto err;
}
memcpy (str, fp->_bf._base, curpos);
fp->_flags = (fp->_flags & ~__SOPT) | __SMBF;
}
else
{
str = (unsigned char *)_realloc_r (ptr, fp->_bf._base,
newsize);
if (!str) {
/* Free unneeded buffer. */
_free_r (ptr, fp->_bf._base);
/* Ensure correct errno, even if free
* changed it. */
ptr->_errno = ENOMEM;
goto err;
}
}
fp->_bf._base = str;
fp->_p = str + curpos;
fp->_bf._size = newsize;
w = len;
fp->_w = newsize - curpos;
}
if (len < w)
w = len;
(void)memmove ((_PTR) fp->_p, (_PTR) buf, (size_t) (w));
fp->_w -= w;
fp->_p += w;
return 0;
err:
fp->_flags |= __SERR;
return EOF;
}
#endif
int
_DEFUN(__ssprint_r, (ptr, fp, uio),
struct _reent *ptr _AND
@@ -280,11 +358,46 @@ err:
return EOF;
}
#else /* !INTEGER_ONLY */
#ifndef _FVWRITE_IN_STREAMIO
int __ssputs_r (struct _reent *, FILE *, _CONST char *, size_t);
#endif
int __ssprint_r (struct _reent *, FILE *, register struct __suio *);
#endif /* !INTEGER_ONLY */
#else /* !STRING_ONLY */
#ifdef INTEGER_ONLY
#ifndef _FVWRITE_IN_STREAMIO
int
_DEFUN(__sfputs_r, (ptr, fp, buf, len),
struct _reent *ptr _AND
FILE *fp _AND
_CONST char *buf _AND
size_t len)
{
register int i;
#ifdef _WIDE_ORIENT
if (fp->_flags2 & __SWID) {
wchar_t *p;
p = (wchar_t *) buf;
for (i = 0; i < (len / sizeof (wchar_t)); i++) {
if (_fputwc_r (ptr, p[i], fp) == WEOF)
return -1;
}
} else {
#else
{
#endif
for (i = 0; i < len; i++) {
if (_fputc_r (ptr, buf[i], fp) == EOF)
return -1;
}
}
return (0);
}
#endif
/*
* Flush out all the vectors defined by the given uio,
* then reset it so that it can be reused.
@@ -301,6 +414,7 @@ _DEFUN(__sprint_r, (ptr, fp, uio),
uio->uio_iovcnt = 0;
return (0);
}
#ifdef _WIDE_ORIENT
if (fp->_flags2 & __SWID) {
struct __siov *iov;
wchar_t *p;
@@ -319,6 +433,7 @@ _DEFUN(__sprint_r, (ptr, fp, uio),
}
}
} else
#endif
err = __sfvwrite_r(ptr, fp, uio);
out:
uio->uio_resid = 0;
@@ -326,15 +441,21 @@ out:
return (err);
}
#else /* !INTEGER_ONLY */
#ifndef _FVWRITE_IN_STREAMIO
int __sfputs_r (struct _reent *, FILE *, _CONST char *buf, size_t);
#endif
int __sprint_r (struct _reent *, FILE *, register struct __suio *);
#endif /* !INTEGER_ONLY */
#ifdef _UNBUF_STREAM_OPT
/*
* 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.
*
* Make sure to avoid inlining.
*/
static int
_NOINLINE_STATIC int
_DEFUN(__sbprintf, (rptr, fp, fmt, ap),
struct _reent *rptr _AND
register FILE *fp _AND
@@ -372,6 +493,7 @@ _DEFUN(__sbprintf, (rptr, fp, fmt, ap),
#endif
return (ret);
}
#endif /* _UNBUF_STREAM_OPT */
#endif /* !STRING_ONLY */
@@ -548,7 +670,6 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
register int ch; /* character from fmt */
register int n, m; /* handy integers (short term usage) */
register char *cp; /* handy char pointer (short term usage) */
register struct __siov *iovp;/* for PRINT macro */
register int flags; /* flags as above */
char *fmt_anchor; /* current format spec being processed */
#ifndef _NO_POS_ARGS
@@ -567,9 +688,9 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
char sign; /* sign prefix (' ', '+', '-', or \0) */
#ifdef _WANT_IO_C99_FORMATS
/* locale specific numeric grouping */
char *thousands_sep;
size_t thsnd_len;
const char *grouping;
char *thousands_sep = NULL;
size_t thsnd_len = 0;
const char *grouping = NULL;
#endif
#ifdef FLOATING_POINT
char *decimal_point = _localeconv_r (data)->decimal_point;
@@ -585,7 +706,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
#if defined (FLOATING_POINT) || defined (_WANT_IO_C99_FORMATS)
int ndig = 0; /* actual number of digits returned by cvt */
#endif
#ifdef _WANT_IO_C99_FORMATS
#if defined (FLOATING_POINT) && defined (_WANT_IO_C99_FORMATS)
int nseps; /* number of group separators with ' */
int nrepeats; /* number of repeats of the last group */
#endif
@@ -595,9 +716,12 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
char *xdigs = NULL; /* digits for [xX] conversion */
#ifdef _FVWRITE_IN_STREAMIO
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
register struct __siov *iovp;/* for PRINT macro */
#endif
char buf[BUF]; /* space for %c, %S, %[diouxX], %[aA] */
char ox[2]; /* space for 0x hex-prefix */
#ifdef _MB_CAPABLE
@@ -623,6 +747,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
#ifdef _FVWRITE_IN_STREAMIO
#define PRINT(ptr, len) { \
iovp->iov_base = (ptr); \
iovp->iov_len = (len); \
@@ -657,6 +782,30 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
uio.uio_iovcnt = 0; \
iovp = iov; \
}
#else
#define PRINT(ptr, len) { \
if (__SPRINT (data, fp, (ptr), (len)) == EOF) \
goto error; \
}
#define PAD(howmany, with) { \
if ((n = (howmany)) > 0) { \
while (n > PADSIZE) { \
PRINT (with, PADSIZE); \
n -= PADSIZE; \
} \
PRINT (with, n); \
} \
}
#define PRINTANDPAD(p, ep, len, with) { \
int n = (ep) - (p); \
if (n > (len)) \
n = (len); \
if (n > 0) \
PRINT((p), n); \
PAD((len) - (n > 0 ? n : 0), (with)); \
}
#define FLUSH()
#endif
/* Macros to support positional arguments */
#ifndef _NO_POS_ARGS
@@ -708,22 +857,24 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
#ifndef STRING_ONLY
/* Initialize std streams if not dealing with sprintf family. */
CHECK_INIT (data, fp);
_flockfile (fp);
_newlib_flockfile_start (fp);
ORIENT(fp, -1);
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
if (cantwrite (data, fp)) {
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return (EOF);
}
#ifdef _UNBUF_STREAM_OPT
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0) {
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return (__sbprintf (data, fp, fmt0, ap));
}
#endif
#else /* STRING_ONLY */
/* Create initial buffer if we are called by asprintf family. */
if (fp->_flags & __SMBF && !fp->_bf._base)
@@ -739,9 +890,11 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
#endif /* STRING_ONLY */
fmt = (char *)fmt0;
#ifdef _FVWRITE_IN_STREAMIO
uio.uio_iov = iovp = iov;
uio.uio_resid = 0;
uio.uio_iovcnt = 0;
#endif
ret = 0;
#ifndef _NO_POS_ARGS
arg_index = 0;
@@ -793,10 +946,10 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
sign = '\0';
#ifdef FLOATING_POINT
lead = 0;
#endif
#ifdef _WANT_IO_C99_FORMATS
nseps = nrepeats = 0;
#endif
#endif
#ifndef _NO_POS_ARGS
N = arg_index;
is_pos_arg = 0;
@@ -1225,6 +1378,15 @@ reswitch: switch (ch) {
sign = '-';
break;
#endif /* FLOATING_POINT */
#ifdef _GLIBC_EXTENSION
case 'm': /* extension */
{
int dummy;
cp = _strerror_r (data, data->_errno, 1, &dummy);
}
flags &= ~LONGINT;
goto string;
#endif
case 'n':
#ifndef _NO_LONGLONG
if (flags & QUADINT)
@@ -1272,8 +1434,11 @@ reswitch: switch (ch) {
#ifdef _WANT_IO_C99_FORMATS
case 'S':
#endif
sign = '\0';
cp = GET_ARG (N, ap, char_ptr_t);
#ifdef _GLIBC_EXTENSION
string:
#endif
sign = '\0';
#ifndef __OPTIMIZE_SIZE__
/* Behavior is undefined if the user passed a
NULL string when precision is not 0.
@@ -1621,7 +1786,7 @@ error:
if (malloc_buf != NULL)
_free_r (data, malloc_buf);
#ifndef STRING_ONLY
_funlockfile (fp);
_newlib_flockfile_end (fp);
#endif
return (__sferror (fp) ? EOF : ret);
/* NOTREACHED */

View File

@@ -148,10 +148,12 @@ Supporting OS subroutines required:
#endif
#ifdef STRING_ONLY
#undef _flockfile
#undef _funlockfile
#define _flockfile(x) {}
#define _funlockfile(x) {}
#undef _newlib_flockfile_start
#undef _newlib_flockfile_exit
#undef _newlib_flockfile_end
#define _newlib_flockfile_start(x) {}
#define _newlib_flockfile_exit(x) {}
#define _newlib_flockfile_end(x) {}
#define _ungetc_r _sungetc_r
#define __srefill_r __ssrefill_r
#define _fread_r _sfread_r
@@ -160,6 +162,7 @@ Supporting OS subroutines required:
#ifdef FLOATING_POINT
#include <math.h>
#include <float.h>
#include <locale.h>
/* Currently a test is made to see if long double processing is warranted.
This could be changed in the future should the _ldtoa_r code be
@@ -172,11 +175,7 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
#include "floatio.h"
#if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
# define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
#else
# define BUF MB_LEN_MAX
#endif
#define BUF (MAXEXP+MAXFRACT+MB_LEN_MAX+2) /* decimal point + sign + NUL */
/* An upper bound for how long a long prints in decimal. 4 / 13 approximates
log (2). Add one char for roundoff compensation and one for the sign. */
@@ -241,10 +240,7 @@ static void * get_arg (int, va_list *, int *, void **);
#define CT_INT 3 /* integer, i.e., strtol or strtoul */
#define CT_FLOAT 4 /* floating, i.e., strtod */
#if 0
#define u_char unsigned char
#endif
#define u_char char
#define u_long unsigned long
#ifndef _NO_LONGLONG
@@ -267,8 +263,10 @@ _DEFUN(VFSCANF, (fp, fmt, ap),
_CONST char *fmt _AND
va_list ap)
{
CHECK_INIT(_REENT, fp);
return __SVFSCANF_R (_REENT, fp, fmt, ap);
struct _reent *reent = _REENT;
CHECK_INIT(reent, fp);
return __SVFSCANF_R (reent, fp, fmt, ap);
}
int
@@ -496,7 +494,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
# define GET_ARG(n, ap, type) (va_arg (ap, type))
#endif
_flockfile (fp);
_newlib_flockfile_start (fp);
ORIENT (fp, -1);
@@ -511,8 +509,8 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
#ifndef _MB_CAPABLE
wc = *fmt;
#else
nbytes = __mbtowc (rptr, &wc, fmt, MB_CUR_MAX, __locale_charset (),
&state);
nbytes = __mbtowc (rptr, &wc, (char *) fmt, MB_CUR_MAX,
__locale_charset (), &state);
if (nbytes < 0) {
wc = 0xFFFD; /* Unicode replacement character */
nbytes = 1;
@@ -795,7 +793,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
* Disgusting backwards compatibility hacks. XXX
*/
case '\0': /* compat */
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return EOF;
default: /* compat */
@@ -1287,6 +1285,10 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
unsigned width_left = 0;
char nancount = 0;
char infcount = 0;
const char *decpt = _localeconv_r (rptr)->decimal_point;
#ifdef _MB_CAPABLE
int decptpos = 0;
#endif
#ifdef hardway
if (width == 0 || width > sizeof (buf) - 1)
#else
@@ -1415,14 +1417,6 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
goto fok;
}
break;
case '.':
if (flags & DPTOK)
{
flags &= ~(SIGNOK | DPTOK);
leading_zeroes = zeroes;
goto fok;
}
break;
case 'e':
case 'E':
/* no exponent without some digits */
@@ -1441,6 +1435,53 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
goto fok;
}
break;
default:
#ifndef _MB_CAPABLE
if ((unsigned char) c == (unsigned char) decpt[0]
&& (flags & DPTOK))
{
flags &= ~(SIGNOK | DPTOK);
leading_zeroes = zeroes;
goto fok;
}
break;
#else
if (flags & DPTOK)
{
while ((unsigned char) c
== (unsigned char) decpt[decptpos])
{
if (decpt[++decptpos] == '\0')
{
/* We read the complete decpt seq. */
flags &= ~(SIGNOK | DPTOK);
leading_zeroes = zeroes;
p = stpncpy (p, decpt, decptpos);
decptpos = 0;
goto fskip;
}
++nread;
if (--fp->_r > 0)
fp->_p++;
else if (__srefill_r (rptr, fp))
break; /* EOF */
c = *fp->_p;
}
if (decptpos > 0)
{
/* We read part of a multibyte decimal point,
but the rest is invalid or we're at EOF,
so back off. */
while (decptpos-- > 0)
{
_ungetc_r (rptr, (unsigned char) decpt[decptpos],
fp);
--nread;
}
}
}
break;
#endif
}
break;
fok:
@@ -1595,12 +1636,12 @@ input_failure:
should have been set prior to here. On EOF failure (including
invalid format string), return EOF if no matches yet, else number
of matches made prior to failure. */
_funlockfile (fp);
_newlib_flockfile_exit (fp);
return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF;
match_failure:
all_done:
/* Return number of matches, which can be 0 on match failure. */
_funlockfile (fp);
_newlib_flockfile_end (fp);
return nassigned;
}

View File

@@ -34,8 +34,10 @@ _DEFUN(vscanf, (fmt, ap),
_CONST char *fmt _AND
va_list ap)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return __svfscanf_r (_REENT, _stdin_r (_REENT), fmt, ap);
struct _reent *reent = _REENT;
_REENT_SMALL_CHECK_INIT (reent);
return __svfscanf_r (reent, _stdin_r (reent), fmt, ap);
}
#endif /* !_REENT_ONLY */
@@ -43,7 +45,7 @@ _DEFUN(vscanf, (fmt, ap),
int
_DEFUN(_vscanf_r, (ptr, fmt, ap),
struct _reent *ptr _AND
_CONST char *fmt _AND
_CONST char *__restrict fmt _AND
va_list ap)
{
_REENT_SMALL_CHECK_INIT (ptr);

View File

@@ -33,9 +33,9 @@ static char sccsid[] = "%W% (Berkeley) %G%";
int
_DEFUN(vsnprintf, (str, size, fmt, ap),
char *str _AND
char *__restrict str _AND
size_t size _AND
const char *fmt _AND
const char *__restrict fmt _AND
va_list ap)
{
return _vsnprintf_r (_REENT, str, size, fmt, ap);
@@ -46,9 +46,9 @@ _DEFUN(vsnprintf, (str, size, fmt, ap),
int
_DEFUN(_vsnprintf_r, (ptr, str, size, fmt, ap),
struct _reent *ptr _AND
char *str _AND
char *__restrict str _AND
size_t size _AND
const char *fmt _AND
const char *__restrict fmt _AND
va_list ap)
{
int ret;

View File

@@ -32,8 +32,8 @@ static char sccsid[] = "%W% (Berkeley) %G%";
int
_DEFUN(vsprintf, (str, fmt, ap),
char *str _AND
const char *fmt _AND
char *__restrict str _AND
const char *__restrict fmt _AND
va_list ap)
{
return _vsprintf_r (_REENT, str, fmt, ap);
@@ -44,8 +44,8 @@ _DEFUN(vsprintf, (str, fmt, ap),
int
_DEFUN(_vsprintf_r, (ptr, str, fmt, ap),
struct _reent *ptr _AND
char *str _AND
const char *fmt _AND
char *__restrict str _AND
const char *__restrict fmt _AND
va_list ap)
{
int ret;

View File

@@ -36,8 +36,8 @@
int
_DEFUN(vsscanf, (str, fmt, ap),
_CONST char *str _AND
_CONST char *fmt _AND
_CONST char *__restrict str _AND
_CONST char *__restrict fmt _AND
va_list ap)
{
return _vsscanf_r (_REENT, str, fmt, ap);
@@ -48,8 +48,8 @@ _DEFUN(vsscanf, (str, fmt, ap),
int
_DEFUN(_vsscanf_r, (ptr, str, fmt, ap),
struct _reent *ptr _AND
_CONST char *str _AND
_CONST char *fmt _AND
_CONST char *__restrict str _AND
_CONST char *__restrict fmt _AND
va_list ap)
{
FILE f;