mescc: Mes C Library: Fix ungetc.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 16 Mar 2019 10:55:00 +0000 (11:55 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 16 Mar 2019 10:55:00 +0000 (11:55 +0100)
* include/sys/resource.h (OPEN_MAX, RLIMIT_NOFILE): New macro.
* lib/libc.c: Add memset.c include.
* lib/libc+tcc.c: Remove memset.c include.
* lib/linux/tcc.c (close):
* lib/mes/fdgetc.c (__ungetc_buf): New global.
(_ungetc_pos, _ungetc_fd, _ungetc_buf): Remove.  Update users.
* scaffold/tests/65-read.c: Update.

include/sys/resource.h
lib/libc+tcc.c
lib/libc.c
lib/linux/libc.c
lib/linux/tcc.c
lib/mes/fdgetc.c
lib/mes/fdungetc.c
scaffold/tests/65-read.c

index 276405ba84d06d5bb699bf4aae498b7524b11f43..ebf5809ab21f42a5c73b0668a0dfa3c440b17b1f 100644 (file)
@@ -50,6 +50,8 @@ struct rusage
 
 #define RUSAGE_SELF 0
 #define RUSAGE_CHILDREN -1
+#define RLIMIT_NOFILE 1024
+#define OPEN_MAX RLIMIT_NOFILE
 
 int getrusage (int processes, struct rusage *rusage);
 
index 177da71bfa244a44057a61dfef951b6b830266b3..a788dc91dc56f002c3dfd5ae6f13f6d1204cac73 100644 (file)
@@ -93,7 +93,6 @@ int errno;
 #include <stdlib/strtoull.c>
 #include <string/memmem.c>
 #include <string/memmove.c>
-#include <string/memset.c>
 #include <string/strcat.c>
 #include <string/strchr.c>
 #include <string/strlwr.c>
index 2c88613783ada924760f25860553811316114707..b37fc9bd7a250850652fe7b8e50b54cc20fa5cec 100644 (file)
@@ -74,6 +74,7 @@ __mes_debug ()
 
 #include <string/memchr.c>
 #include <string/memcmp.c>
+#include <string/memset.c>
 #include <string/strcmp.c>
 #include <string/strcpy.c>
 #include <string/strncmp.c>
index 6d990c27b82c2165af877b40c4a76edc618d3ec2..7f6a1fc70165888f563b152b307df58da7f9b0a0 100644 (file)
@@ -69,14 +69,10 @@ read (int filedes, void *buffer, size_t size)
 int
 _open3 (char const *file_name, int flags, int mask)
 {
-#if !MES_BOOTSTRAP
-  if (!flags)
-    {
-      _ungetc_pos = -1;
-      _ungetc_fd = -1;
-    }
-#endif
   int r = _sys_call3 (SYS_open, (long)file_name, (int)flags, (int)mask);
+  __ungetc_init ();
+  if (r > 2)
+    __ungetc_buf[r] = -1;
   return r;
 }
 
index 7c49ba98ef2d1954482ead83658ddb98d3e28db4..d57b58cc526b1fd621dfe8c02c85faddb5933c92 100644 (file)
 int
 close (int filedes)
 {
-  if (_ungetc_fd == filedes)
-    {
-      _ungetc_pos = -1;
-      _ungetc_fd = -1;
-    }
+  if (filedes > 2)
+    __ungetc_buf[filedes] = -1;
   return _sys_call1 (SYS_close, (int)filedes);
 }
 
index bf1240a9f75a60c1bdd3a555adfec9097c59ecd1..09bca8b6417ecd378ff5f6b6afd49cae6b3eaa2c 100644 (file)
  */
 
 #include <libmes.h>
+#include <limits.h>
+#include <sys/resource.h>
 
-int _ungetc_pos = -1;
-int _ungetc_fd = -1;
-char _ungetc_buf[10];
+int __ungetc_buf[RLIMIT_NOFILE+1] = {0};
+
+void
+__ungetc_init ()
+{
+  if (__ungetc_buf[RLIMIT_NOFILE] == 0)
+    memset (__ungetc_buf, -1, (RLIMIT_NOFILE+1)*sizeof (int));
+}
 
 int
 fdgetc (int fd)
 {
+  __ungetc_init ();
+
   char c;
-  int i;
-  if (_ungetc_pos == -1)
+  int i = __ungetc_buf[fd];
+  if (i >= 0)
+    __ungetc_buf[fd] = -1;
+  else
     {
       int r = read (fd, &c, 1);
       if (r < 1)
         return -1;
       i = c;
    }
-  else
-    {
-      i = _ungetc_buf[_ungetc_pos];
-      if (_ungetc_fd != fd && i == 10)
-        {
-          // FIXME: Nyacc's ungetc exposes harmless libmec.c bug
-          // we need one unget position per FD
-          _ungetc_pos = -1;
-          _ungetc_fd = -1;
-          return fdgetc (fd);
-        }
-      else if (_ungetc_fd != fd)
-        {
-          eputs (" ***MES C LIB*** fdgetc ungetc conflict unget-fd=");
-          eputs (itoa (_ungetc_fd));
-          eputs (", fdgetc-fd=");
-          eputs (itoa (fd));
-          eputs (", c=");
-          eputs (itoa ( _ungetc_buf[_ungetc_pos]));
-          eputs ("\n");
-          exit (1);
-        }
-      i = _ungetc_buf[_ungetc_pos];
-      _ungetc_pos -= 1;
-      if (_ungetc_pos == -1)
-        _ungetc_fd = -1;
-     }
   if (i < 0)
     i += 256;
 
index ddf134b235e7f37acf166f1a0b27df98e4b04708..06d59b280a3039797011ab5c0e230d4a102a6646 100644 (file)
 int
 fdungetc (int c, int fd)
 {
+  __ungetc_init ();
   if (c == -1)
     return c;
-  if (_ungetc_pos == -1)
-    _ungetc_fd = fd;
-  else if (_ungetc_fd != fd)
+  else if (__ungetc_buf[fd] != -1)
     {
-      eputs (" ***MES LIB C*** fdungetc ungetc conflict unget-fd=");
-      eputs (itoa (_ungetc_fd));
-      eputs (", fdungetc-fd=");
+      eputs (" ***MES C LIB*** fdungetc ungetc buffer overflow fd=");
       eputs (itoa (fd));
       eputs ("\n");
       exit (1);
     }
-  _ungetc_pos++;
-  _ungetc_buf[_ungetc_pos] = c;
+  __ungetc_buf[fd] = c;
   return c;
 }
 
 int
 _fdungetc_p (int fd)
 {
-  return _ungetc_pos > -1;
+  return __ungetc_buf[fd] >= 0;
 }
index f7c2f336872da0fdfc116cedaaa24cb509931289..4574321fa9ffe53ba47f6de44335393ee785885e 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-comment-start: "//";comment-end:""-*-
  * GNU Mes --- Maxwell Equations of Software
- * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ * Copyright © 2017,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  *
  * This file is part of GNU Mes.
  *
@@ -24,7 +24,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-struct scm {
+struct scm
+{
   int type;
   int car;
   int cdr;
@@ -56,30 +57,31 @@ main ()
   oputs ("\n: ");
   oputs ("t: read 0123456789\nt: ");
   int c = get ();
-  while (i < 10) {
-    *p++ = c;
-    putchar (c);
-    c = get ();
-    i++;
-  }
+  while (i < 10)
+    {
+      *p++ = c;
+      putchar (c);
+      c = get ();
+      i++;
+    }
   oputs ("\n");
-  if (strcmp (g_chars, "0123456789")) return 1;
+  if (strcmp (g_chars, "0123456789"))
+    return 1;
 
-  oputs ("t: ungetc ('A') == getchar ()\n");
-  ungetc ('A', STDIN);
-  if (getchar () != 'A') return 1;
-  ungetc (0, STDIN);
-  //ungetc ('\1', STDIN);
-  ungetc (1, STDIN);
-  oputs ("t: ungetc ();ungetc ();getchar ();getchar ()\n");
-  if (getchar () != 1) return 1;
-  //if (getchar () != '\0') return 1;
-  if (getchar () != 0) return 1;
+  oputs ("t: fdungetc ('A') == getchar ()\n");
+  fdungetc ('A', STDIN);
+  if (getchar () != 'A')
+    return 2;
+  oputs ("t: fdungetc (0)\n");
+  fdungetc (0, STDIN);
+  if (getchar () != 0)
+    return 3;
 
   oputs ("t: i == 'm'\n");
   char m = 0x1122336d;
   i = m;
-  if (i != 'm') return 1;
+  if (i != 'm')
+    return 4;
 
   return 0;
 }