summaryrefslogtreecommitdiffstats
path: root/newlib
diff options
context:
space:
mode:
Diffstat (limited to 'newlib')
-rw-r--r--newlib/ChangeLog36
-rw-r--r--newlib/libc/stdio/fclose.c7
-rw-r--r--newlib/libc/stdio/fcloseall.c10
-rw-r--r--newlib/libc/stdio/fdopen.c4
-rw-r--r--newlib/libc/stdio/findfp.c42
-rw-r--r--newlib/libc/stdio/fopen.c12
-rw-r--r--newlib/libc/stdio/freopen.c9
-rw-r--r--newlib/libc/stdio/fwalk.c40
-rw-r--r--newlib/libc/stdio/local.h8
-rw-r--r--newlib/libc/stdio64/fdopen64.c8
-rw-r--r--newlib/libc/stdio64/fopen64.c12
-rw-r--r--newlib/libc/stdio64/freopen64.c11
12 files changed, 145 insertions, 54 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 1c7363ec4..9f2f066e2 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,3 +1,39 @@
+2004-03-25 Thomas Pfaff <tpfaff@gmx.net>
+
+ * libc/stdio/fclose.c (fclose): Protect file pointer list when
+ releasing a file.
+ * libc/stdio/fcloseall.c (_fcloseall_r): Close all files via
+ fwalk.
+ * libc/stdio/fdopen.c (_fdopen_r): Add calls to
+ _flockfile/_funlockfile.
+ * libc/stdio/findfp.c: Move __sfp_lock. Change __sfp_lock type
+ to recursive.
+ Change __lock_acquire/__lock_release calls for __sfp_lock to
+ __sfp_lock_acquire/__sfp_lock_release throughout.
+ (std): Make sure that file lock is only initialized once.
+ (__sfp): Move _file initialization. Initialize file lock.
+ (__sfp_lock_acquire): New function.
+ (__sfp_lock_release): Ditto.
+ (__fp_lock_all): Remove __sfp_lock_acquire call.
+ (__fp_unlock_all): Remove __sfp_lock_release call.
+ * libc/stdio/fopen.c (_fopen_r): Protect file pointer list.
+ Add calls to _flockfile/_funlockfile. Remove
+ __lock_init_recursive call.
+ * libc/stdio/freopen.c (_freopen_r): Protect file pointer list.
+ * libc/stdio/fwalk.c (__fwalk): New static function.
+ (_fwalk): Protect file pointer list. Use __fwalk to walk through
+ file pointers.
+ * libc/stdio/local.h: Add defines for
+ __sfp_lock_acquire/__sfp_lock_release when
+ single threaded. Add function prototypes otherwise.
+ * libc/stdio64/fdopen64.c (_fdopen64_r): Add calls to
+ _flockfile/_funlockfile.
+ * libc/stdio/fopen64.c (_fopen64_r): Protect file pointer list.
+ Add calls to _flockfile/_funlockfile. Remove
+ __lock_init_recursive call.
+ * libc/stdio/freopen64.c (_freopen64_r): Protect file pointer
+ list.
+
2004-03-25 Jeff Johnston <jjohnstn@redhat.com>
* libc/sys/linux/sys/lock.h: Turn on __USE_GNU flag if not already
diff --git a/newlib/libc/stdio/fclose.c b/newlib/libc/stdio/fclose.c
index 1caeb4cde..a125f16ef 100644
--- a/newlib/libc/stdio/fclose.c
+++ b/newlib/libc/stdio/fclose.c
@@ -65,6 +65,8 @@ _DEFUN (fclose, (fp),
if (fp == NULL)
return (0); /* on NULL */
+ __sfp_lock_acquire ();
+
_flockfile(fp);
CHECK_INIT (fp);
@@ -72,6 +74,7 @@ _DEFUN (fclose, (fp),
if (fp->_flags == 0) /* not open! */
{
_funlockfile(fp);
+ __sfp_lock_release ();
return (0);
}
r = fp->_flags & __SWR ? fflush (fp) : 0;
@@ -83,11 +86,13 @@ _DEFUN (fclose, (fp),
FREEUB (fp);
if (HASLB (fp))
FREELB (fp);
+ fp->_flags = 0; /* release this FILE for reuse */
_funlockfile(fp);
#ifndef __SINGLE_THREAD__
__lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
#endif
- fp->_flags = 0; /* release this FILE for reuse */
+
+ __sfp_lock_release ();
return (r);
}
diff --git a/newlib/libc/stdio/fcloseall.c b/newlib/libc/stdio/fcloseall.c
index d51c6fe34..e5a3af277 100644
--- a/newlib/libc/stdio/fcloseall.c
+++ b/newlib/libc/stdio/fcloseall.c
@@ -66,15 +66,7 @@ int
_fcloseall_r (ptr)
struct _reent *ptr;
{
- register FILE *fp;
- register int n, ret = 0;
- register struct _glue *g;
-
- for (g = &ptr->__sglue; g != NULL; g = g->_next)
- for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
- if (fp->_flags != 0)
- ret |= fclose (fp);
- return ret;
+ return _fwalk (ptr, fclose);
}
#ifndef _REENT_ONLY
diff --git a/newlib/libc/stdio/fdopen.c b/newlib/libc/stdio/fdopen.c
index 0db6062dd..8c1555d34 100644
--- a/newlib/libc/stdio/fdopen.c
+++ b/newlib/libc/stdio/fdopen.c
@@ -76,6 +76,9 @@ _DEFUN (_fdopen_r, (ptr, fd, mode),
if ((fp = __sfp (ptr)) == 0)
return 0;
+
+ _flockfile(fp);
+
fp->_flags = flags;
/*
* If opened for appending, but underlying descriptor
@@ -111,6 +114,7 @@ _DEFUN (_fdopen_r, (ptr, fd, mode),
fp->_flags |= __SCLE;
#endif
+ _funlockfile(fp);
return fp;
}
diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c
index 0ddbf9403..10f01b271 100644
--- a/newlib/libc/stdio/findfp.c
+++ b/newlib/libc/stdio/findfp.c
@@ -25,10 +25,6 @@
#include <sys/lock.h>
#include "local.h"
-#ifndef __SINGLE_THREAD__
-__LOCK_INIT(static, __sfp_lock);
-#endif
-
static void
std (ptr, flags, file, data)
FILE *ptr;
@@ -49,8 +45,12 @@ std (ptr, flags, file, data)
ptr->_write = __swrite;
ptr->_seek = __sseek;
ptr->_close = __sclose;
-#ifndef __SINGLE_THREAD__
+#if !defined(__SINGLE_THREAD__) && !defined(_REENT_SMALL)
__lock_init_recursive (*(_LOCK_RECURSIVE_T *)&ptr->_lock);
+ /*
+ * #else
+ * lock is already initialized in __sfp
+ */
#endif
#ifdef __SCLE
@@ -90,9 +90,7 @@ __sfp (d)
int n;
struct _glue *g;
-#ifndef __SINGLE_THREAD__
- __lock_acquire(__sfp_lock);
-#endif
+ __sfp_lock_acquire ();
if (!_GLOBAL_REENT->__sdidinit)
__sinit (_GLOBAL_REENT);
@@ -105,24 +103,24 @@ __sfp (d)
(g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL)
break;
}
-#ifndef __SINGLE_THREAD__
- __lock_release(__sfp_lock);
-#endif
+ __sfp_lock_release ();
d->_errno = ENOMEM;
return NULL;
found:
+ fp->_file = -1; /* no file */
fp->_flags = 1; /* reserve this slot; caller sets real flags */
#ifndef __SINGLE_THREAD__
- __lock_release(__sfp_lock);
+ __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
#endif
+ __sfp_lock_release ();
+
fp->_p = NULL; /* no current pointer */
fp->_w = 0; /* nothing to read or write */
fp->_r = 0;
fp->_bf._base = NULL; /* no buffer */
fp->_bf._size = 0;
fp->_lbfsize = 0; /* not line buffered */
- fp->_file = -1; /* no file */
/* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */
fp->_ub._base = NULL; /* no ungetc buffer */
fp->_ub._size = 0;
@@ -197,6 +195,20 @@ __sinit (s)
#ifndef __SINGLE_THREAD__
+__LOCK_INIT_RECURSIVE(static, __sfp_lock);
+
+void
+__sfp_lock_acquire ()
+{
+ __lock_acquire(__sfp_lock);
+}
+
+void
+__sfp_lock_release ()
+{
+ __lock_release(__sfp_lock);
+}
+
/* Walkable file locking routine. */
static int
__fp_lock (ptr)
@@ -220,8 +232,6 @@ __fp_unlock (ptr)
void
__fp_lock_all ()
{
- __lock_acquire(__sfp_lock);
-
(void) _fwalk (_REENT, __fp_lock);
}
@@ -229,7 +239,5 @@ void
__fp_unlock_all ()
{
(void) _fwalk (_REENT, __fp_unlock);
-
- __lock_release(__sfp_lock);
}
#endif
diff --git a/newlib/libc/stdio/fopen.c b/newlib/libc/stdio/fopen.c
index bcd2287c5..844e6dc05 100644
--- a/newlib/libc/stdio/fopen.c
+++ b/newlib/libc/stdio/fopen.c
@@ -138,10 +138,17 @@ _DEFUN (_fopen_r, (ptr, file, mode),
if ((f = _open_r (ptr, file, oflags, 0666)) < 0)
{
+ __sfp_lock_acquire ();
fp->_flags = 0; /* release */
+#ifndef __SINGLE_THREAD__
+ __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
+#endif
+ __sfp_lock_release ();
return NULL;
}
+ _flockfile(fp);
+
fp->_file = f;
fp->_flags = flags;
fp->_cookie = (_PTR) fp;
@@ -158,10 +165,7 @@ _DEFUN (_fopen_r, (ptr, file, mode),
fp->_flags |= __SCLE;
#endif
-#ifndef __SINGLE_THREAD__
- __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
-#endif
-
+ _funlockfile(fp);
return fp;
}
diff --git a/newlib/libc/stdio/freopen.c b/newlib/libc/stdio/freopen.c
index ba83dd215..dd42aaae1 100644
--- a/newlib/libc/stdio/freopen.c
+++ b/newlib/libc/stdio/freopen.c
@@ -87,14 +87,17 @@ _DEFUN (_freopen_r, (ptr, file, mode, fp),
register int f;
int flags, oflags, e;
+ __sfp_lock_acquire ();
+
_flockfile(fp);
CHECK_INIT (fp);
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
- (void) fclose (fp);
_funlockfile(fp);
+ (void) fclose (fp);
+ __sfp_lock_release ();
return NULL;
}
@@ -148,12 +151,13 @@ _DEFUN (_freopen_r, (ptr, file, mode, fp),
if (f < 0)
{ /* did not get it after all */
+ fp->_flags = 0; /* set it free */
ptr->_errno = e; /* restore in case _close clobbered */
_funlockfile(fp);
#ifndef __SINGLE_THREAD__
__lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
#endif
- fp->_flags = 0; /* set it free */
+ __sfp_lock_release ();
return NULL;
}
@@ -171,6 +175,7 @@ _DEFUN (_freopen_r, (ptr, file, mode, fp),
#endif
_funlockfile(fp);
+ __sfp_lock_release ();
return fp;
}
diff --git a/newlib/libc/stdio/fwalk.c b/newlib/libc/stdio/fwalk.c
index b147da3af..566fa4af8 100644
--- a/newlib/libc/stdio/fwalk.c
+++ b/newlib/libc/stdio/fwalk.c
@@ -26,8 +26,8 @@ static char sccsid[] = "%W% (Berkeley) %G%";
#include <errno.h>
#include "local.h"
-int
-_fwalk (ptr, function)
+static int
+__fwalk (ptr, function)
struct _reent *ptr;
register int (*function) ();
{
@@ -35,20 +35,36 @@ _fwalk (ptr, function)
register int n, ret = 0;
register struct _glue *g;
+ for (g = &ptr->__sglue; g != NULL; g = g->_next)
+ for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
+ if (fp->_flags != 0)
+ {
+ _flockfile (fp);
+ if (fp->_flags != 0 && fp->_file != -1)
+ ret |= (*function) (fp);
+ _funlockfile (fp);
+ }
+
+ return ret;
+}
+
+int
+_fwalk (ptr, function)
+ struct _reent *ptr;
+ register int (*function) ();
+{
+ register int ret = 0;
+
+ __sfp_lock_acquire ();
+
/* Must traverse given list for std streams. */
if (ptr != _GLOBAL_REENT)
- {
- for (g = &ptr->__sglue; g != NULL; g = g->_next)
- for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
- if (fp->_flags != 0)
- ret |= (*function) (fp);
- }
+ ret |= __fwalk (ptr, function);
/* Must traverse global list for all other streams. */
- for (g = &_GLOBAL_REENT->__sglue; g != NULL; g = g->_next)
- for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
- if (fp->_flags != 0)
- ret |= (*function) (fp);
+ ret |= __fwalk (_GLOBAL_REENT, function);
+
+ __sfp_lock_release ();
return ret;
}
diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h
index b4f4457fc..d97a03e9a 100644
--- a/newlib/libc/stdio/local.h
+++ b/newlib/libc/stdio/local.h
@@ -87,3 +87,11 @@ char *_EXFUN(_llicvt,(char *, long long, char));
#define CVT_BUF_SIZE 128
#define NDYNAMIC 4 /* add four more whenever necessary */
+
+#ifdef __SINGLE_THREAD__
+#define __sfp_lock_acquire()
+#define __sfp_lock_release()
+#else
+void _EXFUN(__sfp_lock_acquire,(void));
+void _EXFUN(__sfp_lock_release,(void));
+#endif
diff --git a/newlib/libc/stdio64/fdopen64.c b/newlib/libc/stdio64/fdopen64.c
index d0fd0d584..aa5a9ce56 100644
--- a/newlib/libc/stdio64/fdopen64.c
+++ b/newlib/libc/stdio64/fdopen64.c
@@ -63,6 +63,9 @@ _DEFUN (_fdopen64_r, (ptr, fd, mode),
if ((fp = __sfp (ptr)) == 0)
return 0;
+
+ _flockfile(fp);
+
fp->_flags = flags;
/*
* If opened for appending, but underlying descriptor
@@ -99,12 +102,9 @@ _DEFUN (_fdopen64_r, (ptr, fd, mode),
fp->_flags |= __SCLE;
#endif
-#ifndef __SINGLE_THREAD__
- __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
-#endif
-
fp->_flags |= __SL64;
+ _funlockfile(fp);
return fp;
}
diff --git a/newlib/libc/stdio64/fopen64.c b/newlib/libc/stdio64/fopen64.c
index 3c69820ee..1feffd1db 100644
--- a/newlib/libc/stdio64/fopen64.c
+++ b/newlib/libc/stdio64/fopen64.c
@@ -91,10 +91,17 @@ _DEFUN (_fopen64_r, (ptr, file, mode),
if ((f = _open64_r (ptr, file, oflags, 0666)) < 0)
{
+ __sfp_lock_acquire ();
fp->_flags = 0; /* release */
+#ifndef __SINGLE_THREAD__
+ __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
+#endif
+ __sfp_lock_release ();
return NULL;
}
+ _flockfile(fp);
+
fp->_file = f;
fp->_flags = flags;
fp->_cookie = (_PTR) fp;
@@ -114,10 +121,7 @@ _DEFUN (_fopen64_r, (ptr, file, mode),
fp->_flags |= __SL64;
-#ifndef __SINGLE_THREAD__
- __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
-#endif
-
+ _funlockfile(fp);
return fp;
}
diff --git a/newlib/libc/stdio64/freopen64.c b/newlib/libc/stdio64/freopen64.c
index 6e4586cd9..c28cbeee2 100644
--- a/newlib/libc/stdio64/freopen64.c
+++ b/newlib/libc/stdio64/freopen64.c
@@ -70,6 +70,7 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <sys/lock.h>
#include "local64.h"
/*
@@ -88,14 +89,17 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
register int f;
int flags, oflags, e;
+ __sfp_lock_acquire ();
+
_flockfile(fp);
CHECK_INIT (fp);
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
- (void) fclose (fp);
_funlockfile(fp);
+ (void) fclose (fp);
+ __sfp_lock_release ();
return NULL;
}
@@ -152,6 +156,10 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
fp->_flags = 0; /* set it free */
ptr->_errno = e; /* restore in case _close clobbered */
_funlockfile(fp);
+#ifndef __SINGLE_THREAD__
+ __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
+#endif
+ __sfp_lock_release ();
return NULL;
}
@@ -172,6 +180,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
fp->_flags |= __SL64;
_funlockfile(fp);
+ __sfp_lock_release ();
return fp;
}