[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] stdio write problem in mintlib



Alan Hourihane a écrit:
Now we default to binary if UNIXMODE specifies it for stdin, stdout and
stderr. If UNIXMODE doesn't specify 'b', then it's only when isatty(x)
is true that we're in binary mode & under FreeMiNT - see further down
the file for this. Should these change too ??

According to me, here is how it should work (like Cygwin)
- default mode (text or binary, according to UNIXMODE) must be only used for regular files - textmode must be used for the TOS console (because is doesn't work in binmode)
- binmode must be used in all the other cases (including pipes)

I have a attached a new patch which replaces the last one.
It works perfectly for me with ARAnym and TOS.

And good new, it solves the original problem with the shell ` ` syntax.

If anyone agrees, this one should be committed.

--
Vincent Rivière

diff -aurN mintlib-CVS-20080109/mintlib/main.c mintlib-CVS-20080109-patch-20080109/mintlib/main.c
--- mintlib-CVS-20080109/mintlib/main.c	2008-01-09 11:54:15.921875000 +0100
+++ mintlib-CVS-20080109-patch-20080109/mintlib/main.c	2008-01-10 00:16:36.312500000 +0100
@@ -19,6 +19,7 @@
 #include <mint/ssystem.h>
 #include <mint/sysvars.h>
 #include <sys/param.h>
+#include <sys/stat.h>
 
 #include "lib.h"
 
@@ -31,8 +32,41 @@
 
 /* in defmode.c or defined by user */
 extern __io_mode __default_mode__;
-
-void __libc_main (long, char **, char **);
+
+/* Initialize a stream with the correct text or binary mode.  */
+static void
+init_stream_mode(FILE* stream)
+{
+	int fd;
+	struct stat st;
+	int result;
+
+	/* By default, the standard streams use binary mode.
+	 * This is especially important for the pipes and the console.
+	 */
+	__set_binmode(stream, 1);
+
+	fd = fileno(stream);
+	if (fd < 0)
+		return;
+
+	if (!__mint && isatty(fd))
+	{
+		/* The current implementation of the TOS console needs textmode.  */
+		__set_binmode(stream, 0);
+		return;
+	}
+    
+	result = fstat(fd, &st);
+	if (result < 0)
+		return;
+
+	/* If the standard stream is redirected to a regular file,
+	 * use the mode requested by the user via the UNIXMODE variable.
+	 */
+    if (S_ISREG(st.st_mode))
+		__set_binmode(stream, __default_mode__.__binary);
+}
 
 void
 __libc_main (long _argc, char **_argv, char **_envp)
@@ -165,20 +199,16 @@
 	setvbuf (stdout, NULL, _IOLBF, 0);
 	setvbuf (stderr, NULL, _IONBF, 0);
 
-	/* Flag device streams.  */
-	if (isatty (0)) {
-		if (__mint) stdin->__mode.__binary = 1;
-	}
-	if (isatty (1)) {
-		if (__mint) stdout->__mode.__binary = 1;
-	} else {
-		/* If redirected, make stdout fully buffered.  */
-		setvbuf (stdout, NULL, _IOFBF, 0);
-	}
-	if (isatty (2)) {
-		if (__mint) stderr->__mode.__binary = 1;
-	}
-
+	if (!isatty (1)) {
+		/* If redirected, make stdout fully buffered.  */
+		setvbuf (stdout, NULL, _IOFBF, 0);
+	}
+
+	/* Set the standard streams with the the correct text or binary mode.  */
+	init_stream_mode(stdin);
+	init_stream_mode(stdout);
+	init_stream_mode(stderr);
+
 #if 0
 /* used in limits.h, stdio.h */
 #define	_NFILE		(32)		/* maximum number of open streams */