Skip site navigation (1)Skip section navigation (2)
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
This is a multi-part message in MIME format.
--------------F1DE339299AEF4912D6989B0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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
--------------F1DE339299AEF4912D6989B0
Content-Type: text/plain; charset=us-ascii;
 name="stdio.diffs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="stdio.diffs"

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))

--------------F1DE339299AEF4912D6989B0--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3A887FAE.CF15C4BE>