summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/c_runtime/ungetc
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/tests/palsuite/c_runtime/ungetc')
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt20
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.c131
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt20
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test2/test2.txt1
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.c189
8 files changed, 390 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ungetc/CMakeLists.txt
new file mode 100644
index 0000000000..ef14ea5352
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test2)
+
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt
new file mode 100644
index 0000000000..bcb85d18cf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ ungetc.c
+)
+
+add_executable(paltest_ungetc_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_ungetc_test1 CoreClrPal)
+
+target_link_libraries(paltest_ungetc_test1
+ pthread
+ rt
+ m
+ CoreClrPal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/ungetc/test1/testinfo.dat
new file mode 100644
index 0000000000..b292853733
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test1/testinfo.dat
@@ -0,0 +1,12 @@
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+
+Version = 1.0
+Section = c_runtime
+Function = ungetc
+Name = test for ungetc (test 1)
+Type = DEFAULT
+EXE1 = ungetc
+Description
+= Test how ungetc handles a write-only file (should fail)
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.c b/src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.c
new file mode 100644
index 0000000000..d894f8b0b2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.c
@@ -0,0 +1,131 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+/*=====================================================================
+**
+** Source: ungetc.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the ungetc function by calling
+** the function on a write-only file.
+**
+** Dependencies:
+** fopen
+** fclose
+** fseek
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ char szFileName[] = {"test1.tmp"};
+ const char text[] =
+ {"The quick brown fox jumped over the lazy dog's back."};
+ FILE* pFile = NULL;
+ int nChar = 65; /* 'A' */
+ int nRc = 0;
+ int itemsExpected;
+ int itemsWritten;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create the file */
+ pFile = fopen(szFileName, "w");
+ if (pFile == NULL)
+ {
+ Fail("ungetc: ERROR -> fopen failed to create the file \"%s\""
+ " as write-only.\n",
+ szFileName);
+ }
+
+ /* write to the file */
+ itemsExpected = sizeof(text);
+ itemsWritten = fwrite(text, sizeof(text[0]), sizeof(text), pFile);
+ if (itemsWritten == 0)
+ {
+ Trace("ungetc: ERROR -> fwrite failed to write to the file \"%s\"\n",
+ szFileName);
+
+ if (fclose(pFile) != 0)
+ {
+ Fail("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+
+ }
+ else if (itemsWritten != itemsExpected)
+ {
+ Trace("ungetc: ERROR -> fwrite failed to write the correct number "
+ "of characters to the file \"%s\"\n",
+ szFileName);
+
+ if (fclose(pFile) != 0)
+ {
+ Fail("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ /* Close the file */
+ if (fclose(pFile) != 0)
+ {
+ Fail("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+
+ /*
+ ** open the file in write only mode and
+ ** attempt to push an unread character back on the stream
+ */
+
+
+ /* open the file write-only */
+ pFile = fopen(szFileName, "a");
+ if (pFile == NULL)
+ {
+ Fail("ungetc: ERROR -> fopen failed to open the file \"%s\""
+ " as write-only.\n",
+ szFileName);
+ }
+
+ /* move the file pointer back to the beginning of the file */
+ if (fseek(pFile, 1, SEEK_SET) != 0)
+ {
+
+ Trace("ungetc: ERROR -> fseek failed to move the file pointer to the "
+ "beginning of the file.\n");
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ /* call ungetc on a write-only file which should fail */
+ if ((nRc = ungetc(nChar, pFile)) != EOF)
+ {
+ Trace("ungetc: ERROR -> ungetc returned \"%c\" when run on "
+ "an write-only file.\n", nChar);
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ if (fclose(pFile) != 0)
+ {
+ Fail("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt
new file mode 100644
index 0000000000..e15b2befdc
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ ungetc.c
+)
+
+add_executable(paltest_ungetc_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_ungetc_test2 CoreClrPal)
+
+target_link_libraries(paltest_ungetc_test2
+ pthread
+ rt
+ m
+ CoreClrPal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test2/test2.txt b/src/pal/tests/palsuite/c_runtime/ungetc/test2/test2.txt
new file mode 100644
index 0000000000..96c906756d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test2/test2.txt
@@ -0,0 +1 @@
+foo bar \ No newline at end of file
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/ungetc/test2/testinfo.dat
new file mode 100644
index 0000000000..a8a258bf68
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test2/testinfo.dat
@@ -0,0 +1,12 @@
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+
+Version = 1.0
+Section = c_runtime
+Function = ungetc
+Name = test for ungetc (test 2)
+Type = DEFAULT
+EXE1 = ungetc
+Description
+= Push characters back onto the stream and verify
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.c b/src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.c
new file mode 100644
index 0000000000..f24a6f764e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.c
@@ -0,0 +1,189 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+/*=====================================================================
+**
+** Source: ungetc.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the ungetc function
+**
+** Dependencies:
+** fopen
+** fread
+** fclose
+** fseek
+** getc
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char szFileName[] = {"test2.txt"};
+ const char szNewString[] = {"bar bar"};
+ char szBuffer[MAX_PATH];
+ FILE* pFile = NULL;
+ int nChar = 32; /* space */
+ int i = 0;
+ int nRc = 0;
+ size_t nCount = 0;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ memset(szBuffer, 0, MAX_PATH);
+
+ /*
+ ** open the file in write only mode, populate it and
+ ** attempt to push an unread character back on the stream
+ */
+
+
+ /* open the file for read */
+ pFile = fopen(szFileName, "r");
+ if (pFile == NULL)
+ {
+ Fail("ungetc: ERROR -> fopen failed to open the file \"%s\""
+ " as read-only.n",
+ szFileName);
+ }
+
+
+ /*
+ ** Call getc to get the first char and ungetc to put
+ ** it back. getc should read it again.
+ */
+
+ /* read a character */
+ if ((nChar = getc(pFile)) == EOF)
+ {
+ Trace("ungetc: ERROR -> getc encountered an error reading.\n");
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ /* put it back */
+ if ((nRc = ungetc(nChar, pFile)) == EOF)
+ {
+ Trace("ungetc: ERROR -> ungetc failed to push '%c' back onto the"
+ " stream.\n");
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ /* read it again... hopefully */
+ if (((nChar = getc(pFile)) == EOF) || (nChar != nRc))
+ {
+ Trace("ungetc: ERROR -> getc encountered an error reading.\n");
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ /*
+ ** test multiple ungetcs by replacing "foo" in the stream with "bar"
+ */
+
+ /* move the file pointer back to the beginning of the file */
+ if (fseek(pFile, 0, SEEK_SET) != 0)
+ {
+ Trace("ungetc: ERROR -> fseek failed to move the file pointer to the "
+ "beginning of the file. GetLastError returned %ld\n",
+ GetLastError());
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ /* read a few characters */
+ for (i = 0; i < 3; i++)
+ {
+ if (getc(pFile) == EOF)
+ {
+ Trace("ungetc: ERROR -> getc encountered an error reading. "
+ "GetLastError returned %ld\n",
+ GetLastError());
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+ }
+
+ /* we just read "foo" so push "bar" back on the stream */
+ for (i = 2; i >= 0; i--)
+ {
+ if ((nRc = ungetc(szNewString[i], pFile)) == EOF)
+ {
+ Trace("ungetc: ERROR -> ungetc failed to push '%c' back onto the"
+ " stream.\n");
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+ }
+
+
+ /* read the new and improved stream - I use szNewString because it
+ is correct length */
+ nCount = fread(szBuffer, sizeof(char), strlen(szNewString), pFile);
+
+ /* did we get the right number of characters?*/
+ if (nCount != strlen(szNewString))
+ {
+ Trace("ungetc: ERROR -> fread read %d characters from the stream but"
+ " %d characters were expected\n",
+ nRc,
+ strlen(szNewString));
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ /* did we get the right string? */
+ if (strcmp(szBuffer, szNewString) != 0)
+ {
+ Trace("ungetc: ERROR -> fread returned \"%s\" but \"%s\" was "
+ "expected\n",
+ szBuffer,
+ szNewString);
+ if (fclose(pFile) != 0)
+ {
+ Trace("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+ Fail("");
+ }
+
+ if (fclose(pFile) != 0)
+ {
+ Fail("ungetc: ERROR -> fclose failed to close the file.\n");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}