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

Patch for Cconrs



Hi there!

I'm currently writing an XFS for MagiC, where you have to implement your own
readline-function which is called whenever a process calles Cconrs for a
File on your FS. To ensure I do this right, I've checked the behaviour of
TOS and MiNT and noticed that MiNT's c_conrs is broken as soon as stdin is
redirected to a file.

An example. The file contains:
line1
line2
line3

Stdin is redirected to that File, and normally a Cconrs with len == 80 would
return line1, the next call would return line2, etc. With MiNT, the first
call returns line1, the second returns nothing. That's because MiNT always
reads 80 bytes, so that in the case the whole file is read. After the Fread,
MiNT looks for a CR/LF and cuts the line at the point, so the rest is lost.

As long as stdin is connected to a tty, this doesn't matter, because Fread
will automatically stop reading when a LF is encountered, the problem really
only arises when you read from a file.

Below is a little diff for this. Please tell me if I got something wrong,
but I'm quite sure that the behaviour I described above is incorrect.

There a second diff for mint.h to prevent those annoying warning messages
about DEBUG being redefined when you compile MiNT with the Makefile found
in the 1.12.h5 original distribution.

Ah, before I forget: The diffs are relative to 1.12.h5


Ciao

Thomas


--
/----------------------------------------------------------------------------\
| Thomas Binder (IRCNick: Gryf)                | "Quick to judge, quick to   |
| Johann-Valentin-May-Strasse 7                |  anger, slow to understand, |
| 64665 Alsbach-Haehnlein / Germany            |  ignorance, prejudice and   |
| Email: binder@rbg.informatik.th-darmstadt.de |  fear walk hand in hand."   |
| PGP-key available on request!                |                        Rush |
\----------------------------------------------------------------------------/
-- cut here ------------------------------------------------------------------
--- console.c.orig	Thu Nov  2 22:39:00 1995
+++ console.c	Thu Jan 18 23:06:52 1996
@@ -171,29 +171,73 @@
 
 long ARGS_ON_STACK
 c_conrs(buf)
 	char *buf;
 {
-	long size, r;
-	char *s;
+	long size, count, r;
+	char dummy;
 
 	size = ((long)*buf) & 0xff;
-	r = f_read(0, size, buf+2);
-	if (r < 0) {
-		buf[1] = 0;
-		return r;
+	if (is_terminal(curproc->handle[0]))
+	{
+/*
+ * TB: When reading from a terminal, f_read is used which automatically
+ * breaks at the first newline
+ */
+		r = f_read(0, size, buf + 2);
+		if (r < 0)
+			buf[1] = 0;
+		else
+			buf[1] = (char)r;
+		return (r < 0) ? r : 0;
 	}
-/* if reading from a file, stop at first CR or LF encountered */
-	s = buf+2;
-	size = 0;
-	while(r-- > 0) {
-		if (*s == '\r' || *s == '\n')
-			break;
-		s++; size++;
+/*
+ * TB: In all other cases, we must read character by character, breaking
+ * at a newline or carriage return, or when the maximum number of
+ * characters has been read
+ */
+	for (count = 0L;; count++)
+	{
+		if (count == size)
+		{
+			buf[1] = (char)count;
+		  	buf[count + 2] = 0;
+			return 0;
+		}
+		r = c_conin();
+/* Also break on error... */
+		if (r < 0)
+		{
+			buf[count + 2] = 0;
+			buf[1] = (char)count;
+			return r;
+		}
+		dummy = (char)r;
+/* ... or at EOF */
+		if (dummy == MiNTEOF)
+		{
+			buf[count + 2] = 0;
+			buf[1] = (char)count;
+			return 0;
+		}
+		if ((dummy == '\r') || (dummy == '\n'))
+		{
+			buf[count + 2] = 0;
+			buf[1] = (char)count;
+/*
+ * When we've read a carriage return, the next char has to be skipped,
+ * because it usually is a linefeed (GEMDOS-style lines end with CR/LF).
+ * Problems may occur with files that have lines ending with CR only, but
+ * I have not seen many yet.
+ */
+			if (dummy == '\r')
+				return f_read(0, 1L, &dummy);
+			else
+				return 0;
+		}
+		buf[count + 2] = dummy;
 	}
-	buf[1] = (char)size;
-	return 0;
 }
 
 long ARGS_ON_STACK
 c_conis()
 {
--- mint.h.orig	Sun Jun 11 13:40:02 1995
+++ mint.h	Thu Jan  4 13:22:46 1996
@@ -257,11 +257,11 @@
 #define TRUE 1
 #define FALSE 0
 #endif
 
 /* is debugging info included? */
-#ifndef MULTITOS
+#if !defined(MULTITOS) && !defined(DEBUG_INFO)
 #define DEBUG_INFO
 #endif
 
 #include "debug.h"