This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]