This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
[PATCH] Fix stdin,-out and -err for multithreaded apps
- From: Thomas Pfaff <tpfaff at gmx dot net>
- To: newlib at sources dot redhat dot com
- Date: Thu, 18 Sep 2003 21:05:26 +0200
- Subject: [PATCH] Fix stdin,-out and -err for multithreaded apps
Attached is a patch that should fix the bug reported at
http://sources.redhat.com/ml/newlib/2003/msg00544.html.
which is another __DYNAMIC_REENT related problem.
It will change stdin, -out and -err locations to use _GLOBAL_REENT
instead of _REENT where appropriate, and it includes a change for the
stdin, stdout and stderr defines that i suggested some time ago (see
http://sources.redhat.com/ml/newlib/2003/msg00363.html).
This will allow to change stdin, stdout and stderr without recompiling
all user apps in the future.
If speed is an issue the former defines can be used by defining
_INLINE_STDFP.
After applying this patch Makefile.in must be regenerated.
Comments are welcome.
TIA,
Thomas
2003-09-18 Thomas Pfaff <tpfaff@gmx.net>
* libc/include/stdio.h: Redefine stdin, stdout and stderr to use
function calls instead of direct member access if newlib is
compiled without _INLINE_STDFP.
* libc/stdio/Makefile.am (GENERAL_SOURCES): Add stdfp.c.
* libc/stdio/stdfp.c: New file.
* libc/stdio/getchar.c: Replace _REENT with _GLOBAL_REENT where
appropriate.
* libc/stdio/getchar_u.c: Ditto.
* libc/stdio/gets.c: Ditto.
* libc/stdio/iprintf.c: Ditto.
* libc/stdio/perror.c: Ditto.
* libc/stdio/printf.c: Ditto.
* libc/stdio/putchar.c: Ditto.
* libc/stdio/putchar_u.c: Ditto.
* libc/stdio/puts.c: Ditto.
* libc/stdio/scanf.c: Ditto.
* libc/stdio/vprintf.c: Ditto.
* libc/stdio/vscanf.c: Ditto.
diff -rupN newlib.old/libc/include/stdio.h newlib/libc/include/stdio.h
--- newlib.old/libc/include/stdio.h 2003-08-27 02:12:31.000000000 +0200
+++ newlib/libc/include/stdio.h 2003-09-18 13:09:34.000000000 +0200
@@ -143,6 +143,8 @@ typedef _fpos64_t fpos64_t;
#define TMP_MAX 26
+#ifdef _INLINE_STDFP
+
#ifndef _REENT_ONLY
#define stdin (_REENT->_stdin)
#define stdout (_REENT->_stdout)
@@ -153,6 +155,17 @@ typedef _fpos64_t fpos64_t;
#define stderr (_impure_ptr->_stderr)
#endif /* _REENT_ONLY */
+#else /* _INLINE_STDFP */
+
+extern __FILE **__stdin _PARAMS ((void));
+extern __FILE **__stdout _PARAMS ((void));
+extern __FILE **__stderr _PARAMS ((void));
+#define stdin (*__stdin())
+#define stdout (*__stdout())
+#define stderr (*__stderr())
+
+#endif /* _INLINE_STDFP */
+
#define _stdin_r(x) ((x)->_stdin)
#define _stdout_r(x) ((x)->_stdout)
#define _stderr_r(x) ((x)->_stderr)
diff -rupN newlib.old/libc/stdio/Makefile.am newlib/libc/stdio/Makefile.am
--- newlib.old/libc/stdio/Makefile.am 2003-01-10 21:49:04.000000000 +0100
+++ newlib/libc/stdio/Makefile.am 2003-09-18 14:26:33.000000000 +0200
@@ -61,6 +61,7 @@ GENERAL_SOURCES = \
snprintf.c \
sprintf.c \
sscanf.c \
+ stdfp.c \
stdio.c \
tmpfile.c \
tmpnam.c \
@@ -211,6 +212,7 @@ setvbuf.$(oext): local.h
siprintf.$(oext): local.h
sprintf.$(oext): local.h
sscanf.$(oext): local.h
+stdfp.$(oext): local.h
stdio.$(oext): local.h
ungetc.$(oext): local.h
vfiprintf.$(oext): local.h
diff -rupN newlib.old/libc/stdio/getchar.c newlib/libc/stdio/getchar.c
--- newlib.old/libc/stdio/getchar.c 2002-02-20 04:24:11.000000000 +0100
+++ newlib/libc/stdio/getchar.c 2003-09-18 13:26:50.000000000 +0200
@@ -93,7 +93,7 @@ getchar ()
{
/* CHECK_INIT is called (eventually) by __srefill. */
- return _getchar_r (_REENT);
+ return _getchar_r (_GLOBAL_REENT);
}
#endif
diff -rupN newlib.old/libc/stdio/getchar_u.c newlib/libc/stdio/getchar_u.c
--- newlib.old/libc/stdio/getchar_u.c 2002-05-08 21:11:22.000000000 +0200
+++ newlib/libc/stdio/getchar_u.c 2003-09-18 13:41:15.000000000 +0200
@@ -73,7 +73,7 @@ getchar_unlocked ()
{
/* CHECK_INIT is called (eventually) by __srefill. */
- return _getchar_unlocked_r (_REENT);
+ return _getchar_unlocked_r (_GLOBAL_REENT);
}
#endif
diff -rupN newlib.old/libc/stdio/gets.c newlib/libc/stdio/gets.c
--- newlib.old/libc/stdio/gets.c 2000-05-14 18:46:11.000000000 +0200
+++ newlib/libc/stdio/gets.c 2003-09-18 13:45:55.000000000 +0200
@@ -96,7 +96,7 @@ char *
gets (buf)
char *buf;
{
- return _gets_r (_REENT, buf);
+ return _gets_r (_GLOBAL_REENT, buf);
}
#endif
diff -rupN newlib.old/libc/stdio/iprintf.c newlib/libc/stdio/iprintf.c
--- newlib.old/libc/stdio/iprintf.c 2003-08-25 02:04:07.000000000 +0200
+++ newlib/libc/stdio/iprintf.c 2003-09-18 13:38:05.000000000 +0200
@@ -61,7 +61,7 @@ iprintf (fmt, va_alist)
int ret;
va_list ap;
- _REENT_SMALL_CHECK_INIT(_stdout_r (_REENT));
+ _REENT_SMALL_CHECK_INIT(_stdout_r (_GLOBAL_REENT));
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
diff -rupN newlib.old/libc/stdio/perror.c newlib/libc/stdio/perror.c
--- newlib.old/libc/stdio/perror.c 2002-02-20 04:24:11.000000000 +0100
+++ newlib/libc/stdio/perror.c 2003-09-18 13:28:39.000000000 +0200
@@ -77,7 +77,7 @@ void
_DEFUN (perror, (s),
_CONST char *s)
{
- _perror_r (_REENT, s);
+ _perror_r (_GLOBAL_REENT, s);
}
#endif
diff -rupN newlib.old/libc/stdio/printf.c newlib/libc/stdio/printf.c
--- newlib.old/libc/stdio/printf.c 2003-08-25 02:04:07.000000000 +0200
+++ newlib/libc/stdio/printf.c 2003-09-18 13:39:01.000000000 +0200
@@ -50,13 +50,13 @@ printf (fmt, va_alist)
int ret;
va_list ap;
- _REENT_SMALL_CHECK_INIT(_stdout_r (_REENT));
+ _REENT_SMALL_CHECK_INIT(_stdout_r (_GLOBAL_REENT));
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
- ret = vfprintf (_stdout_r (_REENT), fmt, ap);
+ ret = vfprintf (_stdout_r (_GLOBAL_REENT), fmt, ap);
va_end (ap);
return ret;
}
diff -rupN newlib.old/libc/stdio/putchar.c newlib/libc/stdio/putchar.c
--- newlib.old/libc/stdio/putchar.c 2002-05-30 22:19:05.000000000 +0200
+++ newlib/libc/stdio/putchar.c 2003-09-18 13:39:34.000000000 +0200
@@ -91,7 +91,7 @@ putchar (c)
{
/* CHECK_INIT is (eventually) called by __swbuf. */
- return _putchar_r (_REENT, c);
+ return _putchar_r (_GLOBAL_REENT, c);
}
#endif
diff -rupN newlib.old/libc/stdio/putchar_u.c newlib/libc/stdio/putchar_u.c
--- newlib.old/libc/stdio/putchar_u.c 2002-05-08 21:11:22.000000000 +0200
+++ newlib/libc/stdio/putchar_u.c 2003-09-18 13:39:49.000000000 +0200
@@ -74,7 +74,7 @@ putchar_unlocked (c)
{
/* CHECK_INIT is (eventually) called by __swbuf. */
- _putchar_unlocked_r (_REENT, c);
+ _putchar_unlocked_r (_GLOBAL_REENT, c);
}
#endif
diff -rupN newlib.old/libc/stdio/puts.c newlib/libc/stdio/puts.c
--- newlib.old/libc/stdio/puts.c 2002-02-20 04:24:11.000000000 +0100
+++ newlib/libc/stdio/puts.c 2003-09-18 13:40:27.000000000 +0200
@@ -98,7 +98,7 @@ int
_DEFUN (puts, (s),
char _CONST * s)
{
- return _puts_r (_REENT, s);
+ return _puts_r (_GLOBAL_REENT, s);
}
#endif
diff -rupN newlib.old/libc/stdio/scanf.c newlib/libc/stdio/scanf.c
--- newlib.old/libc/stdio/scanf.c 2002-02-20 04:24:11.000000000 +0100
+++ newlib/libc/stdio/scanf.c 2003-09-18 13:36:56.000000000 +0200
@@ -41,13 +41,13 @@ scanf (fmt, va_alist)
int ret;
va_list ap;
- _REENT_SMALL_CHECK_INIT(_stdin_r (_REENT));
+ _REENT_SMALL_CHECK_INIT(_stdin_r (_GLOBAL_REENT));
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
- ret = __svfscanf_r (_REENT, _stdin_r (_REENT), fmt, ap);
+ ret = __svfscanf_r (_GLOBAL_REENT, _stdin_r (_GLOBAL_REENT), fmt, ap);
va_end (ap);
return ret;
}
diff -rupN newlib.old/libc/stdio/stdfp.c newlib/libc/stdio/stdfp.c
--- newlib.old/libc/stdio/stdfp.c 1970-01-01 01:00:00.000000000 +0100
+++ newlib/libc/stdio/stdfp.c 2003-09-18 14:32:13.000000000 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include <_ansi.h>
+#include <stdio.h>
+#include "local.h"
+
+#ifndef _INLINE_STDFP
+
+/*
+ * stdin
+ */
+
+__FILE **
+_DEFUN_VOID (__stdin)
+{
+ return &_GLOBAL_REENT->_stdin;
+}
+
+__FILE **
+_DEFUN_VOID (__stdout)
+{
+ return &_GLOBAL_REENT->_stdout;
+}
+
+__FILE **
+_DEFUN_VOID (__stderr)
+{
+ return &_GLOBAL_REENT->_stderr;
+}
+
+#endif /* _INLINE_STDFP */
diff -rupN newlib.old/libc/stdio/vprintf.c newlib/libc/stdio/vprintf.c
--- newlib.old/libc/stdio/vprintf.c 2003-08-25 02:04:07.000000000 +0200
+++ newlib/libc/stdio/vprintf.c 2003-09-18 13:35:04.000000000 +0200
@@ -35,8 +35,8 @@ _DEFUN (vprintf, (fmt, ap),
_CONST char *fmt _AND
va_list ap)
{
- _REENT_SMALL_CHECK_INIT(_stdout_r (_REENT));
- return _vfprintf_r (_REENT, _stdout_r (_REENT), fmt, ap);
+ _REENT_SMALL_CHECK_INIT(_stdout_r (_GLOBAL_REENT));
+ return _vfprintf_r (_GLOBAL_REENT, _stdout_r (_GLOBAL_REENT), fmt, ap);
}
#endif /* !_REENT_ONLY */
diff -rupN newlib.old/libc/stdio/vscanf.c newlib/libc/stdio/vscanf.c
--- newlib.old/libc/stdio/vscanf.c 2002-02-20 04:24:11.000000000 +0100
+++ newlib/libc/stdio/vscanf.c 2003-09-18 13:34:27.000000000 +0200
@@ -38,8 +38,8 @@ _DEFUN (vscanf, (fmt, ap),
_CONST char *fmt _AND
va_list ap)
{
- _REENT_SMALL_CHECK_INIT(_stdin_r (_REENT));
- return __svfscanf_r (_REENT, _stdin_r (_REENT), fmt, ap);
+ _REENT_SMALL_CHECK_INIT(_stdin_r (_GLOBAL_REENT));
+ return __svfscanf_r (_GLOBAL_REENT, _stdin_r (_GLOBAL_REENT), fmt, ap);
}
#endif /* !_REENT_ONLY */