Problems with MMIX _read function

Florian Schrack florian.schrack@freenet.de
Tue Jul 9 03:11:00 GMT 2002


I have installed the most recent version of Prof. Knuth's MMIX
simulator. Furthermore I have successfully compiled the gcc/binutils
toolchain for the MMIX target, using newlib as the C library (gcc and
binutils/newlib 

The compiler works fine as far as I can say, but the implementation of
the _read function (newlib/libc/sys/mmixware/read.c) seems incompatible
with the normal UNIX read syscall, resulting in strange I/O behavior on
terminals: When you call the UNIX read function to read a certain number
of characters from a terminal, it stops reading if it encounters a '\n'
character in the input, even before having read the desired number of
characters. The MMIX _read function, however, calls the MMIXWARE
SYS_Fread syscall, which does *not* stop after encountering a newline.

The problem described above makes it very difficult to write interactive
programs: the functions commonly used to read *one* line from a
terminal, such as fgets(), simply don't return after having read one
line, but they continue reading until the buffer is filled up (usually
after 1024 characters, I think).

A possible soultion would be to test if the file descriptor given to the
_read function points to a terminal (isatty()) and to use the SYS_Fgets
call instead of the SYS_Fread call on terminals.

I have included a patch below that does just that. Due to the semantics
of the SYS_Fgets call, the patched function reads at most size - 1
characters on terminals; I don't know if that is a problem. I have
mapped the return value -1 of the SYS_Fgets call to 0 as it indicates
EOF according to Knuth's documentation.

I have tested the patch and it seems that it solves my problem. Although
I could not find any new problems introduced by my code, it would be
nice if some newlib maintainer could comment on it and perhaps commit it
to the CVS repository.

Here is the diff:

*** newlib/libc/sys/mmixware/read.c.orig	Tue Jul  9 10:25:45 2002
--- newlib/libc/sys/mmixware/read.c	Tue Jul  9 10:35:48 2002
***************
*** 27,38 ****
--- 27,48 ----
    if ((unsigned int) file >= 32 || _MMIX_allocated_filehandle[file] == 0)
      {
        errno = EBADF;
        return -1;
      }
  
+   if (isatty(file))
+     {
+       ret = TRAP3f (SYS_Fgets, file, ptr, len);
+ 
+       if (ret == -1)
+         return 0;
+ 
+       return ret;
+     }
+ 
    ret = TRAP3f (SYS_Fread, file, ptr, len);
  
    /* Map the return codes:
       -1-len: an error.  We return -1.
       0: success.  We return len.
       n-len: end-of-file after n chars read.  We return n. */
*** newlib/libc/sys/mmixware/sys/syscall.h.orig	Tue Jul  9 11:51:55 2002
--- newlib/libc/sys/mmixware/sys/syscall.h	Tue Jul  9 11:53:06 2002
***************
*** 17,22 ****
--- 17,23 ----
  #define	SYS_Fopen	1
  #define	SYS_Fclose	2
  #define	SYS_Fread	3
+ #define	SYS_Fgets	4
  #define	SYS_Fwrite	6
  #define	SYS_Fseek	9
  #define	SYS_Ftell	10

-- 
Florian Schrack <florian.schrack@freenet.de>



More information about the Newlib mailing list