source: rtems/testsuites/fstests/fsrdwr/init.c @ b88c7583

5
Last change on this file since b88c7583 was b88c7583, checked in by Sebastian Huber <sebastian.huber@…>, on 11/11/19 at 13:24:45

fstests: Use tmacros.h instead of pmacros.h

This avoids an extra include path.

Update #3818.

  • Property mode set to 100644
File size: 17.9 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2011.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include <sys/stat.h>
15#include <string.h>
16#include <stdlib.h>
17#include <fcntl.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <stdint.h>
21#include <memory.h>
22#include <unistd.h>
23#include <errno.h>
24
25#include "fstest.h"
26#include "fs_config.h"
27#include <tmacros.h>
28
29const char rtems_test_name[] = "FSRDWR " FILESYSTEM;
30
31static const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
32
33static const char databuf [] =
34  "Happy days are here again.  Happy days are here again.1Happy "
35  "days are here again.2Happy days are here again.3Happy days are here again."
36  "4Happy days are here again.5Happy days are here again.6Happy days are here "
37  "again.7Happy days are here again.";
38
39static const size_t len = sizeof (databuf) - 1;
40
41static void
42test_case_enter (const char *wd)
43{
44  int status;
45
46  printf ("test case: %s\n", wd);
47
48  status = mkdir (wd, mode);
49  rtems_test_assert (status == 0);
50
51  status = chdir (wd);
52  rtems_test_assert (status == 0);
53}
54
55static void
56test_case_leave (void)
57{
58  int status;
59
60  status = chdir ("..");
61  rtems_test_assert (status == 0);
62}
63
64static void
65read_write_test (void)
66{
67
68  int fd;
69  int status;
70  char *name01 = "name01";
71  char *name02 = "name02";
72  struct stat statbuf;
73  char *readbuf;
74  off_t pos = 0;
75
76  int n;
77
78  test_case_enter (__func__);
79
80  /*
81   * Create an empty file
82   */
83  fd = open (name01, O_CREAT | O_WRONLY, mode);
84  status = close (fd);
85  rtems_test_assert (status == 0);
86  /*
87   * Verify the empty file
88   */
89  status = stat (name01, &statbuf);
90  rtems_test_assert (status == 0);
91
92  rtems_test_assert (S_ISREG (statbuf.st_mode));
93  rtems_test_assert (statbuf.st_size == 0);
94
95  /*
96   * Write data to the empty file
97   */
98  fd = open (name01, O_WRONLY);
99  rtems_test_assert (fd >= 0);
100
101  n = write (fd, databuf, len);
102  rtems_test_assert (n == len);
103  status = close (fd);
104  rtems_test_assert (status == 0);
105
106  status = stat (name01, &statbuf);
107  rtems_test_assert (status == 0);
108  rtems_test_assert (S_ISREG (statbuf.st_mode));
109  rtems_test_assert (statbuf.st_size == len);
110
111  /*
112   * Read the data from the file
113   */
114  readbuf = (char *) malloc (len + 1);
115  rtems_test_assert (readbuf);
116
117  fd = open (name01, O_RDONLY);
118  rtems_test_assert (fd >= 0);
119  n = read (fd, readbuf, len);
120  rtems_test_assert (n == len);
121  rtems_test_assert (!strncmp (databuf, readbuf, len));
122  status = close (fd);
123  rtems_test_assert (status == 0);
124
125  /*
126   * Open the file using O_APPEND and write the data
127   */
128  memset (readbuf, 0, len + 1);
129  fd = open (name01, O_WRONLY | O_APPEND);
130  n = write (fd, databuf, len);
131  rtems_test_assert (n == len);
132  pos = lseek (fd, 0, SEEK_CUR);
133  rtems_test_assert (pos == 2 * len);
134  pos = lseek (fd, 0, SEEK_SET);
135  rtems_test_assert (pos == 0);
136  n = write (fd, databuf, len);
137  rtems_test_assert (n == len);
138  pos = lseek (fd, 0, SEEK_CUR);
139  rtems_test_assert (pos == 3 * len);
140  status = close (fd);
141  rtems_test_assert (status == 0);
142
143  /*
144   * Read the data and verify it
145   */
146  fd = open (name01, O_RDONLY);
147  rtems_test_assert (fd >= 0);
148  n = read (fd, readbuf, len);
149  rtems_test_assert (n == len);
150  rtems_test_assert (!strncmp (databuf, readbuf, len));
151  n = read (fd, readbuf, len);
152  rtems_test_assert (n == len);
153  rtems_test_assert (!strncmp (databuf, readbuf, len));
154  n = read (fd, readbuf, len);
155  rtems_test_assert (n == len);
156  rtems_test_assert (!strncmp (databuf, readbuf, len));
157  status = close (fd);
158  rtems_test_assert (status == 0);
159
160  /*
161   * Open the file using O_RDWR
162   */
163  memset (readbuf, 0, len + 1);
164
165  fd = open (name01, O_RDWR);
166  n = write (fd, databuf, len);
167  rtems_test_assert (n == len);
168  pos = lseek (fd, 0, SEEK_CUR);
169  rtems_test_assert (pos == len);
170  n = read (fd, readbuf, len);
171  rtems_test_assert (n == len);
172  rtems_test_assert (!strncmp (databuf, readbuf, len));
173  pos = lseek (fd, 0, SEEK_CUR);
174  rtems_test_assert (pos == 2 * len);
175  status = close (fd);
176  rtems_test_assert (status == 0);
177
178  /*
179   * Open the file using O_TRUNC
180   */
181
182  fd = open (name01, O_WRONLY | O_TRUNC);
183  status = close (fd);
184  rtems_test_assert (status == 0);
185
186  /*
187   * Verify if the length is zero
188   */
189  status = stat (name01, &statbuf);
190  rtems_test_assert (status == 0);
191  rtems_test_assert (S_ISREG (statbuf.st_mode));
192  rtems_test_assert (statbuf.st_size == 0);
193
194  /*
195   * Open a directory
196   */
197  status = mkdir (name02, mode);
198  rtems_test_assert (status == 0);
199  fd = open (name02, O_RDONLY);
200  rtems_test_assert (fd >= 0);
201
202  status = close (fd);
203  rtems_test_assert (status == 0);
204
205  free (readbuf);
206
207  test_case_leave ();
208}
209
210static void
211truncate_test03 (void)
212{
213
214  int fd;
215  int status;
216  char *name01 = "name01";
217  struct stat statbuf;
218
219  char data;
220  int n;
221  int i;
222
223  char *readbuf;
224  off_t good_size = 100;
225
226  test_case_enter (__func__);
227
228  /*
229   * Create an empty file
230   */
231  fd = creat (name01, mode);
232  status = close (fd);
233  rtems_test_assert (status == 0);
234
235
236  /*
237   * Truncate it to a valid size
238   */
239  status = truncate (name01, good_size);
240  rtems_test_assert (status == 0);
241  /*
242   * Verify the size and the data
243   */
244  status = stat (name01, &statbuf);
245  rtems_test_assert (status == 0);
246  rtems_test_assert (good_size == statbuf.st_size);
247
248  fd = open (name01, O_RDONLY);
249  while ((n = read (fd, &data, 1)) > 0) {
250    rtems_test_assert (data == 0);
251  }
252
253  status = close (fd);
254  rtems_test_assert (status == 0);
255
256  /*
257   * Fill a file with data
258   */
259  fd = open (name01, O_WRONLY);
260  rtems_test_assert (fd >= 0);
261  n = write (fd, databuf, len);
262  rtems_test_assert (n == len);
263  status = close (fd);
264  rtems_test_assert (status == 0);
265
266  /*
267   * Truncate it to the half size
268   */
269
270  status = truncate (name01, len / 2);
271  rtems_test_assert (status == 0);
272  status = truncate (name01, len);
273  rtems_test_assert (status == 0);
274
275  /*
276   * verify the data
277   */
278  readbuf = (char *) malloc (len / 2);
279  rtems_test_assert (readbuf);
280  fd = open (name01, O_RDONLY);
281  rtems_test_assert (fd >= 0);
282  n = read (fd, readbuf, len / 2);
283  rtems_test_assert (n == len / 2);
284  rtems_test_assert (!strncmp (databuf, readbuf, len / 2));
285  n = read (fd, readbuf, len / 2);
286  rtems_test_assert (n == len / 2);
287  for (i = 0; i < len / 2; i++) {
288    rtems_test_assert (readbuf[i] == 0);
289  }
290  status = close (fd);
291  rtems_test_assert (status == 0);
292
293  /*
294   * Go back to parent directory
295   */
296  status = chdir ("..");
297  rtems_test_assert (status == 0);
298
299  free(readbuf);
300}
301
302static void
303lseek_test (void)
304{
305  int fd;
306  int status;
307  const char *name01 = "test_name01";
308  struct stat statbuf;
309
310  ssize_t n;
311  int i;
312
313  off_t pos;
314  ssize_t total_written = 0;
315
316  char *readbuf;
317
318  test_case_enter (__func__);
319
320  /*
321   * Create a file and fill with the data.
322   */
323  puts ("Create a new file");
324  fd = creat (name01, mode);
325  rtems_test_assert (fd >= 0);
326
327  pos = lseek (fd, 0, SEEK_CUR);
328  rtems_test_assert (pos == 0);
329
330  pos = lseek (fd, 0, SEEK_END);
331  rtems_test_assert (pos == 0);
332
333  pos = lseek (fd, 0, SEEK_SET);
334  rtems_test_assert (pos == 0);
335
336
337  printf ("Writing %zd bytes to file\n", len * 10);
338  for (i = 0; i < 10; i++) {
339    n = write (fd, databuf, len);
340    rtems_test_assert (n == (ssize_t) len);
341    total_written += n;
342  }
343  printf ("Successfully wrote %zd\n", total_written);
344
345  /*
346   * Check the current position
347   */
348  puts ("Check the current position");
349  pos = lseek (fd, 0, SEEK_CUR);
350  rtems_test_assert (pos == total_written);
351
352  pos = lseek (fd, 0, SEEK_END);
353  rtems_test_assert (pos == total_written);
354
355  /*
356   * ftruncate shall not change the posistion
357   */
358  status = ftruncate (fd, total_written + 1);
359  rtems_test_assert (status == 0);
360
361  pos = lseek (fd, 0, SEEK_CUR);
362  rtems_test_assert (pos == total_written);
363
364  pos = lseek (fd, 0, SEEK_END);
365  printf ("%jd\n", (intmax_t) pos);
366  rtems_test_assert (pos == total_written + 1);
367
368  status = ftruncate (fd, total_written);
369  rtems_test_assert (status == 0);
370
371  pos = lseek (fd, 0, SEEK_CUR);
372  rtems_test_assert (pos == total_written + 1);
373
374  /*
375   * Check the file size
376   */
377  status = fstat (fd, &statbuf);
378  rtems_test_assert (status == 0);
379  rtems_test_assert (statbuf.st_size == total_written);
380
381  status = ftruncate (fd, total_written);
382  rtems_test_assert (status == 0);
383
384  status = close (fd);
385  rtems_test_assert (status == 0);
386
387  /*
388   * Open the file with O_RDONLY and check the lseek
389   */
390  readbuf = (char *) malloc (len);
391  fd = open (name01, O_RDONLY);
392  pos = lseek (fd, len, SEEK_CUR);
393  rtems_test_assert (pos == len);
394  n = read (fd, readbuf, len);
395  rtems_test_assert (n == len);
396  rtems_test_assert (!strncmp (databuf, readbuf, len));
397
398  pos = lseek (fd, len, SEEK_CUR);
399  rtems_test_assert (pos == 3 * len);
400  n = read (fd, readbuf, len);
401  rtems_test_assert (n == len);
402  rtems_test_assert (!strncmp (databuf, readbuf, len));
403
404  pos = lseek (fd, -(off_t) len, SEEK_CUR);
405  rtems_test_assert (pos == 3 * len);
406  n = read (fd, readbuf, len);
407  rtems_test_assert (n == len);
408  rtems_test_assert (!strncmp (databuf, readbuf, len));
409
410  pos = lseek (fd, 4 * len, SEEK_SET);
411  n = read (fd, readbuf, len);
412  rtems_test_assert (n == len);
413  rtems_test_assert (!strncmp (databuf, readbuf, len));
414
415
416  pos = lseek (fd, 10, SEEK_SET);
417  n = read (fd, readbuf, len);
418  rtems_test_assert (n == len);
419  rtems_test_assert (strncmp (databuf, readbuf, len) != 0);
420
421  pos = lseek (fd, -(off_t) len, SEEK_END);
422  n = read (fd, readbuf, 2 * len);
423  rtems_test_assert (n == len);
424  rtems_test_assert (!strncmp (databuf, readbuf, len));
425
426  status = close (fd);
427  rtems_test_assert (status == 0);
428
429  /*
430   * Open the file withe O_RDWR and check the lseek
431   */
432
433  fd = open (name01, O_RDWR);
434
435  pos = lseek (fd, len, SEEK_CUR);
436  rtems_test_assert (pos == len);
437  n = read (fd, readbuf, len);
438  rtems_test_assert (n == len);
439  rtems_test_assert (!strncmp (databuf, readbuf, len));
440
441  pos = lseek (fd, len, SEEK_CUR);
442  rtems_test_assert (pos == 3 * len);
443  n = read (fd, readbuf, len);
444  rtems_test_assert (n == len);
445  rtems_test_assert (!strncmp (databuf, readbuf, len));
446
447  pos = lseek (fd, -(off_t) len, SEEK_CUR);
448  rtems_test_assert (pos == 3 * len);
449  n = read (fd, readbuf, len);
450  rtems_test_assert (n == len);
451  rtems_test_assert (!strncmp (databuf, readbuf, len));
452
453  pos = lseek (fd, 4 * len, SEEK_SET);
454  n = read (fd, readbuf, len);
455  rtems_test_assert (n == len);
456  rtems_test_assert (!strncmp (databuf, readbuf, len));
457
458  /*
459   * Go to the wrong position, so the data is not the same
460   */
461  pos = lseek (fd, 10, SEEK_SET);
462  n = read (fd, readbuf, len);
463  rtems_test_assert (n == len);
464  rtems_test_assert (strncmp (databuf, readbuf, len) != 0);
465
466  /*
467   * Use SEEK_END
468   */
469  pos = lseek (fd, -(off_t) len, SEEK_END);
470  n = read (fd, readbuf, 2 * len);
471  rtems_test_assert (n == len);
472  rtems_test_assert (!strncmp (databuf, readbuf, len));
473
474  memset (readbuf, 0, len);
475
476  /*
477   * Write the zero to the end of file.
478   */
479  pos = lseek (fd, -(off_t) len, SEEK_END);
480  rtems_test_assert (pos == (off_t) total_written - (off_t) len);
481  n = write (fd, readbuf, len);
482  rtems_test_assert (n == len);
483  /*
484   * Verify it
485   */
486  pos = lseek (fd, (off_t) total_written - (off_t) len, SEEK_SET);
487  n = read (fd, readbuf, len);
488  rtems_test_assert (n == len);
489  for (i = 0; i < n; i++) {
490    rtems_test_assert (readbuf[i] == 0);
491  }
492
493  /*
494   * Write the zero to the beginning of file.
495   */
496  pos = lseek (fd, -(off_t) total_written, SEEK_END);
497  rtems_test_assert (pos == 0);
498  n = write (fd, readbuf, len);
499  rtems_test_assert (n == len);
500
501  /*
502   * Verify it
503   */
504
505  pos = lseek (fd, 0, SEEK_SET);
506  n = read (fd, readbuf, len);
507  rtems_test_assert (n == len);
508  for (i = 0; i < n; i++) {
509    rtems_test_assert (readbuf[i] == 0);
510  }
511
512  n = read (fd, readbuf, len);
513  rtems_test_assert (n == len);
514  rtems_test_assert (strncmp (databuf, readbuf, len) == 0);
515  /*
516   * Call ftruncate to decrease the file and the position not change
517   */
518  status = ftruncate (fd, len);
519  rtems_test_assert (status == 0);
520  pos = lseek (fd, 0, SEEK_CUR);
521  rtems_test_assert (pos == len * 2);
522
523  status = close (fd);
524  rtems_test_assert (status == 0);
525
526  test_case_leave ();
527
528  free(readbuf);
529}
530
531static void
532truncate_to_zero (void)
533{
534  int fd;
535  ssize_t n;
536  int status;
537  off_t pos;
538
539  test_case_enter (__func__);
540
541  fd = creat ("file", mode);
542  rtems_test_assert (fd >= 0);
543
544  n = write (fd, databuf, len);
545  rtems_test_assert (n == (ssize_t) len);
546
547  pos = lseek (fd, 0, SEEK_END);
548  rtems_test_assert (pos == len);
549
550  status = ftruncate (fd, 0);
551  rtems_test_assert (status == 0);
552
553  pos = lseek (fd, 0, SEEK_END);
554  rtems_test_assert (pos == 0);
555
556  status = close (fd);
557  rtems_test_assert (status == 0);
558
559  test_case_leave ();
560}
561
562static void
563random_fill (char *dst, size_t n)
564{
565  static uint32_t u = 0x12345678;
566  uint32_t v = u;
567  uint32_t w = u;
568  size_t i = 0;
569  int j = 0;
570
571  while (i < n) {
572    if (j == 0) {
573      v *= 1664525;
574      v += 1013904223;
575      w = v;
576    } else {
577      w >>= 8;
578    }
579
580    dst [i] = (char) w;
581
582    ++i;
583    j = (j + 1) % 4;
584  }
585
586  u = v;
587}
588
589static void
590block_rw_lseek (int fd, size_t pos)
591{
592  off_t actual;
593
594  actual = lseek (fd, pos, SEEK_SET);
595  rtems_test_assert (actual == pos);
596}
597
598static void
599block_rw_write (int fd, char *out, size_t pos, size_t size)
600{
601  ssize_t n;
602
603  random_fill (out + pos, size);
604
605  block_rw_lseek (fd, pos);
606
607  n = write (fd, out + pos, size);
608  rtems_test_assert (n == (ssize_t) size);
609}
610
611static void
612block_rw_write_cont (int fd, char *out, size_t *pos, size_t size)
613{
614  ssize_t n;
615
616  random_fill (out + *pos, size);
617
618  n = write (fd, out + *pos, size);
619  rtems_test_assert (n == (ssize_t) size);
620
621  *pos += size;
622}
623
624static void
625block_rw_check (int fd, const char *out, char *in, size_t size)
626{
627  ssize_t n;
628  off_t file_size;
629
630  file_size = lseek (fd, 0, SEEK_END);
631  rtems_test_assert (file_size == size);
632
633  block_rw_lseek (fd, 0);
634
635  n = read (fd, in, size);
636  rtems_test_assert (n == (ssize_t) size);
637
638  rtems_test_assert (memcmp (out, in, size) == 0);
639}
640
641static void
642block_rw_prepare (const char *t, int fd, char *out, size_t size)
643{
644  int status;
645
646  printf ("test case: %s\n", t);
647
648  memset (out, 0, size);
649
650  status = ftruncate (fd, 0);
651  rtems_test_assert (status == 0);
652
653  block_rw_lseek (fd, 0);
654}
655
656static void
657block_rw_case_0 (int fd, size_t block_size, char *out, char *in)
658{
659  const size_t size = 3 * block_size + 1;
660
661  block_rw_prepare (__func__, fd, out, size);
662  block_rw_write (fd, out, 0, size);
663  block_rw_check (fd, out, in, size);
664}
665
666static void
667block_rw_case_1 (int fd, size_t block_size, char *out, char *in)
668{
669  const size_t size = 2 * block_size;
670
671  block_rw_prepare (__func__, fd, out, size);
672  block_rw_write (fd, out, block_size, block_size);
673  block_rw_check (fd, out, in, size);
674}
675
676static void
677block_rw_case_2 (int fd, size_t block_size, char *out, char *in)
678{
679  const size_t size = (5 * block_size) / 2;
680
681  block_rw_prepare (__func__, fd, out, size);
682  block_rw_write (fd, out, (3 * block_size) / 2, block_size);
683  block_rw_check (fd, out, in, size);
684}
685
686static void
687block_rw_case_3 (int fd, size_t block_size, char *out, char *in)
688{
689  const size_t size = 2 * block_size;
690
691  block_rw_prepare (__func__, fd, out, size);
692  block_rw_write (fd, out, block_size, block_size / 3);
693  block_rw_write (fd, out, 2 * block_size - block_size / 3, block_size / 3);
694  block_rw_check (fd, out, in, size);
695}
696
697static void
698block_rw_case_4 (int fd, size_t block_size, char *out, char *in)
699{
700  const size_t size = 3 * block_size + 1;
701  size_t pos = 0;
702
703  block_rw_prepare (__func__, fd, out, size);
704  block_rw_write_cont (fd, out, &pos, block_size);
705  block_rw_write_cont (fd, out, &pos, block_size / 2);
706  block_rw_write_cont (fd, out, &pos, block_size);
707  block_rw_write_cont (fd, out, &pos, block_size / 2);
708  block_rw_write_cont (fd, out, &pos, 1);
709  block_rw_check (fd, out, in, size);
710}
711
712static void
713block_read_and_write (void)
714{
715  int fd;
716  struct stat st;
717  int status;
718  size_t block_size;
719  size_t size;
720  char *out;
721  char *in;
722
723  test_case_enter (__func__);
724
725  fd = open ("file", O_RDWR | O_CREAT | O_TRUNC, mode);
726  rtems_test_assert (fd >= 0);
727
728  status = fstat (fd, &st);
729  rtems_test_assert (status == 0);
730
731  block_size = st.st_blksize;
732  size = 3 * block_size + 1;
733
734  out = malloc (size);
735  rtems_test_assert (out != NULL);
736
737  in = malloc (size);
738  rtems_test_assert (in != NULL);
739
740  block_rw_case_0 (fd, block_size, out, in);
741  block_rw_case_1 (fd, block_size, out, in);
742  block_rw_case_2 (fd, block_size, out, in);
743  block_rw_case_3 (fd, block_size, out, in);
744  block_rw_case_4 (fd, block_size, out, in);
745
746  status = close (fd);
747  rtems_test_assert (status == 0);
748
749  free (out);
750  free (in);
751
752  test_case_leave ();
753}
754
755static void
756write_until_no_space_is_left (void)
757{
758  static const char file [] = "zero";
759  int fd;
760  struct stat st;
761  int status;
762  blksize_t block_size;
763  char *out;
764  ssize_t chunk_size;
765  ssize_t written;
766  off_t total;
767
768  /* Use the root directory to account for some FAT12 or FAT16 specialities */
769  printf ("test case: %s\n", __func__);
770
771  fd = open (file, O_RDWR | O_CREAT | O_TRUNC, mode);
772  rtems_test_assert (fd >= 0);
773
774  status = fstat (fd, &st);
775  rtems_test_assert (status == 0);
776  rtems_test_assert (st.st_size == 0);
777  rtems_test_assert (st.st_blksize > 0);
778  block_size = st.st_blksize;
779
780  out = calloc (1, block_size);
781  rtems_test_assert (out != NULL);
782
783  total = 0;
784  chunk_size = block_size / 2;
785  do {
786    errno = 0;
787
788    written = write (fd, out, chunk_size);
789    if (written > 0) {
790      total += written;
791    }
792
793    chunk_size = block_size;
794  } while (written > 0);
795
796  rtems_test_assert (written == -1);
797  rtems_test_assert (errno == ENOSPC || errno == EFBIG);
798
799  status = close (fd);
800  rtems_test_assert (status == 0);
801
802  /* Do not use fstat() to do the path evaluation again */
803  status = lstat (file, &st);
804  rtems_test_assert (status == 0);
805  rtems_test_assert (st.st_size == total);
806
807  free (out);
808}
809
810void
811test (void)
812{
813  read_write_test ();
814  lseek_test ();
815  truncate_test03 ();
816  truncate_to_zero ();
817  block_read_and_write ();
818  write_until_no_space_is_left ();
819}
Note: See TracBrowser for help on using the repository browser.