+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
if (fp == NULL)
return (0); /* on NULL */
+ __sfp_lock_acquire ();
+
_flockfile(fp);
CHECK_INIT (fp);
if (fp->_flags == 0) /* not open! */
{
_funlockfile(fp);
+ __sfp_lock_release ();
return (0);
}
r = fp->_flags & __SWR ? fflush (fp) : 0;
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);
}
_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
if ((fp = __sfp (ptr)) == 0)
return 0;
+
+ _flockfile(fp);
+
fp->_flags = flags;
/*
* If opened for appending, but underlying descriptor
fp->_flags |= __SCLE;
#endif
+ _funlockfile(fp);
return fp;
}
#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;
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
int n;
struct _glue *g;
-#ifndef __SINGLE_THREAD__
- __lock_acquire(__sfp_lock);
-#endif
+ __sfp_lock_acquire ();
if (!_GLOBAL_REENT->__sdidinit)
__sinit (_GLOBAL_REENT);
(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;
#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)
void
__fp_lock_all ()
{
- __lock_acquire(__sfp_lock);
-
(void) _fwalk (_REENT, __fp_lock);
}
__fp_unlock_all ()
{
(void) _fwalk (_REENT, __fp_unlock);
-
- __lock_release(__sfp_lock);
}
#endif
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;
fp->_flags |= __SCLE;
#endif
-#ifndef __SINGLE_THREAD__
- __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
-#endif
-
+ _funlockfile(fp);
return 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;
}
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;
}
#endif
_funlockfile(fp);
+ __sfp_lock_release ();
return fp;
}
#include <errno.h>
#include "local.h"
-int
-_fwalk (ptr, function)
+static int
+__fwalk (ptr, function)
struct _reent *ptr;
register int (*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;
}
#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
if ((fp = __sfp (ptr)) == 0)
return 0;
+
+ _flockfile(fp);
+
fp->_flags = flags;
/*
* If opened for appending, but underlying descriptor
fp->_flags |= __SCLE;
#endif
-#ifndef __SINGLE_THREAD__
- __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
-#endif
-
fp->_flags |= __SL64;
+ _funlockfile(fp);
return fp;
}
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;
fp->_flags |= __SL64;
-#ifndef __SINGLE_THREAD__
- __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock);
-#endif
-
+ _funlockfile(fp);
return fp;
}
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <sys/lock.h>
#include "local64.h"
/*
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;
}
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;
}
fp->_flags |= __SL64;
_funlockfile(fp);
+ __sfp_lock_release ();
return fp;
}