1 /* $Id: qio-t.c 10457 2020-12-19 06:10:49Z eagle $ */
2 /* Test suite for the Quick I/O library */
3 
4 #define LIBTEST_NEW_FORMAT 1
5 
6 #include "config.h"
7 #include "clibrary.h"
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <sys/stat.h>
11 
12 #include "inn/qio.h"
13 #include "inn/libinn.h"
14 #include "tap/basic.h"
15 
16 
17 static void
output(int fd,const void * data,size_t size)18 output(int fd, const void *data, size_t size)
19 {
20     if (xwrite(fd, data, size) < 0)
21         sysbail("Can't write to .testout");
22 }
23 
24 
25 int
main(void)26 main(void)
27 {
28     unsigned char data[256], line[256], out[256];
29     unsigned char c;
30     char *result;
31     int i, count, fd;
32     QIOSTATE *qio;
33     bool success;
34 
35     for (c = 1, i = 0; i < 255; i++, c++)
36         data[i] = c;
37     data[9] = ' ';
38     data[255] = '\255';
39     memcpy(line, data, 255);
40     line[255] = '\n';
41     memcpy(out, data, 255);
42     out[255] = '\0';
43     fd = open(".testout", O_RDWR | O_CREAT | O_TRUNC, 0644);
44     if (fd < 0)
45         sysbail("Can't create .testout");
46 
47     /* Start with small, equally sized lines exactly equal to the buffer.
48        Then a line equal in size to the buffer, then a short line and
49        another line equal in size to the buffer, then a half line and lines
50        repeated to fill another buffer, then a line that's one character too
51        long.  Finally, put out another short line. */
52     count = QIO_BUFFERSIZE / 256;
53     for (i = 0; i < count; i++)
54         output(fd, line, 256);
55     for (i = 0; i < count - 1; i++)
56         output(fd, data, 256);
57     output(fd, line, 256);
58     output(fd, "\n", 1);
59     for (i = 0; i < count - 1; i++)
60         output(fd, data, 256);
61     output(fd, line, 256);
62     output(fd, data, 127);
63     output(fd, "\n", 1);
64     for (i = 0; i < count; i++)
65         output(fd, line, 256);
66     for (i = 0; i < count; i++)
67         output(fd, data, 256);
68     output(fd, "\n", 1);
69     output(fd, line, 256);
70     close(fd);
71 
72     plan(36);
73 
74     /* Now make sure we can read all that back correctly. */
75     qio = QIOopen(".testout");
76     ok(qio != NULL, "QIOpen works");
77     ok(!QIOerror(qio), "...and there is no error state");
78     ok(QIOfileno(qio) > 0, "...and QIOfileno returns something valid");
79     if (unlink(".testout") < 0)
80         sysbail("Can't unlink .testout");
81     for (success = true, i = 0; i < count; i++) {
82         result = QIOread(qio);
83         success = (success && !QIOerror(qio) && (QIOlength(qio) == 255)
84                    && !strcmp(result, (char *) out));
85     }
86     ok(success, "Able to read the first QIO_BUFFERSIZE of data");
87     is_int(QIOtell(qio), (off_t) QIO_BUFFERSIZE, "QIOtell is correct");
88     result = QIOread(qio);
89     if (strlen(result) < QIO_BUFFERSIZE - 1) {
90         ok(false, "Read largest possible line");
91     } else {
92         for (success = true, i = 0; i < count - 1; i++)
93             success = success && !memcmp(result + i * 256, data, 256);
94         success = success && !memcmp(result + i * 256, data, 255);
95         ok(success, "Read largest possible line");
96     }
97     is_int(QIOtell(qio), (off_t) (2 * QIO_BUFFERSIZE), "QIOtell is correct");
98     result = QIOread(qio);
99     ok(!QIOerror(qio), "No error on reading an empty line");
100     is_int(QIOlength(qio), 0, "Length of the line is 0");
101     is_string(result, "", "...and result is an empty string");
102     result = QIOread(qio);
103     if (strlen(result) < QIO_BUFFERSIZE - 1) {
104         ok(false, "Read largest line again");
105     } else {
106         for (success = true, i = 0; i < count - 1; i++)
107             success = success && !memcmp(result + i * 256, data, 256);
108         success = success && !memcmp(result + i * 256, data, 255);
109         ok(success, "Read largest line again");
110     }
111     is_int(QIOtell(qio), (off_t) (3 * QIO_BUFFERSIZE + 1),
112            "QIOtell is correct");
113     result = QIOread(qio);
114     ok(!QIOerror(qio), "No error on a shorter read");
115     is_int(QIOlength(qio), 127, "Length is 127");
116     is_int(strlen(result), 127, "String is 127");
117     ok(!memcmp(result, data, 127), "Data is correct");
118     for (success = true, i = 0; i < count; i++) {
119         result = QIOread(qio);
120         success = (success && !QIOerror(qio) && (QIOlength(qio) == 255)
121                    && !strcmp(result, (char *) out));
122     }
123     ok(success, "Able to read another batch of lines");
124     is_int(QIOtell(qio), (off_t) (4 * QIO_BUFFERSIZE + 129),
125            "QIOtell is correct");
126     result = QIOread(qio);
127     ok(!result, "Failed to read too long of line");
128     ok(QIOerror(qio), "Error reported");
129     ok(QIOtoolong(qio), "...and too long flag is set");
130     result = QIOread(qio);
131     ok(!QIOerror(qio), "Reading again succeeds");
132     is_int(QIOlength(qio), 255, "...and returns the next block");
133     is_int(strlen(result), 255, "...and length is correct");
134     ok(!memcmp(result, line, 255), "...and data is correct");
135     result = QIOread(qio);
136     ok(!result, "End of file reached");
137     ok(!QIOerror(qio), "...with no error");
138     is_int(QIOrewind(qio), 0, "QIOrewind works");
139     is_int(QIOtell(qio), 0, "...and QIOtell is correct");
140     result = QIOread(qio);
141     ok(!QIOerror(qio), "Reading the first line works");
142     is_int(QIOlength(qio), 255, "...and QIOlength is correct");
143     is_int(strlen(result), 255, "...and the length is correct");
144     ok(!strcmp(result, (char *) out), "...and the data is correct");
145     is_int(QIOtell(qio), 256, "...and QIOtell is correct");
146     fd = QIOfileno(qio);
147     QIOclose(qio);
148     ok(close(fd) < 0, "QIOclose closed the file descriptor");
149     is_int(errno, EBADF, "...as confirmed by errno");
150 
151     return 0;
152 }
153