1 /* Test that assigning to stdin redirects input (bug 24153).
2    Copyright (C) 2019-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 /* Prevent getchar -> getc inline expansion.  */
20 #define __NO_INLINE__
21 #pragma GCC optimize ("O0")
22 
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <support/check.h>
28 #include <support/temp_file.h>
29 #include <support/xstdio.h>
30 #include <support/xunistd.h>
31 #include <wchar.h>
32 
33 static int
call_vscanf(const char * format,...)34 call_vscanf (const char *format, ...)
35 {
36   va_list ap;
37   va_start (ap, format);
38   int ret = vscanf (format, ap);
39   va_end (ap);
40   return ret;
41 }
42 
43 static int
call_vwscanf(const wchar_t * format,...)44 call_vwscanf (const wchar_t *format, ...)
45 {
46   va_list ap;
47   va_start (ap, format);
48   int ret = vwscanf (format, ap);
49   va_end (ap);
50   return ret;
51 }
52 
53 static void
narrow(const char * path)54 narrow (const char *path)
55 {
56   FILE *old_stdin = stdin;
57   stdin = xfopen (path, "r");
58 
59   TEST_COMPARE (getchar (), 'a');
60   TEST_COMPARE (getchar_unlocked (), 'b');
61   char ch = 1;
62   TEST_COMPARE (scanf ("%c", &ch), 1);
63   TEST_COMPARE (ch, 'c');
64   TEST_COMPARE (call_vscanf ("%c", &ch), 1);
65   TEST_COMPARE (ch, 'd');
66   char buf[8];
67   memset (buf, 'X', sizeof (buf));
68 
69   /* Legacy interface.  */
70   extern char *gets (char *);
71   TEST_VERIFY (gets (buf) == buf);
72   TEST_COMPARE_BLOB (buf, sizeof (buf), "ef\0XXXXX", sizeof (buf));
73 
74   fclose (stdin);
75   stdin = old_stdin;
76 }
77 
78 static void
wide(const char * path)79 wide (const char *path)
80 {
81   FILE *old_stdin = stdin;
82   stdin = xfopen (path, "r");
83 
84   TEST_COMPARE (getwchar (), L'a');
85   TEST_COMPARE (getwchar_unlocked (), L'b');
86   wchar_t ch = 1;
87   TEST_COMPARE (wscanf (L"%lc", &ch), 1);
88   TEST_COMPARE (ch, L'c');
89   TEST_COMPARE (call_vwscanf (L"%lc", &ch), 1);
90   TEST_COMPARE (ch, L'd');
91 
92   fclose (stdin);
93   stdin = old_stdin;
94 }
95 
96 static int
do_test(void)97 do_test (void)
98 {
99   char *path;
100   {
101     int fd = create_temp_file ("tst-bz24153-", &path);
102     TEST_VERIFY_EXIT (fd >= 0);
103     xwrite (fd, "abcdef", strlen ("abcdef"));
104     xclose (fd);
105   }
106 
107   narrow (path);
108   wide (path);
109 
110   free (path);
111   return 0;
112 }
113 
114 #include <support/test-driver.c>
115