|
@@ -65,6 +65,18 @@
|
|
|
* Set EOF to end of buffer when fmemopen used on a readonly stream.
|
|
|
* Note: I really need to run some tests on this to see what the
|
|
|
* glibc code does in each case.
|
|
|
+ *
|
|
|
+ * Sept 21, 2003
|
|
|
+ * Modify _stdio_READ to conform with C99, as stdio input behavior upon
|
|
|
+ * encountering EOF changed with Defect Report #141. In the current
|
|
|
+ * standard, the stream's EOF indicator is "sticky". Once it is set,
|
|
|
+ * all further input from the stream should fail until the application
|
|
|
+ * explicitly clears the EOF indicator (clearerr(), file positioning),
|
|
|
+ * even if more data becomes available.
|
|
|
+ * Fixed a bug in fgets. Wasn't checking for read errors.
|
|
|
+ * Minor thread locking optimizations to avoid some unnecessary locking.
|
|
|
+ * Remove the explicit calls to __builtin_* funcs, as we really need to
|
|
|
+ * implement a more general solution.
|
|
|
*/
|
|
|
|
|
|
|
|
@@ -293,7 +305,8 @@ int getw(FILE *stream)
|
|
|
|
|
|
#ifdef __STDIO_WIDE
|
|
|
|
|
|
- return (fread((void *)aw, sizeof(int), 1, stream) > 0) ? (*aw) : EOF;
|
|
|
+ return (fread_unlocked((void *)aw, sizeof(int), 1, stream) > 0)
|
|
|
+ ? (*aw) : EOF;
|
|
|
|
|
|
#else
|
|
|
|
|
@@ -317,7 +330,8 @@ int putw(int w, FILE *stream)
|
|
|
|
|
|
#ifdef __STDIO_WIDE
|
|
|
|
|
|
- return (fwrite((void *)aw, sizeof(int), 1, stream) == 1) ? 0 : EOF;
|
|
|
+ return (fwrite_unlocked((void *)aw, sizeof(int), 1, stream) == 1)
|
|
|
+ ? 0 : EOF;
|
|
|
|
|
|
#else
|
|
|
|
|
@@ -1181,7 +1195,8 @@ ssize_t __getdelim(char **__restrict lineptr, size_t *__restrict n,
|
|
|
*n += GETDELIM_GROWBY;
|
|
|
*lineptr = buf;
|
|
|
}
|
|
|
- } while (((c = getc(stream)) != EOF) && ((buf[pos++ - 1] = c) != delimiter));
|
|
|
+ } while (((c = (getc_unlocked)(stream)) != EOF)
|
|
|
+ && ((buf[pos++ - 1] = c) != delimiter));
|
|
|
|
|
|
__STDIO_THREADUNLOCK(stream);
|
|
|
|
|
@@ -1322,7 +1337,8 @@ static ssize_t _stdio_READ(register FILE *stream, unsigned char *buf, size_t buf
|
|
|
{
|
|
|
ssize_t rv;
|
|
|
|
|
|
- if (bufsize == 0) {
|
|
|
+
|
|
|
+ if ((bufsize == 0) || (stream->modeflags & __FLAG_EOF)) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2751,7 +2767,8 @@ UNLOCKED(int,fgetc,(FILE *stream),(stream))
|
|
|
|
|
|
#ifdef __STDIO_WIDE
|
|
|
|
|
|
- return (fread(buf, (size_t) 1, (size_t) 1, stream) > 0) ? *buf : EOF;
|
|
|
+ return (fread_unlocked(buf, (size_t) 1, (size_t) 1, stream) > 0)
|
|
|
+ ? *buf : EOF;
|
|
|
|
|
|
#else
|
|
|
|
|
@@ -2773,19 +2790,39 @@ UNLOCKED(char *,fgets,
|
|
|
register char *p;
|
|
|
int c;
|
|
|
|
|
|
+#ifdef __UCLIBC_MJN3_ONLY__
|
|
|
+#warning CONSIDER: What should fgets do if n <= 0?
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (n <= 0) {
|
|
|
+
|
|
|
+ goto ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
p = s;
|
|
|
- while ((n > 1) && ((c = getc(stream)) != EOF) && ((*p++ = c) != '\n')) {
|
|
|
- --n;
|
|
|
- }
|
|
|
- if (p == s) {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- return NULL;
|
|
|
+
|
|
|
+ while (--n) {
|
|
|
+ if ((c = (getc_unlocked)(stream)) == EOF) {
|
|
|
+ if (__FERROR(stream)) {
|
|
|
+ goto ERROR;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if ((*p++ = c) == '\n') {
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
- *p = 0;
|
|
|
- return s;
|
|
|
+
|
|
|
+#ifdef __UCLIBC_MJN3_ONLY__
|
|
|
+#warning CONSIDER: If n==1 and not at EOF, should fgets return an empty string?
|
|
|
+#endif
|
|
|
+ if (p > s) {
|
|
|
+ *p = 0;
|
|
|
+ return s;
|
|
|
+ }
|
|
|
+
|
|
|
+ ERROR:
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
#endif
|
|
@@ -2802,7 +2839,8 @@ UNLOCKED(int,fputc,(int c, FILE *stream),(c,stream))
|
|
|
|
|
|
#ifdef __STDIO_WIDE
|
|
|
|
|
|
- return (fwrite(buf, (size_t) 1, (size_t) 1, stream) > 0) ? (*buf) : EOF;
|
|
|
+ return (fwrite_unlocked(buf, (size_t) 1, (size_t) 1, stream) > 0)
|
|
|
+ ? (*buf) : EOF;
|
|
|
|
|
|
#else
|
|
|
|
|
@@ -2824,7 +2862,7 @@ UNLOCKED(int,fputs,
|
|
|
|
|
|
#ifdef __STDIO_WIDE
|
|
|
|
|
|
- return (fwrite(s, n, (size_t) 1, stream) > 0) ? n : EOF;
|
|
|
+ return (fwrite_unlocked(s, n, (size_t) 1, stream) > 0) ? n : EOF;
|
|
|
|
|
|
#else
|
|
|
|
|
@@ -3484,8 +3522,8 @@ char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,
|
|
|
#ifndef __LOCALE_C_ONLY
|
|
|
if (!grouping) {
|
|
|
bufend -= __UCLIBC_CURLOCALE_DATA.thousands_sep_len;
|
|
|
- __builtin_memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
|
|
|
- __UCLIBC_CURLOCALE_DATA.thousands_sep_len);
|
|
|
+ memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
|
|
|
+ __UCLIBC_CURLOCALE_DATA.thousands_sep_len);
|
|
|
if (g[1] != 0) {
|
|
|
|
|
|
* we'll never wrap around, we can set grouping to -1 without
|
|
@@ -3502,9 +3540,9 @@ char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,
|
|
|
#ifndef __LOCALE_C_ONLY
|
|
|
if (unlikely(outdigit)) {
|
|
|
bufend -= __UCLIBC_CURLOCALE_DATA.outdigit_length[digit];
|
|
|
- __builtin_memcpy(bufend,
|
|
|
- (&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit],
|
|
|
- __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]);
|
|
|
+ memcpy(bufend,
|
|
|
+ (&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit],
|
|
|
+ __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]);
|
|
|
} else
|
|
|
#endif
|
|
|
{
|
|
@@ -3527,8 +3565,8 @@ char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,
|
|
|
#ifndef __LOCALE_C_ONLY
|
|
|
if (!grouping) {
|
|
|
bufend -= __UCLIBC_CURLOCALE_DATA.thousands_sep_len;
|
|
|
- __builtin_memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
|
|
|
- __UCLIBC_CURLOCALE_DATA.thousands_sep_len);
|
|
|
+ memcpy(bufend, __UCLIBC_CURLOCALE_DATA.thousands_sep,
|
|
|
+ __UCLIBC_CURLOCALE_DATA.thousands_sep_len);
|
|
|
if (g[1] != 0) {
|
|
|
|
|
|
* we'll never wrap around, we can set grouping to -1 without
|
|
@@ -3554,9 +3592,9 @@ char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,
|
|
|
#ifndef __LOCALE_C_ONLY
|
|
|
if (unlikely(outdigit)) {
|
|
|
bufend -= __UCLIBC_CURLOCALE_DATA.outdigit_length[digit];
|
|
|
- __builtin_memcpy(bufend,
|
|
|
- (&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit],
|
|
|
- __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]);
|
|
|
+ memcpy(bufend,
|
|
|
+ (&__UCLIBC_CURLOCALE_DATA.outdigit0_mb)[digit],
|
|
|
+ __UCLIBC_CURLOCALE_DATA.outdigit_length[digit]);
|
|
|
} else
|
|
|
#endif
|
|
|
{
|