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
26static int
27do_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 (template: fname);
36 if (fd == -1)
37 error (EXIT_FAILURE, errno, format: "cannot create temporary file");
38
39 /* Make sure the file gets removed. */
40 unlink (name: fname);
41
42 fclose (stderr);
43
44 if (dup2 (fd: fd, fd2: 2) == -1)
45 {
46 printf (format: "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 (format: "fdopen failed: %m\n");
54 exit (EXIT_FAILURE);
55 }
56
57 if (fwide (stderr, mode: 0) != 0)
58 {
59 printf (format: "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, mode: 0) != 0)
67 {
68 puts (s: "perror changed the mode from 0");
69 result = 1;
70 }
71
72 fputs ("multibyte string\n", stderr);
73
74 if (fwide (stderr, mode: 0) >= 0)
75 {
76 puts (s: "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: fd, offset: 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 (format: "multibyte test failed. Expected:\n%s\nGot:\n%.*s\n",
90 MB_EXP, (int) n, buf);
91 result = 1;
92 }
93 else
94 puts (s: "multibyte test succeeded");
95
96 lseek (fd: fd, offset: 0, SEEK_SET);
97 ftruncate (fd: fd, length: 0);
98
99 if (dup2 (fd: fd, fd2: 2) == -1)
100 {
101 printf (format: "cannot create file descriptor 2: %m\n");
102 exit (EXIT_FAILURE);
103 }
104 stderr = fdopen (2, "w");
105 if (stderr == NULL)
106 {
107 printf (format: "fdopen failed: %m\n");
108 exit (EXIT_FAILURE);
109 }
110
111 if (fwide (stderr, mode: 0) != 0)
112 {
113 printf (format: "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, mode: 0) != 0)
121 {
122 puts (s: "perror changed the mode from 0");
123 result = 1;
124 }
125
126 fputws (ws: L"wide string\n", stderr);
127
128 if (fwide (stderr, mode: 0) <= 0)
129 {
130 puts (s: "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: fd, offset: 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 (format: "wide test failed. Expected:\n%s\nGot:\n%.*s\n",
144 WC_EXP, (int) n, buf);
145 result = 1;
146 }
147 else
148 puts (s: "wide test succeeded");
149
150 close (fd: fd);
151
152 return result;
153}
154
155#define TEST_FUNCTION do_test ()
156#include "../test-skeleton.c"
157

source code of glibc/stdio-common/tst-perror.c