Date: Mon, 12 Feb 2001 19:28:30 -0500 From: Daniel Eischen <eischen@vigrid.com> To: Warner Losh <imp@harmony.village.org> Cc: John Indra <john@office.naver.co.id>, freebsd-current@FreeBSD.ORG Subject: Patch for FILE problems (was Re: -CURRENT is bad for me...) Message-ID: <3A887FAE.CF15C4BE@vigrid.com> References: <md5:A7E854B5C23FF2AEECF4F650019BBD3D>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Attached is a patch that attempts to work around recent stdio
breakage in -current. I've verified it compiles, but won't be
able to test it until at least tomorrow. If someone wants to
review it and verify it works, I'll commit it.
Thanks,
--
Dan Eischen
[-- Attachment #2 --]
Index: include/stdio.h
===================================================================
RCS file: /opt/FreeBSD/cvs/src/include/stdio.h,v
retrieving revision 1.28
diff -u -r1.28 stdio.h
--- include/stdio.h 2001/02/12 03:31:23 1.28
+++ include/stdio.h 2001/02/12 23:21:41
@@ -96,6 +96,39 @@
*
* NB: see WARNING above before changing the layout of this structure!
*/
+typedef struct __old_sFILE {
+ unsigned char *_p; /* current position in (some) buffer */
+ int _r; /* read space left for getc() */
+ int _w; /* write space left for putc() */
+ short _flags; /* flags, below; this FILE is free if 0 */
+ short _file; /* fileno, if Unix descriptor, else -1 */
+ struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
+ int _lbfsize; /* 0 or -_bf._size, for inline putc */
+
+ /* operations */
+ void *_cookie; /* cookie passed to io functions */
+ int (*_close) __P((void *));
+ int (*_read) __P((void *, char *, int));
+ fpos_t (*_seek) __P((void *, fpos_t, int));
+ int (*_write) __P((void *, const char *, int));
+
+ /* separate buffer for long sequences of ungetc() */
+ struct __sbuf _ub; /* ungetc buffer */
+ unsigned char *_up; /* saved _p when _p is doing ungetc data */
+ int _ur; /* saved _r when _r is counting ungetc data */
+
+ /* tricks to meet minimum requirements even when malloc() fails */
+ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
+ unsigned char _nbuf[1]; /* guarantee a getc() buffer */
+
+ /* separate buffer for fgetln() when line crosses buffer boundary */
+ struct __sbuf _lb; /* buffer for fgetln() */
+
+ /* Unix stdio files get aligned to block boundaries on fseek() */
+ int _blksize; /* stat.st_blksize (may be != _bf._size) */
+ fpos_t _offset; /* current lseek offset (see WARNING) */
+} __old_FILE;
+
typedef struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */
@@ -131,7 +164,7 @@
} FILE;
__BEGIN_DECLS
-extern FILE __sF[];
+extern __old_FILE __sF[];
__END_DECLS
#define __SLBF 0x0001 /* line buffered */
@@ -194,9 +227,9 @@
#define SEEK_END 2 /* set file offset to EOF plus offset */
#endif
-#define stdin (&__sF[0])
-#define stdout (&__sF[1])
-#define stderr (&__sF[2])
+#define stdin ((FILE *)&__sF[0])
+#define stdout ((FILE *)&__sF[1])
+#define stderr ((FILE *)&__sF[2])
/*
* Functions defined in ANSI C standard.
Index: lib/libc/stdio/_flock_stub.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libc/stdio/_flock_stub.c,v
retrieving revision 1.5
diff -u -r1.5 _flock_stub.c
--- lib/libc/stdio/_flock_stub.c 2001/02/11 22:06:39 1.5
+++ lib/libc/stdio/_flock_stub.c 2001/02/12 23:16:41
@@ -67,6 +67,21 @@
int fl_count; /* recursive lock count */
};
+static FILE std_files[3];
+
+static inline FILE *
+get_file_with_lock(FILE *fp)
+{
+ if (fp == stdin)
+ return (&std_files[0]);
+ else if (fp == stdout)
+ return (&std_files[1]);
+ else if (fp == stderr)
+ return (&std_files[2]);
+ else
+ return (fp);
+}
+
/*
* Allocate and initialize a file lock.
*/
@@ -89,9 +104,10 @@
}
void
-_flockfile(FILE *fp)
+_flockfile(FILE *f)
{
pthread_t curthread = _pthread_self();
+ FILE *fp = get_file_with_lock(f);
/*
* Check if this is a real file with a valid lock, creating
@@ -123,9 +139,10 @@
}
int
-_ftrylockfile(FILE *fp)
+_ftrylockfile(FILE *f)
{
pthread_t curthread = _pthread_self();
+ FILE *fp = get_file_with_lock(f);
int ret = 0;
/*
@@ -153,9 +170,10 @@
}
void
-_funlockfile(FILE *fp)
+_funlockfile(FILE *f)
{
pthread_t curthread = _pthread_self();
+ FILE *fp = get_file_with_lock(f);
/*
* Check if this is a real file with a valid lock owned
Index: lib/libc/stdio/findfp.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libc/stdio/findfp.c,v
retrieving revision 1.12
diff -u -r1.12 findfp.c
--- lib/libc/stdio/findfp.c 2001/02/12 03:31:23 1.12
+++ lib/libc/stdio/findfp.c 2001/02/13 00:05:09
@@ -65,15 +65,14 @@
/* the usual - (stdin + stdout + stderr) */
static FILE usual[FOPEN_MAX - 3];
-static struct glue uglue = { NULL, FOPEN_MAX - 3, usual };
-FILE __sF[3] = {
+__old_FILE __sF[3] = {
std(__SRD, STDIN_FILENO), /* stdin */
std(__SWR, STDOUT_FILENO), /* stdout */
std(__SWR|__SNBF, STDERR_FILENO) /* stderr */
};
-struct glue __sglue = { &uglue, 3, __sF };
-static struct glue *lastglue = &uglue;
+struct glue __sglue = { NULL, FOPEN_MAX - 3, usual };
+static struct glue *lastglue = &__sglue;
static struct glue * moreglue __P((int));
@@ -123,6 +122,13 @@
* The list must be locked because a FILE may be updated.
*/
THREAD_LOCK();
+ /* Check std{in,out,err} first. */
+ for (n = 0; n < 3; n++) {
+ if (__sF[n]._flags == 0) {
+ fp = (FILE *)&__sF[n];
+ goto found;
+ }
+ }
for (g = &__sglue; g != NULL; g = g->next) {
for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
if (fp->_flags == 0)
Index: lib/libc/stdio/fwalk.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libc/stdio/fwalk.c,v
retrieving revision 1.8
diff -u -r1.8 fwalk.c
--- lib/libc/stdio/fwalk.c 2001/02/11 22:06:42 1.8
+++ lib/libc/stdio/fwalk.c 2001/02/13 00:02:19
@@ -65,6 +65,10 @@
* Avoid locking this list while walking it or else you will
* introduce a potential deadlock in [at least] refill.c.
*/
+ for (n = 0; n < 3; n++) {
+ if ((__sF[n]._flags != 0) && ((__sF[n]._flags & __SIGN) == 0))
+ ret |= (*function)((FILE *)&__sF[n]);
+ }
for (g = &__sglue; g != NULL; g = g->next)
for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
if ((fp->_flags != 0) && ((fp->_flags & __SIGN) == 0))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3A887FAE.CF15C4BE>
