1 /* Test of perror.
2    To be used only for testing glibc.  */
3 
4 #include <errno.h>
5 #include <error.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <wchar.h>
11 
12 
13 #define MB_EXP \
14   "null mode test 1: Invalid or incomplete multibyte or wide character\n" \
15   "multibyte string\n" \
16   "<0 mode test: Invalid argument\n"
17 #define MB_EXP_LEN (sizeof (MB_EXP) - 1)
18 
19 #define WC_EXP \
20   "null mode test 2: Invalid or incomplete multibyte or wide character\n" \
21   "wide string\n" \
22   ">0 mode test: Invalid argument\n"
23 #define WC_EXP_LEN (sizeof (WC_EXP) - 1)
24 
25 
26 static int
do_test(void)27 do_test (void)
28 {
29   int fd;
30   char fname[] = "/tmp/tst-perror.XXXXXX";
31   int result = 0;
32   char buf[200];
33   ssize_t n;
34 
35   fd = mkstemp (fname);
36   if (fd == -1)
37     error (EXIT_FAILURE, errno, "cannot create temporary file");
38 
39   /* Make sure the file gets removed.  */
40   unlink (fname);
41 
42   fclose (stderr);
43 
44   if (dup2 (fd, 2) == -1)
45     {
46       printf ("cannot create file descriptor 2: %m\n");
47       exit (EXIT_FAILURE);
48     }
49 
50   stderr = fdopen (2, "w");
51   if (stderr == NULL)
52     {
53       printf ("fdopen failed: %m\n");
54       exit (EXIT_FAILURE);
55     }
56 
57   if (fwide (stderr, 0) != 0)
58     {
59       printf ("stderr not initially in mode 0\n");
60       exit (EXIT_FAILURE);
61     }
62 
63   errno = EILSEQ;
64   perror ("null mode test 1");
65 
66   if (fwide (stderr, 0) != 0)
67     {
68       puts ("perror changed the mode from 0");
69       result = 1;
70     }
71 
72   fputs ("multibyte string\n", stderr);
73 
74   if (fwide (stderr, 0) >= 0)
75     {
76       puts ("fputs didn't set orientation to narrow");
77       result = 1;
78     }
79 
80   errno = EINVAL;
81   perror ("<0 mode test");
82 
83   fclose (stderr);
84 
85   lseek (fd, 0, SEEK_SET);
86   n = read (fd, buf, sizeof (buf));
87   if (n != MB_EXP_LEN || memcmp (buf, MB_EXP, MB_EXP_LEN) != 0)
88     {
89       printf ("multibyte test failed.  Expected:\n%s\nGot:\n%.*s\n",
90 	      MB_EXP, (int) n, buf);
91       result = 1;
92     }
93   else
94     puts ("multibyte test succeeded");
95 
96   lseek (fd, 0, SEEK_SET);
97   ftruncate (fd, 0);
98 
99   if (dup2 (fd, 2) == -1)
100     {
101       printf ("cannot create file descriptor 2: %m\n");
102       exit (EXIT_FAILURE);
103     }
104   stderr = fdopen (2, "w");
105   if (stderr == NULL)
106     {
107       printf ("fdopen failed: %m\n");
108       exit (EXIT_FAILURE);
109     }
110 
111   if (fwide (stderr, 0) != 0)
112     {
113       printf ("stderr not initially in mode 0\n");
114       exit (EXIT_FAILURE);
115     }
116 
117   errno = EILSEQ;
118   perror ("null mode test 2");
119 
120   if (fwide (stderr, 0) != 0)
121     {
122       puts ("perror changed the mode from 0");
123       result = 1;
124     }
125 
126   fputws (L"wide string\n", stderr);
127 
128   if (fwide (stderr, 0) <= 0)
129     {
130       puts ("fputws didn't set orientation to wide");
131       result = 1;
132     }
133 
134   errno = EINVAL;
135   perror (">0 mode test");
136 
137   fclose (stderr);
138 
139   lseek (fd, 0, SEEK_SET);
140   n = read (fd, buf, sizeof (buf));
141   if (n != WC_EXP_LEN || memcmp (buf, WC_EXP, WC_EXP_LEN) != 0)
142     {
143       printf ("wide test failed.  Expected:\n%s\nGot:\n%.*s\n",
144 	      WC_EXP, (int) n, buf);
145       result = 1;
146     }
147   else
148     puts ("wide test succeeded");
149 
150   close (fd);
151 
152   return result;
153 }
154 
155 #define TEST_FUNCTION do_test ()
156 #include "../test-skeleton.c"
157