mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-28 23:34:53 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			520 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			520 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Test freopen.
 | |
|    Copyright (C) 2024-2025 Free Software Foundation, Inc.
 | |
|    This file is part of the GNU C Library.
 | |
| 
 | |
|    The GNU C Library is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU Lesser General Public
 | |
|    License as published by the Free Software Foundation; either
 | |
|    version 2.1 of the License, or (at your option) any later version.
 | |
| 
 | |
|    The GNU C Library is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|    Lesser General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU Lesser General Public
 | |
|    License along with the GNU C Library; if not, see
 | |
|    <https://www.gnu.org/licenses/>.  */
 | |
| 
 | |
| #include <errno.h>
 | |
| #include <fcntl.h>
 | |
| #include <mcheck.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <wchar.h>
 | |
| 
 | |
| #include <support/check.h>
 | |
| #include <support/descriptors.h>
 | |
| #include <support/file_contents.h>
 | |
| #include <support/support.h>
 | |
| #include <support/temp_file.h>
 | |
| #include <support/test-driver.h>
 | |
| #include <support/xstdio.h>
 | |
| 
 | |
| #define START_TEST(DESC)			\
 | |
|   do						\
 | |
|     {						\
 | |
|       fds = support_descriptors_list ();	\
 | |
|       verbose_printf (DESC);			\
 | |
|     }						\
 | |
|   while (0)
 | |
| 
 | |
| #define END_TEST				\
 | |
|   do						\
 | |
|     {						\
 | |
|       support_descriptors_check (fds);		\
 | |
|       support_descriptors_free (fds);		\
 | |
|     }						\
 | |
|   while (0)
 | |
| 
 | |
| int
 | |
| do_test (void)
 | |
| {
 | |
|   mtrace ();
 | |
|   struct support_descriptors *fds;
 | |
|   char *temp_dir = support_create_temp_directory ("tst-freopen2");
 | |
|   char *file1 = xasprintf ("%s/file1", temp_dir);
 | |
|   support_write_file_string (file1, "file1");
 | |
|   add_temp_file (file1);
 | |
|   char *file2 = xasprintf ("%s/file2", temp_dir);
 | |
|   support_write_file_string (file2, "file2");
 | |
|   add_temp_file (file2);
 | |
|   char *file3 = xasprintf ("%s/file3", temp_dir);
 | |
|   char *file4 = xasprintf ("%s/file4", temp_dir);
 | |
|   char *file1a = xasprintf ("%s/file1a", temp_dir);
 | |
|   FILE *fp;
 | |
|   int ret;
 | |
|   wint_t wc;
 | |
| 
 | |
|   /* Test each pair of old and new modes from r w a.  */
 | |
| 
 | |
|   START_TEST ("Testing r -> r\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "file2");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing r -> w\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("File2new", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file1, "file1");
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "File2new");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing r -> a\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = FREOPEN (file2, "a", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("3", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "File2new3");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing w -> r\n");
 | |
|   fp = xfopen (file1, "w");
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "File2new3");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing w -> w\n");
 | |
|   fp = xfopen (file1, "w");
 | |
|   fp = FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("next", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file1, "");
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "next");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing w -> a\n");
 | |
|   fp = xfopen (file1, "w");
 | |
|   fp = FREOPEN (file2, "a", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("4", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "next4");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing a -> r\n");
 | |
|   fp = xfopen (file1, "a");
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "next4");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing a -> w\n");
 | |
|   fp = xfopen (file1, "a");
 | |
