Browse Source

Fix the handle locking in stdio to use flockfile/funlockfile

internally when and where required.  Macros in <stdio.h> are updated
to automatically call the underlying functions when the process is
threaded to obtain the necessary locking.  A private mutex is added
to protect __sglue, the internal list of FILE handles, and another
to protect the one-time initialization.  Some routines in libc that
use getc() change to use getc_unlocked() as they're either protected
by their own lock or aren't thread-safe routines anyway.
ok kurt@, earlier version tested by sthen@ and jj@
OPENBSD_4_7
guenther 15 years ago
parent
commit
4645a9665c
1 changed files with 19 additions and 19 deletions
  1. +19
    -19
      src/include/stdio.h

+ 19
- 19
src/include/stdio.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: stdio.h,v 1.35 2006/01/13 18:10:09 miod Exp $ */
/* $OpenBSD: stdio.h,v 1.36 2009/10/21 16:04:23 guenther Exp $ */
/* $NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $ */ /* $NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $ */
/*- /*-
@ -157,6 +157,7 @@ __END_DECLS
#define __SOFF 0x1000 /* set iff _offset is in fact correct */ #define __SOFF 0x1000 /* set iff _offset is in fact correct */
#define __SMOD 0x2000 /* true => fgetln modified _p text */ #define __SMOD 0x2000 /* true => fgetln modified _p text */
#define __SALC 0x4000 /* allocate string space dynamically */ #define __SALC 0x4000 /* allocate string space dynamically */
#define __SIGN 0x8000 /* ignore this file in _fwalk */
/* /*
* The following three definitions are for ANSI C, which took them * The following three definitions are for ANSI C, which took them
@ -322,12 +323,6 @@ char *tempnam(const char *, const char *);
#endif #endif
__END_DECLS __END_DECLS
#ifndef _POSIX_THREADS
# define flockfile(fp) /* nothing */
# define ftrylockfile(fp) (0)
# define funlockfile(fp) /* nothing */
#endif
#endif /* __BSD_VISIBLE || __POSIX_VISIBLE || __XPG_VISIBLE */ #endif /* __BSD_VISIBLE || __POSIX_VISIBLE || __XPG_VISIBLE */
/* /*
@ -402,32 +397,37 @@ static __inline int __sputc(int _c, FILE *_p) {
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file) #define __sfileno(p) ((p)->_file)
#define feof(p) __sfeof(p)
#define ferror(p) __sferror(p)
extern int __isthreaded;
#ifndef _POSIX_THREADS
#define clearerr(p) __sclearerr(p)
#endif
#define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p))
#define ferror(p) (!__isthreaded ? __sferror(p) : (ferror)(p))
#define clearerr(p) (!__isthreaded ? __sclearerr(p) : (clearerr)(p))
#if __POSIX_VISIBLE #if __POSIX_VISIBLE
#define fileno(p) __sfileno(p)
#define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p))
#endif #endif
#define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp))
#if __BSD_VISIBLE
/*
* The macro implementations of putc and putc_unlocked are not
* fully POSIX compliant; they do not set errno on failure
*/
#define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp))
#endif /* __BSD_VISIBLE */
#ifndef lint #ifndef lint
#ifndef _POSIX_THREADS
#define getc(fp) __sgetc(fp)
#endif /* _POSIX_THREADS */
#if __POSIX_VISIBLE >= 199506
#define getc_unlocked(fp) __sgetc(fp) #define getc_unlocked(fp) __sgetc(fp)
/* /*
* The macro implementations of putc and putc_unlocked are not * The macro implementations of putc and putc_unlocked are not
* fully POSIX compliant; they do not set errno on failure * fully POSIX compliant; they do not set errno on failure
*/ */
#if __BSD_VISIBLE #if __BSD_VISIBLE
#ifndef _POSIX_THREADS
#define putc(x, fp) __sputc(x, fp)
#endif /* _POSIX_THREADS */
#define putc_unlocked(x, fp) __sputc(x, fp) #define putc_unlocked(x, fp) __sputc(x, fp)
#endif /* __BSD_VISIBLE */ #endif /* __BSD_VISIBLE */
#endif /* __POSIX_VISIBLE >= 199506 */
#endif /* lint */ #endif /* lint */
#define getchar() getc(stdin) #define getchar() getc(stdin)


Loading…
Cancel
Save