source: rtems/testsuites/psxtests/psxrdwrv/test.c @ c1d8ee4

4.11
Last change on this file since c1d8ee4 was c1d8ee4, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 17, 2013 at 9:59:13 AM

libcsupport: Accept NULL for zero-length entries

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/**
2 *  @file
3 *
4 *  This test exercises the following routines:
5 *
6 *    + readv
7 *    + writev
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2012.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.com/license/LICENSE.
17 */
18
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <fcntl.h>
25#include <unistd.h>
26#include <errno.h>
27#include <utime.h>
28#include <string.h>
29#include <inttypes.h>
30#include <limits.h>
31
32#include <stdio.h>
33#include <unistd.h>
34#include <sys/uio.h>
35
36#if defined(__rtems__)
37  #include <rtems.h>
38  #include <rtems/libio.h>
39  #include <pmacros.h>
40#else
41  #define TRUE  1
42  #define FALSE 0
43  #include <stdlib.h>
44  #define rtems_test_exit(_s) exit(_s)
45#endif
46
47/* forward declarations to avoid warnings */
48int test_main(void);
49int fillPatternBuffer(void);
50int doFunctionalTest(void);
51int doErrorTest(void);
52
53#define TESTFILE "testfile1.tst"
54
55/* This buffer size is assumed in the iovec initialization below */
56#define MAX_BUFFER 1000
57unsigned char PatternBuffer[MAX_BUFFER];
58unsigned char ReadBuffer[MAX_BUFFER];
59
60/*
61 * fillPatternBuffer function
62 *
63 * Fill the test buffer.
64 *
65 * Returns: TRUE if buffer filled
66 *          FALSE if buffer failed to fill
67 *
68 */
69int fillPatternBuffer(void)
70{
71  int retval = TRUE;
72  int i;
73
74  for (i=0 ; i<200  ; i++ ) PatternBuffer[i] = 'a';
75  for (    ; i<400  ; i++ ) PatternBuffer[i] = 'b';
76  for (    ; i<600  ; i++ ) PatternBuffer[i] = 'c';
77  for (    ; i<800  ; i++ ) PatternBuffer[i] = 'd';
78  for (    ; i<1000 ; i++ ) PatternBuffer[i] = 'e';
79  return retval;
80}
81
82/*
83 * doFunctionalTest function
84 *
85 * Write a file with writev and then read it back with readv.
86 *
87 * Returns: TRUE if all operations worked as expected
88 *          FALSE if an operation did not work as expected.
89 *
90 */
91int doFunctionalTest(void)
92{
93  FILE         *fp;
94  int           fd;
95  struct iovec  rdvec[4];
96  struct iovec  wrvec[4];
97  int           rc;
98
99
100  /*
101   * Setup the iovec
102   */
103  wrvec[0].iov_base = &PatternBuffer[0];
104  wrvec[0].iov_len  = 100;
105  wrvec[1].iov_base = &PatternBuffer[100];
106  wrvec[1].iov_len  = 200;
107  wrvec[2].iov_base = &PatternBuffer[300];
108  wrvec[2].iov_len  = 300;
109  wrvec[3].iov_base = &PatternBuffer[600];
110  wrvec[3].iov_len  = 400;
111
112  rdvec[0].iov_base = &ReadBuffer[0];
113  rdvec[0].iov_len  = 400;
114  rdvec[1].iov_base = &ReadBuffer[400];
115  rdvec[1].iov_len  = 300;
116  rdvec[2].iov_base = &ReadBuffer[700];
117  rdvec[2].iov_len  = 200;
118  rdvec[3].iov_base = &ReadBuffer[900];
119  rdvec[3].iov_len  = 100;
120
121  /*
122   * Write the File
123   */
124  fp = fopen(TESTFILE, "wt");
125  if ( fp == NULL ) {
126    printf( "fopen for write: %d=%s\n", errno, strerror(errno));
127    return FALSE;
128  }
129  fd = fileno(fp);
130
131  rc = writev(fd, wrvec, 4);
132  if ( rc <= 0 ) {
133    printf( "writev: %d=%s\n", errno, strerror(errno) );
134    return FALSE;
135  }
136
137  fclose(fp);
138
139  puts("File written using writev .. OK");
140
141  /*
142   * Now read it back and check it
143   */
144
145  fp = fopen(TESTFILE, "rt");
146  if ( fp == NULL ) {
147    printf( "fopen for write: %d=%s\n", errno, strerror(errno));
148    return FALSE;
149  }
150  fd = fileno(fp);
151
152  rc = readv(fd, rdvec, 4);
153  if ( rc <= 0 ) {
154    printf( "rd: %d=%s\n", errno, strerror(errno) );
155    return FALSE;
156  }
157
158  if ( memcmp( PatternBuffer, ReadBuffer, MAX_BUFFER ) ) {
159    puts("readv .. Buffers do not match");
160    return FALSE;
161  }
162
163  puts("File read using readv .. OK");
164
165  return TRUE;
166}
167
168/*
169 * doErrorTest function
170 *
171 * Hit all the error cases in readv/writev.
172 *
173 * Returns: TRUE if all operations worked as expected
174 *          FALSE if an operation did not work as expected.
175 *
176 */
177int doErrorTest(void)
178{
179  FILE         *fp;
180  int           fd;
181  struct iovec  vec[4];
182  int           rc;
183
184  /*
185   * Open and close the file to get a bad file descriptor
186   */
187  fp = fopen(TESTFILE, "wt");
188  if ( fp == NULL ) {
189    printf( "fopen for error 1: %d=%s\n", errno, strerror(errno));
190    return FALSE;
191  }
192  fd = fileno(fp);
193  fclose(fp);
194
195  /* writev -- bad file descriptor */
196  puts("writev bad file descriptor -- EBADF");
197  rc = writev(fd, vec, 4);
198  if ( (rc != -1) || (errno != EBADF) ) {
199    printf( "writev error 1: %d=%s\n", errno, strerror(errno) );
200    return FALSE;
201  }
202
203  /* readv -- bad file descriptor */
204  puts("readv bad file descriptor -- EBADF");
205  rc = read(fd, vec, 4);
206  if ( (rc != -1) || (errno != EBADF) ) {
207    printf( "readv error 1: %d=%s\n", errno, strerror(errno) );
208    return FALSE;
209  }
210
211  /*
212   * Open the file for the rest of the tests
213   */
214  fp = fopen(TESTFILE, "w+");
215  if ( fp == NULL ) {
216    printf( "fopen for error 2: %d=%s\n", errno, strerror(errno));
217    return FALSE;
218  }
219  fd = fileno(fp);
220
221#ifdef __rtems__
222  /* writev --  bad iovec pointer */
223  puts("writev bad iovec pointer -- EINVAL");
224  rc = writev(fd, NULL, 4);
225  if ( (rc != -1) || (errno != EINVAL) ) {
226    printf( "writev error 2: %d=%s\n", errno, strerror(errno) );
227    fclose(fp);
228    return FALSE;
229  }
230
231  /* readv --  bad iovec pointer */
232  puts("readv bad iovec pointer -- EINVAL");
233  rc = readv(fd, NULL, 4);
234  if ( (rc != -1) || (errno != EINVAL) ) {
235    printf( "readv error 2: %d=%s\n", errno, strerror(errno) );
236    fclose(fp);
237    return FALSE;
238  }
239
240  /* writev --  bad iovcnt 0 */
241  puts("writev bad iovcnt of 0 -- EINVAL");
242  rc = writev(fd, vec, 0);
243  if ( (rc != -1) || (errno != EINVAL) ) {
244    printf( "writev error 3: %d=%s\n", errno, strerror(errno) );
245    fclose(fp);
246    return FALSE;
247  }
248
249  /* readv --  bad iovcnt 0 */
250  puts("readv bad iovcnt of 0 -- EINVAL");
251  rc = readv(fd, vec, 0);
252  if ( (rc != -1) || (errno != EINVAL) ) {
253    printf( "readv error 3: %d=%s\n", errno, strerror(errno) );
254    fclose(fp);
255    return FALSE;
256  }
257#endif /* __rtems__ */
258
259  /* writev --  bad iovcnt negative */
260  puts("writev bad iovcnt negative -- EINVAL");
261  rc = writev(fd, vec, -2);
262  if ( (rc != -1) || (errno != EINVAL) ) {
263    printf( "writev error 4: %d=%s\n", errno, strerror(errno) );
264    fclose(fp);
265    return FALSE;
266  }
267
268  /* readv --  bad iovcnt negative */
269  puts("readv bad iovcnt negative -- EINVAL");
270  rc = readv(fd, vec, -100);
271  if ( (rc != -1) || (errno != EINVAL) ) {
272    printf( "readv error 4: %d=%s\n", errno, strerror(errno) );
273    fclose(fp);
274    return FALSE;
275  }
276
277#ifdef __rtems__
278  /* writev --  bad iov[i].iov_base */
279  vec[0].iov_base = vec;
280  vec[0].iov_len = 100;
281  vec[1].iov_base = NULL;
282  vec[1].iov_len = 100;
283  puts("writev bad iov[i].iov_base -- EINVAL");
284  rc = writev(fd, vec, 2);
285  if ( (rc != -1) || (errno != EINVAL) ) {
286    printf( "writev error 5: %d=%s\n", errno, strerror(errno) );
287    fclose(fp);
288    return FALSE;
289  }
290
291  /*  readv --  bad iov[i].iov_base */
292  vec[0].iov_base = vec;
293  vec[0].iov_len = 100;
294  vec[1].iov_base = NULL;
295  vec[1].iov_len = 100;
296  puts("readv bad iov[i].iov_base -- EINVAL");
297  rc = readv(fd, vec, 2);
298  if ( (rc != -1) || (errno != EINVAL) ) {
299    printf( "readv error 5: %d=%s\n", errno, strerror(errno) );
300    fclose(fp);
301    return FALSE;
302  }
303#endif /* __rtems__ */
304
305  /*  writev --  bad iov[i].iov_len < 0 */
306  vec[0].iov_base = vec;
307  vec[0].iov_len = 100;
308  vec[1].iov_base = vec;
309  vec[1].iov_len = -10;
310  puts("writev bad iov[i].iov_len < 0 -- EINVAL");
311  rc = writev(fd, vec, 2);
312  if ( (rc != -1) || (errno != EINVAL) ) {
313    printf( "writev error 6: %d=%s\n", errno, strerror(errno) );
314    fclose(fp);
315    return FALSE;
316  }
317
318  /*  readv --  bad iov[i].iov_len < 0 */
319  vec[0].iov_base = vec;
320  vec[0].iov_len = 100;
321  vec[1].iov_base = vec;
322  vec[1].iov_len = -1024;
323  puts("readv bad iov[i].iov_len < 0 -- EINVAL");
324  rc = readv(fd, vec, 2);
325  if ( (rc != -1) || (errno != EINVAL) ) {
326    printf( "readv error 6: %d=%s\n", errno, strerror(errno) );
327    fclose(fp);
328    return FALSE;
329  }
330
331  /*  writev --  iov_len total overflows */
332  vec[0].iov_base = vec;
333  vec[0].iov_len = SIZE_MAX;
334  vec[1].iov_base = vec;
335  vec[1].iov_len = SIZE_MAX;
336  vec[2].iov_base = vec;
337  vec[2].iov_len = SIZE_MAX;
338  puts("writev iov_len total overflows -- EINVAL");
339  rc = writev(fd, vec, 3);
340  if ( (rc != -1) || (errno != EINVAL) ) {
341    printf( "writev error 7: rc=%d %d=%s\n", rc, errno, strerror(errno) );
342    fclose(fp);
343    return FALSE;
344  }
345
346  /*  readv --  iov_len total overflows */
347  vec[0].iov_base = vec;
348  vec[0].iov_len = SIZE_MAX;
349  vec[1].iov_base = vec;
350  vec[1].iov_len = SIZE_MAX;
351  vec[2].iov_base = vec;
352  vec[2].iov_len = SIZE_MAX;
353  puts("readv iov_len total overflows -- EINVAL");
354  rc = readv(fd, vec, 3);
355  if ( (rc != -1) || (errno != EINVAL) ) {
356    printf( "read error 7: rc=%d %d=%s\n", rc, errno, strerror(errno) );
357    fclose(fp);
358    return FALSE;
359  }
360
361  /*  writev --  all zero length buffers */
362  vec[0].iov_base = vec;
363  vec[0].iov_len = 0;
364  vec[1].iov_base = NULL;
365  vec[1].iov_len = 0;
366  puts("writev iov_len works with no effect -- OK");
367  rc = writev(fd, vec, 2);
368  if ( (rc != 0) ) {
369    printf( "writev error 8: %d=%s\n", errno, strerror(errno) );
370    fclose(fp);
371    return FALSE;
372  }
373
374  /*  readv --  all zero length buffers */
375  vec[0].iov_base = vec;
376  vec[0].iov_len = 0;
377  vec[1].iov_base = NULL;
378  vec[1].iov_len = 0;
379  puts("readv iov_len works with no effect -- OK");
380  rc = readv(fd, vec, 2);
381  if ( (rc != 0) ) {
382    printf( "readv error 8: %d=%s\n", errno, strerror(errno) );
383    fclose(fp);
384    return FALSE;
385  }
386
387#ifdef __rtems__
388  puts("readv bad iovcnt of IOV_MAX + 1 -- EINVAL");
389  rc = readv(fd, vec, IOV_MAX + 1);
390  if ( (rc != -1) || (errno != EINVAL) ) {
391    printf( "readv error 9: %d=%s\n", errno, strerror(errno) );
392    fclose(fp);
393    return FALSE;
394  }
395
396  puts("writev bad iovcnt of IOV_MAX + 1 -- EINVAL");
397  rc = writev(fd, vec, IOV_MAX + 1);
398  if ( (rc != -1) || (errno != EINVAL) ) {
399    printf( "writev error 9: %d=%s\n", errno, strerror(errno) );
400    fclose(fp);
401    return FALSE;
402  }
403#endif /* __rtems__ */
404
405  fclose(fp);
406  return TRUE;
407}
408
409
410/* ---------------------------------------------------------------
411 * Main function
412 *
413 *  main entry point to the test
414 *
415 * ---------------------------------------------------------------
416 */
417
418#if defined(__rtems__)
419int test_main(void)
420#else
421int main(
422  int    argc,
423  char **argv
424)
425#endif
426{
427  puts( "*** POSIX TEST READV/WRITEV ***" );
428
429  if ( fillPatternBuffer() != TRUE ) {
430    puts("Error filling pattern buffer" );
431    rtems_test_exit(0);
432  }
433
434  if (doErrorTest() != TRUE) {
435    puts("Error during error test!!!!");
436    rtems_test_exit(0);
437  }
438  if (doFunctionalTest() != TRUE) {
439    puts("Error during functional test!!!!");
440    rtems_test_exit(0);
441  }
442
443  unlink(TESTFILE);
444  puts( "*** END OF TEST PSXRDWRV ***" );
445  rtems_test_exit(0);
446}
Note: See TracBrowser for help on using the repository browser.