|   fp = FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("another", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing a -> a\n");
 | |
|   fp = xfopen (file1, "a");
 | |
|   fp = FREOPEN (file2, "a", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("5", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another5");
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test for file originally opened with fopen64.  */
 | |
|   START_TEST ("Testing fopen64 a -> a\n");
 | |
|   fp = fopen64 (file1, "a");
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   fp = FREOPEN (file2, "a", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("64", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another564");
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test calling freopen more than once on the same FILE *.  */
 | |
| 
 | |
|   START_TEST ("Testing r -> w -> r\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("freopen-twice", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "freopen-twice");
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "freopen-twice");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing r -> w -> r (exactly one freopen64)\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = OTHER_FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("freopen-twice64", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "freopen-twice64");
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test changing to/from b (binary, no-op).  */
 | |
| 
 | |
|   START_TEST ("Testing rb -> r\n");
 | |
|   fp = xfopen (file1, "rb");
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing r -> rb\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = FREOPEN (file2, "rb", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test changing to/from + (read-and-write).  */
 | |
| 
 | |
|   START_TEST ("Testing r -> w+\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = FREOPEN (file2, "w+", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("latest", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   ret = fseek (fp, 0, SEEK_SET);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "latest");
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "latest");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing w -> a+\n");
 | |
|   fp = xfopen (file1, "w");
 | |
|   fp = FREOPEN (file2, "a+", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("suffix", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   ret = fseek (fp, 0, SEEK_SET);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "latestsuffix");
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "latestsuffix");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing a -> r+\n");
 | |
|   fp = xfopen (file1, "a");
 | |
|   fp = FREOPEN (file2, "r+", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "latestsuffix");
 | |
|   ret = fseek (fp, 0, SEEK_SET);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   ret = fputs ("new", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "newestsuffix");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing r+ -> w\n");
 | |
|   fp = xfopen (file1, "r+");
 | |
|   fp = FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("plusto", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   ret = fseek (fp, 0, SEEK_SET);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   errno = 0;
 | |
|   TEST_COMPARE (fgetc (fp), EOF);
 | |
|   TEST_COMPARE (errno, EBADF);
 | |
|   clearerr (fp);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plusto");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing w+ -> a\n");
 | |
|   fp = xfopen (file1, "w+");
 | |
|   fp = FREOPEN (file2, "a", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("more", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   ret = fseek (fp, 0, SEEK_SET);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   errno = 0;
 | |
|   TEST_COMPARE (fgetc (fp), EOF);
 | |
|   TEST_COMPARE (errno, EBADF);
 | |
|   clearerr (fp);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plustomore");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing a+ -> r\n");
 | |
|   fp = xfopen (file1, "a+");
 | |
|   fp = FREOPEN (file2, "rr", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "plustomore");
 | |
|   ret = fputs ("2", fp);
 | |
|   TEST_COMPARE (ret, EOF);
 | |
|   clearerr (fp);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plustomore");
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test changing to/from e (FD_CLOEXEC).  */
 | |
| 
 | |
|   START_TEST ("Testing re -> r\n");
 | |
|   fp = xfopen (file1, "re");
 | |
|   ret = fcntl (fileno (fp), F_GETFD);
 | |
|   TEST_VERIFY (ret != -1);
 | |
|   TEST_COMPARE (ret & FD_CLOEXEC, FD_CLOEXEC);
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fcntl (fileno (fp), F_GETFD);
 | |
|   TEST_VERIFY (ret != -1);
 | |
|   TEST_COMPARE (ret & FD_CLOEXEC, 0);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "plustomore");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing r -> re\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   ret = fcntl (fileno (fp), F_GETFD);
 | |
|   TEST_VERIFY (ret != -1);
 | |
|   TEST_COMPARE (ret & FD_CLOEXEC, 0);
 | |
|   fp = FREOPEN (file2, "re", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fcntl (fileno (fp), F_GETFD);
 | |
|   TEST_VERIFY (ret != -1);
 | |
|   TEST_COMPARE (ret & FD_CLOEXEC, FD_CLOEXEC);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "plustomore");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test changing to/from m (mmap) (a no-op as far as testing
 | |
|      semantics is concerned).  */
 | |
| 
 | |
|   START_TEST ("Testing rm -> r\n");
 | |
|   fp = xfopen (file1, "rm");
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "plustomore");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing r -> rm\n");
 | |
|   fp = xfopen (file1, "r");
 | |
|   fp = FREOPEN (file2, "rm", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "plustomore");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test changing to/from x (O_EXCL).  */
 | |
| 
 | |
|   START_TEST ("Testing wx -> w\n");
 | |
|   fp = xfopen (file3, "wx");
 | |
|   add_temp_file (file3);
 | |
|   fp = FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   ret = fputs ("wxtow", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "wxtow");
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("Testing w -> wx (file does not exist)\n");
 | |
|   fp = xfopen (file1, "w");
 | |
|   fp = FREOPEN (file4, "wx", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   add_temp_file (file4);
 | |
|   ret = fputs ("wtowx", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   xfclose (fp);
 | |
|   TEST_OPEN_AND_COMPARE_FILE_STRING (file4, "wtowx");
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test with ,ccs=CHARSET.  */
 | |
| 
 | |
|   START_TEST ("testing w,ccs=utf-8 -> r\n");
 | |
|   fp = xfopen (file1, "w,ccs=utf-8");
 | |
|   ret = fputws (L"\xc0\xc1", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "wxtow");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("testing w,ccs=iso-8859-1 -> r,ccs=utf-8\n");
 | |
|   fp = xfopen (file2, "w,ccs=iso-8859-1");
 | |
|   ret = fputws (L"\xc0\xc1", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   fp = FREOPEN (file1, "r,ccs=utf-8", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   wc = fgetwc (fp);
 | |
|   TEST_COMPARE (wc, (wint_t) 0xc0);
 | |
|   wc = fgetwc (fp);
 | |
|   TEST_COMPARE (wc, (wint_t) 0xc1);
 | |
|   wc = fgetwc (fp);
 | |
|   TEST_COMPARE (wc, WEOF);
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("testing r,ccs=utf-8 -> r\n");
 | |
|   fp = xfopen (file1, "r,ccs=utf-8");
 | |
|   fp = FREOPEN (file1, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "\u00c0\u00c1");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test that errors closing the old file are ignored.  */
 | |
| 
 | |
|   START_TEST ("testing errors closing old file ignored\n");
 | |
|   fp = xfopen ("/dev/full", "w");
 | |
|   fputc ('x', fp);
 | |
|   fp = FREOPEN (file1, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "\u00c0\u00c1");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test that error / EOF state from the old file are cleared.  */
 | |
| 
 | |
|   START_TEST ("testing error state from old file cleared\n");
 | |
|   fp = xfopen ("/dev/full", "w");
 | |
|   fputc ('x', fp);
 | |
|   fflush (fp);
 | |
|   TEST_VERIFY (ferror (fp));
 | |
|   TEST_VERIFY (!feof (fp));
 | |
|   fp = FREOPEN (file2, "w", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_VERIFY (!ferror (fp));
 | |
|   TEST_VERIFY (!feof (fp));
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   START_TEST ("testing EOF state from old file cleared\n");
 | |
|   fp = xfopen ("/dev/null", "r");
 | |
|   fgetc (fp);
 | |
|   TEST_VERIFY (!ferror (fp));
 | |
|   TEST_VERIFY (feof (fp));
 | |
|   fp = FREOPEN (file2, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_VERIFY (!ferror (fp));
 | |
|   TEST_VERIFY (!feof (fp));
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test freopen with NULL, same mode (should flush content and reset
 | |
|      file offset).  */
 | |
| 
 | |
|   START_TEST ("testing freopen with NULL, same mode\n");
 | |
|   fp = xfopen (file1, "r+");
 | |
|   ret = fputs ("same mode", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   fp = FREOPEN (NULL, "r+", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "same mode");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test freopen with NULL, different mode.  */
 | |
| 
 | |
|   START_TEST ("testing freopen with NULL, different mode\n");
 | |
|   fp = xfopen (file1, "w");
 | |
|   ret = fputs ("different mode", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   fp = FREOPEN (NULL, "r", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "different mode");
 | |
|   xfclose (fp);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test freopen with NULL, renamed file.  This verifies that
 | |
|      reopening succeeds (and resets the file position indicator to
 | |
|      start of file) even when the original path could no longer be
 | |
|      opened.  */
 | |
| 
 | |
|   START_TEST ("testing freopen with NULL, renamed file\n");
 | |
|   fp = xfopen (file1, "r+");
 | |
|   ret = fputs ("file has been renamed", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   ret = rename (file1, file1a);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   fp = FREOPEN (NULL, "r+", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "file has been renamed");
 | |
|   xfclose (fp);
 | |
|   ret = rename (file1a, file1);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   END_TEST;
 | |
| 
 | |
|   /* Test freopen with NULL, deleted file.  This verifies that
 | |
|      reopening succeeds (and resets the file position indicator to
 | |
|      start of file) even when the original path could no longer be
 | |
|      opened.  */
 | |
| 
 | |
|   START_TEST ("testing freopen with NULL, deleted file\n");
 | |
|   fp = xfopen (file1, "r+");
 | |
|   ret = fputs ("file has now been deleted", fp);
 | |
|   TEST_VERIFY (ret >= 0);
 | |
|   ret = remove (file1);
 | |
|   TEST_COMPARE (ret, 0);
 | |
|   fp = FREOPEN (NULL, "r+", fp);
 | |
|   TEST_VERIFY_EXIT (fp != NULL);
 | |
|   TEST_COMPARE_FILE_STRING (fp, "file has now been deleted");
 | |
|   xfclose (fp);
 | |
|   /* Recreate the file so it is present when expected for temporary
 | |
|      file deletion.  */
 | |
|   support_write_file_string (file1, "file1");
 | |
|   END_TEST;
 | |
| 
 | |
|   free (temp_dir);
 | |
|   free (file1);
 | |
|   free (file2);
 | |
|   free (file3);
 | |
|   free (file4);
 | |
|   free (file1a);
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| #include <support/test-driver.c>
 |