diff --git a/libio/Makefile b/libio/Makefile
index 3e08ed0eeb..a2e1c09e1c 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -64,7 +64,8 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
 	bug-memstream1 bug-wmemstream1 \
 	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
 	tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
-	tst-ftell-append tst-fputws tst-bz22415
+	tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
+
 ifeq (yes,$(build-shared))
 # Add test-fopenloc only if shared library is enabled since it depends on
 # shared localedata objects.
diff --git a/libio/fileops.c b/libio/fileops.c
index 5fd8a9647f..9c7e2bc7a2 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -469,11 +469,10 @@ int
 _IO_new_file_underflow (_IO_FILE *fp)
 {
   _IO_ssize_t count;
-#if 0
-  /* SysV does not make this test; take it out for compatibility */
+
+  /* C99 requires EOF to be "sticky".  */
   if (fp->_flags & _IO_EOF_SEEN)
     return (EOF);
-#endif
 
   if (fp->_flags & _IO_NO_READS)
     {
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index f00f6cb979..637fea38db 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -294,11 +294,10 @@ attribute_compat_text_section
 _IO_old_file_underflow (_IO_FILE *fp)
 {
   _IO_ssize_t count;
-#if 0
-  /* SysV does not make this test; take it out for compatibility */
+
+  /* C99 requires EOF to be "sticky".  */
   if (fp->_flags & _IO_EOF_SEEN)
     return (EOF);
-#endif
 
   if (fp->_flags & _IO_NO_READS)
     {
diff --git a/libio/tst-fgetc-after-eof.c b/libio/tst-fgetc-after-eof.c
new file mode 100644
index 0000000000..8487765d9d
--- /dev/null
+++ b/libio/tst-fgetc-after-eof.c
@@ -0,0 +1,135 @@
+/* Bug 1190: EOF conditions are supposed to be sticky.
+   Copyright (C) 2018 Free Software Foundation.
+   Copying and distribution of this file, with or without modification,
+   are permitted in any medium without royalty provided the copyright
+   notice and this notice are preserved. This file is offered as-is,
+   without any warranty.  */
+
+/* ISO C1999 specification of fgetc:
+
+       #include <stdio.h>
+       int fgetc (FILE *stream);
+
+   Description
+
+     If the end-of-file indicator for the input stream pointed to by
+     stream is not set and a next character is present, the fgetc
+     function obtains that character as an unsigned char converted to
+     an int and advances the associated file position indicator for
+     the stream (if defined).
+
+   Returns
+
+     If the end-of-file indicator for the stream is set, or if the
+     stream is at end-of-file, the end-of-file indicator for the
+     stream is set and the fgetc function returns EOF. Otherwise, the
+     fgetc function returns the next character from the input stream
+     pointed to by stream. If a read error occurs, the error indicator
+     for the stream is set and the fgetc function returns EOF.
+
+   The requirement to return EOF "if the end-of-file indicator for the
+   stream is set" was new in C99; the language in the 1989 edition of
+   the standard was ambiguous.  Historically, BSD-derived Unix always
+   had the C99 behavior, whereas in System V fgetc would attempt to
+   call read() again before returning EOF again.  Prior to version 2.28,
+   glibc followed the System V behavior even though this does not
+   comply with C99.
+
+   See
+   <https://sourceware.org/bugzilla/show_bug.cgi?id=1190>,
+   <https://sourceware.org/bugzilla/show_bug.cgi?id=19476>,
+   and the thread at
+   <https://sourceware.org/ml/libc-alpha/2012-09/msg00343.html>
+   for more detail.  */
+
+#include <stdio.h>
+
+#include <support/temp_file.h>
+
+int
+do_test (void)
+{
+  /* Create a scratch file, then open it by name a second time,
+     so that at the operating system level we have two independent
+     seek pointers.  */
+  char *scratch_fname;
+  int wfd = create_temp_file ("tst-fgetc-after-eof.", &scratch_fname);
+  if (wfd == -1)
+    {
+      perror ("create_temp_file");
+      return 1;
+    }
+
+  FILE *fout = fdopen (wfd, "w+");
+  if (!fout)
+    {
+      perror ("fdopen");
+      return 1;
+    }
+
+  if (fputs ("abc\n", fout) == EOF
+      || fflush (fout) || ferror (fout))
+    {
+      perror ("write error (initial)");
+      return 1;
+    }
+
+  FILE *fin = fopen (scratch_fname, "r+");
+  if (!fin)
+    {
+      perror (scratch_fname);
+      return 1;
+    }
+
+  /* Reach EOF.  */
+  while (fgetc (fin) != EOF)
+    ;
+  if (ferror (fin))
+    {
+      perror ("read error");
+      return 1;
+    }
+
+  /* Enlarge the file using the write stream.  */
+  if (fputs ("d\n", fout) == EOF
+      || fflush (fout) || ferror (fout))
+    {
+      perror ("write error (enlarging)");
+      return 1;
+    }
+
+  /* feof (fin) should still be true at this point.  */
+  if (!feof (fin))
+    {
+      fputs ("FAIL: input stream not at EOF after enlarging", stderr);
+      return 1;
+    }
+
+  /* And consistent with that, another fgetc should return EOF.  */
+  int c = fgetc (fin);
+  if (c != EOF)
+    {
+      fprintf (stderr, "FAIL: fgetc returned '%c', not EOF\n", c);
+      return 1;
+    }
+
+  /* However, after calling clearerr(), we should be able to read the
+     next characters written to the file.  */
+  clearerr (fin);
+  c = fgetc (fin);
+  if (c != 'd')
+    {
+      if (c == EOF)
+        fprintf (stderr, "FAIL: fgetc after clearerr returned EOF, not 'd'\n");
+      else
+        fprintf (stderr,
+                 "FAIL: fgetc after clearerr returned '%c', not 'd'\n", c);
+      return 1;
+    }
+
+  fclose (fin);
+  fclose (fout);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 2488821d54..20ebc885e6 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -116,6 +116,10 @@ _IO_wfile_underflow (_IO_FILE *fp)
   enum __codecvt_result status;
   _IO_ssize_t count;
 
+  /* C99 requires EOF to be "sticky".  */
+  if (fp->_flags & _IO_EOF_SEEN)
+    return (EOF);
+
   if (__glibc_unlikely (fp->_flags & _IO_NO_READS))
     {
       fp->_flags |= _IO_ERR_SEEN;
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 3ee91d2e1a..63a6fbab58 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -50,7 +50,7 @@ strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
 	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
 	 tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
-	 tst-wcstod-round test-char-types \
+	 tst-wcstod-round test-char-types tst-fgetwc-after-eof \
 	 $(addprefix test-,$(strop-tests))
 
 include ../Rules
diff --git a/wcsmbs/tst-fgetwc-after-eof.c b/wcsmbs/tst-fgetwc-after-eof.c
new file mode 100644
index 0000000000..d0feeaa916
--- /dev/null
+++ b/wcsmbs/tst-fgetwc-after-eof.c
@@ -0,0 +1,141 @@
+/* Bug 1190: EOF conditions are supposed to be sticky.
+   Copyright (C) 2018 Free Software Foundation.
+   Copying and distribution of this file, with or without modification,
+   are permitted in any medium without royalty provided the copyright
+   notice and this notice are preserved. This file is offered as-is,
+   without any warranty.  */
+
+/* ISO C1999 specification of fgetwc:
+
+       #include <stdio.h>
+       #include <wchar.h>
+       wint_t fgetwc (FILE *stream);
+
+   Description
+
+     If the end-of-file indicator for the input stream pointed to by
+     stream is not set and a next wide character is present, the
+     fgetwc function obtains that wide character as a wchar_t
+     converted to a wint_t and advances the associated file position
+     indicator for the stream (if defined).
+
+  Returns
+
+     If the end-of-file indicator for the stream is set, or if the
+     stream is at end-of-file, the end- of-file indicator for the
+     stream is set and the fgetwc function returns WEOF. Otherwise,
+     the fgetwc function returns the next wide character from the
+     input stream pointed to by stream. If a read error occurs, the
+     error indicator for the stream is set and the fgetwc function
+     returns WEOF. If an encoding error occurs (including too few
+     bytes), the value of the macro EILSEQ is stored in errno and the
+     fgetwc function returns WEOF.
+
+   The requirement to return WEOF "if the end-of-file indicator for the
+   stream is set" was new in C99; the language in the 1995 edition of
+   the standard was ambiguous.  Historically, BSD-derived Unix always
+   had the C99 behavior, whereas in System V fgetc would attempt to
+   call read() again before returning EOF again.  Prior to version 2.28,
+   glibc followed the System V behavior even though this does not
+   comply with C99.
+
+   See
+   <https://sourceware.org/bugzilla/show_bug.cgi?id=1190>,
+   <https://sourceware.org/bugzilla/show_bug.cgi?id=19476>,
+   and the thread at
+   <https://sourceware.org/ml/libc-alpha/2012-09/msg00343.html>
+   for more detail.  */
+
+#include <stdio.h>
+#include <wchar.h>
+
+#include <support/temp_file.h>
+
+int
+do_test (void)
+{
+  /* Create a scratch file, then open it by name a second time,
+     so that at the operating system level we have two independent
+     seek pointers.  */
+  char *scratch_fname;
+  int wfd = create_temp_file ("tst-fgetc-after-eof.", &scratch_fname);
+  if (wfd == -1)
+    {
+      perror ("create_temp_file");
+      return 1;
+    }
+
+  FILE *fout = fdopen (wfd, "w+");
+  if (!fout)
+    {
+      perror ("fdopen");
+      return 1;
+    }
+
+  if (fputws (L"abc\n", fout) == WEOF
+      || fflush (fout) || ferror (fout))
+    {
+      perror ("write error (initial)");
+      return 1;
+    }
+
+  FILE *fin = fopen (scratch_fname, "r+");
+  if (!fin)
+    {
+      perror (scratch_fname);
+      return 1;
+    }
+
+  /* Reach EOF.  */
+  while (fgetwc (fin) != WEOF)
+    ;
+  if (ferror (fin))
+    {
+      perror ("read error");
+      return 1;
+    }
+
+  /* Enlarge the file using the write stream.  */
+  if (fputws (L"d\n", fout) == WEOF
+      || fflush (fout) || ferror (fout))
+    {
+      perror ("write error (enlarging)");
+      return 1;
+    }
+
+  /* feof (fin) should still be true at this point.  */
+  if (!feof (fin))
+    {
+      fputs ("FAIL: input stream not at EOF after enlarging", stderr);
+      return 1;
+    }
+
+  /* And consistent with that, another fgetwc should return WEOF.  */
+  wint_t c = fgetwc (fin);
+  if (c != WEOF)
+    {
+      fprintf (stderr, "FAIL: fgetc returned L'%lc', not WEOF\n", c);
+      return 1;
+    }
+
+  /* However, after calling clearerr(), we should be able to read the
+     next characters written to the file.  */
+  clearerr (fin);
+  c = fgetwc (fin);
+  if (c != L'd')
+    {
+      if (c == EOF)
+        fprintf (stderr,
+                 "FAIL: fgetwc after clearerr returned EOF, not L'd'\n");
+      else
+        fprintf (stderr,
+                 "FAIL: fgetc after clearerr returned L'%lc', not L'd'\n", c);
+      return 1;
+    }
+
+  fclose (fin);
+  fclose (fout);
+  return 0;
+}
+
+#include <support/test-driver.c>
