diff --git a/include/sys/resource.h b/include/sys/resource.h index 276405ba..ebf5809a 100644 --- a/include/sys/resource.h +++ b/include/sys/resource.h @@ -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); diff --git a/lib/libc+tcc.c b/lib/libc+tcc.c index 177da71b..a788dc91 100644 --- a/lib/libc+tcc.c +++ b/lib/libc+tcc.c @@ -93,7 +93,6 @@ int errno; #include #include #include -#include #include #include #include diff --git a/lib/libc.c b/lib/libc.c index 2c886137..b37fc9bd 100644 --- a/lib/libc.c +++ b/lib/libc.c @@ -74,6 +74,7 @@ __mes_debug () #include #include +#include #include #include #include diff --git a/lib/linux/libc.c b/lib/linux/libc.c index 6d990c27..7f6a1fc7 100644 --- a/lib/linux/libc.c +++ b/lib/linux/libc.c @@ -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; } diff --git a/lib/linux/tcc.c b/lib/linux/tcc.c index 7c49ba98..d57b58cc 100644 --- a/lib/linux/tcc.c +++ b/lib/linux/tcc.c @@ -23,11 +23,8 @@ 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); } diff --git a/lib/mes/fdgetc.c b/lib/mes/fdgetc.c index bf1240a9..09bca8b6 100644 --- a/lib/mes/fdgetc.c +++ b/lib/mes/fdgetc.c @@ -19,50 +19,34 @@ */ #include +#include +#include -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; diff --git a/lib/mes/fdungetc.c b/lib/mes/fdungetc.c index ddf134b2..06d59b28 100644 --- a/lib/mes/fdungetc.c +++ b/lib/mes/fdungetc.c @@ -23,26 +23,22 @@ 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; } diff --git a/scaffold/tests/65-read.c b/scaffold/tests/65-read.c index f7c2f336..4574321f 100644 --- a/scaffold/tests/65-read.c +++ b/scaffold/tests/65-read.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2017 Jan (janneke) Nieuwenhuizen + * Copyright © 2017,2019 Jan (janneke) Nieuwenhuizen * * This file is part of GNU Mes. * @@ -24,7 +24,8 @@ #include #include -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; }