mescc: Mes C Library: Fix ungetc.

* 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.
This commit is contained in:
Jan Nieuwenhuizen 2019-03-16 11:55:00 +01:00
parent 48a0bf181d
commit ff32cd03cc
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
8 changed files with 51 additions and 74 deletions

View file

@ -50,6 +50,8 @@ struct rusage
#define RUSAGE_SELF 0 #define RUSAGE_SELF 0
#define RUSAGE_CHILDREN -1 #define RUSAGE_CHILDREN -1
#define RLIMIT_NOFILE 1024
#define OPEN_MAX RLIMIT_NOFILE
int getrusage (int processes, struct rusage *rusage); int getrusage (int processes, struct rusage *rusage);

View file

@ -93,7 +93,6 @@ int errno;
#include <stdlib/strtoull.c> #include <stdlib/strtoull.c>
#include <string/memmem.c> #include <string/memmem.c>
#include <string/memmove.c> #include <string/memmove.c>
#include <string/memset.c>
#include <string/strcat.c> #include <string/strcat.c>
#include <string/strchr.c> #include <string/strchr.c>
#include <string/strlwr.c> #include <string/strlwr.c>

View file

@ -74,6 +74,7 @@ __mes_debug ()
#include <string/memchr.c> #include <string/memchr.c>
#include <string/memcmp.c> #include <string/memcmp.c>
#include <string/memset.c>
#include <string/strcmp.c> #include <string/strcmp.c>
#include <string/strcpy.c> #include <string/strcpy.c>
#include <string/strncmp.c> #include <string/strncmp.c>

View file

@ -69,14 +69,10 @@ read (int filedes, void *buffer, size_t size)
int int
_open3 (char const *file_name, int flags, int mask) _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); int r = _sys_call3 (SYS_open, (long)file_name, (int)flags, (int)mask);
__ungetc_init ();
if (r > 2)
__ungetc_buf[r] = -1;
return r; return r;
} }

View file

@ -23,11 +23,8 @@
int int
close (int filedes) close (int filedes)
{ {
if (_ungetc_fd == filedes) if (filedes > 2)
{ __ungetc_buf[filedes] = -1;
_ungetc_pos = -1;
_ungetc_fd = -1;
}
return _sys_call1 (SYS_close, (int)filedes); return _sys_call1 (SYS_close, (int)filedes);
} }

View file

@ -19,50 +19,34 @@
*/ */
#include <libmes.h> #include <libmes.h>
#include <limits.h>
#include <sys/resource.h>
int _ungetc_pos = -1; int __ungetc_buf[RLIMIT_NOFILE+1] = {0};
int _ungetc_fd = -1;
char _ungetc_buf[10]; void
__ungetc_init ()
{
if (__ungetc_buf[RLIMIT_NOFILE] == 0)
memset (__ungetc_buf, -1, (RLIMIT_NOFILE+1)*sizeof (int));
}
int int
fdgetc (int fd) fdgetc (int fd)
{ {
__ungetc_init ();
char c; char c;
int i; int i = __ungetc_buf[fd];
if (_ungetc_pos == -1) if (i >= 0)
__ungetc_buf[fd] = -1;
else
{ {
int r = read (fd, &c, 1); int r = read (fd, &c, 1);
if (r < 1) if (r < 1)
return -1; return -1;
i = c; 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) if (i < 0)
i += 256; i += 256;

View file

@ -23,26 +23,22 @@
int int
fdungetc (int c, int fd) fdungetc (int c, int fd)
{ {
__ungetc_init ();
if (c == -1) if (c == -1)
return c; return c;
if (_ungetc_pos == -1) else if (__ungetc_buf[fd] != -1)
_ungetc_fd = fd;
else if (_ungetc_fd != fd)
{ {
eputs (" ***MES LIB C*** fdungetc ungetc conflict unget-fd="); eputs (" ***MES C LIB*** fdungetc ungetc buffer overflow fd=");
eputs (itoa (_ungetc_fd));
eputs (", fdungetc-fd=");
eputs (itoa (fd)); eputs (itoa (fd));
eputs ("\n"); eputs ("\n");
exit (1); exit (1);
} }
_ungetc_pos++; __ungetc_buf[fd] = c;
_ungetc_buf[_ungetc_pos] = c;
return c; return c;
} }
int int
_fdungetc_p (int fd) _fdungetc_p (int fd)
{ {
return _ungetc_pos > -1; return __ungetc_buf[fd] >= 0;
} }

View file

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*- /* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software * 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. * This file is part of GNU Mes.
* *
@ -24,7 +24,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
struct scm { struct scm
{
int type; int type;
int car; int car;
int cdr; int cdr;
@ -56,30 +57,31 @@ main ()
oputs ("\n: "); oputs ("\n: ");
oputs ("t: read 0123456789\nt: "); oputs ("t: read 0123456789\nt: ");
int c = get (); int c = get ();
while (i < 10) { while (i < 10)
*p++ = c; {
putchar (c); *p++ = c;
c = get (); putchar (c);
i++; c = get ();
} i++;
}
oputs ("\n"); oputs ("\n");
if (strcmp (g_chars, "0123456789")) return 1; if (strcmp (g_chars, "0123456789"))
return 1;
oputs ("t: ungetc ('A') == getchar ()\n"); oputs ("t: fdungetc ('A') == getchar ()\n");
ungetc ('A', STDIN); fdungetc ('A', STDIN);
if (getchar () != 'A') return 1; if (getchar () != 'A')
ungetc (0, STDIN); return 2;
//ungetc ('\1', STDIN); oputs ("t: fdungetc (0)\n");
ungetc (1, STDIN); fdungetc (0, STDIN);
oputs ("t: ungetc ();ungetc ();getchar ();getchar ()\n"); if (getchar () != 0)
if (getchar () != 1) return 1; return 3;
//if (getchar () != '\0') return 1;
if (getchar () != 0) return 1;
oputs ("t: i == 'm'\n"); oputs ("t: i == 'm'\n");
char m = 0x1122336d; char m = 0x1122336d;
i = m; i = m;
if (i != 'm') return 1; if (i != 'm')
return 4;
return 0; return 0;
} }