Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:31

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2011.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
0027  */
0028 
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #include <sys/stat.h>
0034 #include <string.h>
0035 #include <stdlib.h>
0036 #include <fcntl.h>
0037 #include <stdio.h>
0038 #include <stdlib.h>
0039 #include <stdint.h>
0040 #include <memory.h>
0041 #include <unistd.h>
0042 #include <errno.h>
0043 
0044 #include "fstest.h"
0045 #include "fs_config.h"
0046 #include <tmacros.h>
0047 
0048 const char rtems_test_name[] = "FSRDWR " FILESYSTEM;
0049 const RTEMS_TEST_STATE rtems_test_state = TEST_STATE;
0050 
0051 static const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0052 
0053 static const char databuf [] =
0054   "Happy days are here again.  Happy days are here again.1Happy "
0055   "days are here again.2Happy days are here again.3Happy days are here again."
0056   "4Happy days are here again.5Happy days are here again.6Happy days are here "
0057   "again.7Happy days are here again.";
0058 
0059 static const size_t len = sizeof (databuf) - 1;
0060 
0061 static void
0062 test_case_enter (const char *wd)
0063 {
0064   int status;
0065 
0066   printf ("test case: %s\n", wd);
0067 
0068   status = mkdir (wd, mode);
0069   rtems_test_assert (status == 0);
0070 
0071   status = chdir (wd);
0072   rtems_test_assert (status == 0);
0073 }
0074 
0075 static void
0076 test_case_leave (void)
0077 {
0078   int status;
0079 
0080   status = chdir ("..");
0081   rtems_test_assert (status == 0);
0082 }
0083 
0084 static void
0085 read_write_test (void)
0086 {
0087 
0088   int fd;
0089   int status;
0090   char *name01 = "name01";
0091   char *name02 = "name02";
0092   struct stat statbuf;
0093   char *readbuf;
0094   off_t pos = 0;
0095 
0096   int n;
0097 
0098   test_case_enter (__func__);
0099 
0100   /*
0101    * Create an empty file
0102    */
0103   fd = open (name01, O_CREAT | O_WRONLY, mode);
0104   status = close (fd);
0105   rtems_test_assert (status == 0);
0106   /*
0107    * Verify the empty file
0108    */
0109   status = stat (name01, &statbuf);
0110   rtems_test_assert (status == 0);
0111 
0112   rtems_test_assert (S_ISREG (statbuf.st_mode));
0113   rtems_test_assert (statbuf.st_size == 0);
0114 
0115   /*
0116    * Write data to the empty file
0117    */
0118   fd = open (name01, O_WRONLY);
0119   rtems_test_assert (fd >= 0);
0120 
0121   n = write (fd, databuf, len);
0122   rtems_test_assert (n == len);
0123   status = close (fd);
0124   rtems_test_assert (status == 0);
0125 
0126   status = stat (name01, &statbuf);
0127   rtems_test_assert (status == 0);
0128   rtems_test_assert (S_ISREG (statbuf.st_mode));
0129   rtems_test_assert (statbuf.st_size == len);
0130 
0131   /*
0132    * Read the data from the file
0133    */
0134   readbuf = (char *) malloc (len + 1);
0135   rtems_test_assert (readbuf);
0136 
0137   fd = open (name01, O_RDONLY);
0138   rtems_test_assert (fd >= 0);
0139   n = read (fd, readbuf, len);
0140   rtems_test_assert (n == len);
0141   rtems_test_assert (!strncmp (databuf, readbuf, len));
0142   status = close (fd);
0143   rtems_test_assert (status == 0);
0144 
0145   /*
0146    * Open the file using O_APPEND and write the data
0147    */
0148   memset (readbuf, 0, len + 1);
0149   fd = open (name01, O_WRONLY | O_APPEND);
0150   n = write (fd, databuf, len);
0151   rtems_test_assert (n == len);
0152   pos = lseek (fd, 0, SEEK_CUR);
0153   rtems_test_assert (pos == 2 * len);
0154   pos = lseek (fd, 0, SEEK_SET);
0155   rtems_test_assert (pos == 0);
0156   n = write (fd, databuf, len);
0157   rtems_test_assert (n == len);
0158   pos = lseek (fd, 0, SEEK_CUR);
0159   rtems_test_assert (pos == 3 * len);
0160   status = close (fd);
0161   rtems_test_assert (status == 0);
0162 
0163   /*
0164    * Read the data and verify it
0165    */
0166   fd = open (name01, O_RDONLY);
0167   rtems_test_assert (fd >= 0);
0168   n = read (fd, readbuf, len);
0169   rtems_test_assert (n == len);
0170   rtems_test_assert (!strncmp (databuf, readbuf, len));
0171   n = read (fd, readbuf, len);
0172   rtems_test_assert (n == len);
0173   rtems_test_assert (!strncmp (databuf, readbuf, len));
0174   n = read (fd, readbuf, len);
0175   rtems_test_assert (n == len);
0176   rtems_test_assert (!strncmp (databuf, readbuf, len));
0177   status = close (fd);
0178   rtems_test_assert (status == 0);
0179 
0180   /*
0181    * Open the file using O_RDWR
0182    */
0183   memset (readbuf, 0, len + 1);
0184 
0185   fd = open (name01, O_RDWR);
0186   n = write (fd, databuf, len);
0187   rtems_test_assert (n == len);
0188   pos = lseek (fd, 0, SEEK_CUR);
0189   rtems_test_assert (pos == len);
0190   n = read (fd, readbuf, len);
0191   rtems_test_assert (n == len);
0192   rtems_test_assert (!strncmp (databuf, readbuf, len));
0193   pos = lseek (fd, 0, SEEK_CUR);
0194   rtems_test_assert (pos == 2 * len);
0195   status = close (fd);
0196   rtems_test_assert (status == 0);
0197 
0198   /*
0199    * Open the file using O_TRUNC
0200    */
0201 
0202   fd = open (name01, O_WRONLY | O_TRUNC);
0203   status = close (fd);
0204   rtems_test_assert (status == 0);
0205 
0206   /*
0207    * Verify if the length is zero
0208    */
0209   status = stat (name01, &statbuf);
0210   rtems_test_assert (status == 0);
0211   rtems_test_assert (S_ISREG (statbuf.st_mode));
0212   rtems_test_assert (statbuf.st_size == 0);
0213 
0214   /*
0215    * Open a directory
0216    */
0217   status = mkdir (name02, mode);
0218   rtems_test_assert (status == 0);
0219   fd = open (name02, O_RDONLY);
0220   rtems_test_assert (fd >= 0);
0221 
0222   status = close (fd);
0223   rtems_test_assert (status == 0);
0224 
0225   free (readbuf);
0226 
0227   test_case_leave ();
0228 }
0229 
0230 static void
0231 truncate_test03 (void)
0232 {
0233 
0234   int fd;
0235   int status;
0236   char *name01 = "name01";
0237   struct stat statbuf;
0238 
0239   char data;
0240   int n;
0241   int i;
0242 
0243   char *readbuf;
0244   off_t good_size = 100;
0245 
0246   test_case_enter (__func__);
0247 
0248   /*
0249    * Create an empty file
0250    */
0251   fd = creat (name01, mode);
0252   status = close (fd);
0253   rtems_test_assert (status == 0);
0254 
0255 
0256   /*
0257    * Truncate it to a valid size
0258    */
0259   status = truncate (name01, good_size);
0260   rtems_test_assert (status == 0);
0261   /*
0262    * Verify the size and the data
0263    */
0264   status = stat (name01, &statbuf);
0265   rtems_test_assert (status == 0);
0266   rtems_test_assert (good_size == statbuf.st_size);
0267 
0268   fd = open (name01, O_RDONLY);
0269   while ((n = read (fd, &data, 1)) > 0) {
0270     rtems_test_assert (data == 0);
0271   }
0272 
0273   status = close (fd);
0274   rtems_test_assert (status == 0);
0275 
0276   /*
0277    * Fill a file with data
0278    */
0279   fd = open (name01, O_WRONLY);
0280   rtems_test_assert (fd >= 0);
0281   n = write (fd, databuf, len);
0282   rtems_test_assert (n == len);
0283   status = close (fd);
0284   rtems_test_assert (status == 0);
0285 
0286   /*
0287    * Truncate it to the half size
0288    */
0289 
0290   status = truncate (name01, len / 2);
0291   rtems_test_assert (status == 0);
0292   status = truncate (name01, len);
0293   rtems_test_assert (status == 0);
0294 
0295   /*
0296    * verify the data
0297    */
0298   readbuf = (char *) malloc (len / 2);
0299   rtems_test_assert (readbuf);
0300   fd = open (name01, O_RDONLY);
0301   rtems_test_assert (fd >= 0);
0302   n = read (fd, readbuf, len / 2);
0303   rtems_test_assert (n == len / 2);
0304   rtems_test_assert (!strncmp (databuf, readbuf, len / 2));
0305   n = read (fd, readbuf, len / 2);
0306   rtems_test_assert (n == len / 2);
0307   for (i = 0; i < len / 2; i++) {
0308     rtems_test_assert (readbuf[i] == 0);
0309   }
0310   status = close (fd);
0311   rtems_test_assert (status == 0);
0312 
0313   /*
0314    * Go back to parent directory
0315    */
0316   status = chdir ("..");
0317   rtems_test_assert (status == 0);
0318 
0319   free(readbuf);
0320 }
0321 
0322 static void
0323 lseek_test (void)
0324 {
0325   int fd;
0326   int status;
0327   const char *name01 = "test_name01";
0328   struct stat statbuf;
0329 
0330   ssize_t n;
0331   int i;
0332 
0333   off_t pos;
0334   ssize_t total_written = 0;
0335 
0336   char *readbuf;
0337 
0338   test_case_enter (__func__);
0339 
0340   /*
0341    * Create a file and fill with the data.
0342    */
0343   puts ("Create a new file");
0344   fd = creat (name01, mode);
0345   rtems_test_assert (fd >= 0);
0346 
0347   pos = lseek (fd, 0, SEEK_CUR);
0348   rtems_test_assert (pos == 0);
0349 
0350   pos = lseek (fd, 0, SEEK_END);
0351   rtems_test_assert (pos == 0);
0352 
0353   pos = lseek (fd, 0, SEEK_SET);
0354   rtems_test_assert (pos == 0);
0355 
0356 
0357   printf ("Writing %zd bytes to file\n", len * 10);
0358   for (i = 0; i < 10; i++) {
0359     n = write (fd, databuf, len);
0360     rtems_test_assert (n == (ssize_t) len);
0361     total_written += n;
0362   }
0363   printf ("Successfully wrote %zd\n", total_written);
0364 
0365   /*
0366    * Check the current position
0367    */
0368   puts ("Check the current position");
0369   pos = lseek (fd, 0, SEEK_CUR);
0370   rtems_test_assert (pos == total_written);
0371 
0372   pos = lseek (fd, 0, SEEK_END);
0373   rtems_test_assert (pos == total_written);
0374 
0375   /*
0376    * ftruncate shall not change the posistion
0377    */
0378   status = ftruncate (fd, total_written + 1);
0379   rtems_test_assert (status == 0);
0380 
0381   pos = lseek (fd, 0, SEEK_CUR);
0382   rtems_test_assert (pos == total_written);
0383 
0384   pos = lseek (fd, 0, SEEK_END);
0385   printf ("%jd\n", (intmax_t) pos);
0386   rtems_test_assert (pos == total_written + 1);
0387 
0388   status = ftruncate (fd, total_written);
0389   rtems_test_assert (status == 0);
0390 
0391   pos = lseek (fd, 0, SEEK_CUR);
0392   rtems_test_assert (pos == total_written + 1);
0393 
0394   /*
0395    * Check the file size
0396    */
0397   status = fstat (fd, &statbuf);
0398   rtems_test_assert (status == 0);
0399   rtems_test_assert (statbuf.st_size == total_written);
0400 
0401   status = ftruncate (fd, total_written);
0402   rtems_test_assert (status == 0);
0403 
0404   status = close (fd);
0405   rtems_test_assert (status == 0);
0406 
0407   /*
0408    * Open the file with O_RDONLY and check the lseek
0409    */
0410   readbuf = (char *) malloc (len);
0411   fd = open (name01, O_RDONLY);
0412   pos = lseek (fd, len, SEEK_CUR);
0413   rtems_test_assert (pos == len);
0414   n = read (fd, readbuf, len);
0415   rtems_test_assert (n == len);
0416   rtems_test_assert (!strncmp (databuf, readbuf, len));
0417 
0418   pos = lseek (fd, len, SEEK_CUR);
0419   rtems_test_assert (pos == 3 * len);
0420   n = read (fd, readbuf, len);
0421   rtems_test_assert (n == len);
0422   rtems_test_assert (!strncmp (databuf, readbuf, len));
0423 
0424   pos = lseek (fd, -(off_t) len, SEEK_CUR);
0425   rtems_test_assert (pos == 3 * len);
0426   n = read (fd, readbuf, len);
0427   rtems_test_assert (n == len);
0428   rtems_test_assert (!strncmp (databuf, readbuf, len));
0429 
0430   pos = lseek (fd, 4 * len, SEEK_SET);
0431   n = read (fd, readbuf, len);
0432   rtems_test_assert (n == len);
0433   rtems_test_assert (!strncmp (databuf, readbuf, len));
0434 
0435 
0436   pos = lseek (fd, 10, SEEK_SET);
0437   n = read (fd, readbuf, len);
0438   rtems_test_assert (n == len);
0439   rtems_test_assert (strncmp (databuf, readbuf, len) != 0);
0440 
0441   pos = lseek (fd, -(off_t) len, SEEK_END);
0442   n = read (fd, readbuf, 2 * len);
0443   rtems_test_assert (n == len);
0444   rtems_test_assert (!strncmp (databuf, readbuf, len));
0445 
0446   status = close (fd);
0447   rtems_test_assert (status == 0);
0448 
0449   /*
0450    * Open the file withe O_RDWR and check the lseek
0451    */
0452 
0453   fd = open (name01, O_RDWR);
0454 
0455   pos = lseek (fd, len, SEEK_CUR);
0456   rtems_test_assert (pos == len);
0457   n = read (fd, readbuf, len);
0458   rtems_test_assert (n == len);
0459   rtems_test_assert (!strncmp (databuf, readbuf, len));
0460 
0461   pos = lseek (fd, len, SEEK_CUR);
0462   rtems_test_assert (pos == 3 * len);
0463   n = read (fd, readbuf, len);
0464   rtems_test_assert (n == len);
0465   rtems_test_assert (!strncmp (databuf, readbuf, len));
0466 
0467   pos = lseek (fd, -(off_t) len, SEEK_CUR);
0468   rtems_test_assert (pos == 3 * len);
0469   n = read (fd, readbuf, len);
0470   rtems_test_assert (n == len);
0471   rtems_test_assert (!strncmp (databuf, readbuf, len));
0472 
0473   pos = lseek (fd, 4 * len, SEEK_SET);
0474   n = read (fd, readbuf, len);
0475   rtems_test_assert (n == len);
0476   rtems_test_assert (!strncmp (databuf, readbuf, len));
0477 
0478   /*
0479    * Go to the wrong position, so the data is not the same
0480    */
0481   pos = lseek (fd, 10, SEEK_SET);
0482   n = read (fd, readbuf, len);
0483   rtems_test_assert (n == len);
0484   rtems_test_assert (strncmp (databuf, readbuf, len) != 0);
0485 
0486   /*
0487    * Use SEEK_END
0488    */
0489   pos = lseek (fd, -(off_t) len, SEEK_END);
0490   n = read (fd, readbuf, 2 * len);
0491   rtems_test_assert (n == len);
0492   rtems_test_assert (!strncmp (databuf, readbuf, len));
0493 
0494   memset (readbuf, 0, len);
0495 
0496   /*
0497    * Write the zero to the end of file.
0498    */
0499   pos = lseek (fd, -(off_t) len, SEEK_END);
0500   rtems_test_assert (pos == (off_t) total_written - (off_t) len);
0501   n = write (fd, readbuf, len);
0502   rtems_test_assert (n == len);
0503   /*
0504    * Verify it
0505    */
0506   pos = lseek (fd, (off_t) total_written - (off_t) len, SEEK_SET);
0507   n = read (fd, readbuf, len);
0508   rtems_test_assert (n == len);
0509   for (i = 0; i < n; i++) {
0510     rtems_test_assert (readbuf[i] == 0);
0511   }
0512 
0513   /*
0514    * Write the zero to the beginning of file.
0515    */
0516   pos = lseek (fd, -(off_t) total_written, SEEK_END);
0517   rtems_test_assert (pos == 0);
0518   n = write (fd, readbuf, len);
0519   rtems_test_assert (n == len);
0520 
0521   /*
0522    * Verify it
0523    */
0524 
0525   pos = lseek (fd, 0, SEEK_SET);
0526   n = read (fd, readbuf, len);
0527   rtems_test_assert (n == len);
0528   for (i = 0; i < n; i++) {
0529     rtems_test_assert (readbuf[i] == 0);
0530   }
0531 
0532   n = read (fd, readbuf, len);
0533   rtems_test_assert (n == len);
0534   rtems_test_assert (strncmp (databuf, readbuf, len) == 0);
0535   /*
0536    * Call ftruncate to decrease the file and the position not change
0537    */
0538   status = ftruncate (fd, len);
0539   rtems_test_assert (status == 0);
0540   pos = lseek (fd, 0, SEEK_CUR);
0541   rtems_test_assert (pos == len * 2);
0542 
0543   status = close (fd);
0544   rtems_test_assert (status == 0);
0545 
0546   test_case_leave ();
0547 
0548   free(readbuf);
0549 }
0550 
0551 static void
0552 truncate_to_zero (void)
0553 {
0554   int fd;
0555   ssize_t n;
0556   int status;
0557   off_t pos;
0558 
0559   test_case_enter (__func__);
0560 
0561   fd = creat ("file", mode);
0562   rtems_test_assert (fd >= 0);
0563 
0564   n = write (fd, databuf, len);
0565   rtems_test_assert (n == (ssize_t) len);
0566 
0567   pos = lseek (fd, 0, SEEK_END);
0568   rtems_test_assert (pos == len);
0569 
0570   status = ftruncate (fd, 0);
0571   rtems_test_assert (status == 0);
0572 
0573   pos = lseek (fd, 0, SEEK_END);
0574   rtems_test_assert (pos == 0);
0575 
0576   status = close (fd);
0577   rtems_test_assert (status == 0);
0578 
0579   test_case_leave ();
0580 }
0581 
0582 static void
0583 random_fill (char *dst, size_t n)
0584 {
0585   static uint32_t u = 0x12345678;
0586   uint32_t v = u;
0587   uint32_t w = u;
0588   size_t i = 0;
0589   int j = 0;
0590 
0591   while (i < n) {
0592     if (j == 0) {
0593       v *= 1664525;
0594       v += 1013904223;
0595       w = v;
0596     } else {
0597       w >>= 8;
0598     }
0599 
0600     dst [i] = (char) w;
0601 
0602     ++i;
0603     j = (j + 1) % 4;
0604   }
0605 
0606   u = v;
0607 }
0608 
0609 static void
0610 block_rw_lseek (int fd, size_t pos)
0611 {
0612   off_t actual;
0613 
0614   actual = lseek (fd, pos, SEEK_SET);
0615   rtems_test_assert (actual == pos);
0616 }
0617 
0618 static void
0619 block_rw_write (int fd, char *out, size_t pos, size_t size)
0620 {
0621   ssize_t n;
0622 
0623   random_fill (out + pos, size);
0624 
0625   block_rw_lseek (fd, pos);
0626 
0627   n = write (fd, out + pos, size);
0628   rtems_test_assert (n == (ssize_t) size);
0629 }
0630 
0631 static void
0632 block_rw_write_cont (int fd, char *out, size_t *pos, size_t size)
0633 {
0634   ssize_t n;
0635 
0636   random_fill (out + *pos, size);
0637 
0638   n = write (fd, out + *pos, size);
0639   rtems_test_assert (n == (ssize_t) size);
0640 
0641   *pos += size;
0642 }
0643 
0644 static void
0645 block_rw_check (int fd, const char *out, char *in, size_t size)
0646 {
0647   ssize_t n;
0648   off_t file_size;
0649 
0650   file_size = lseek (fd, 0, SEEK_END);
0651   rtems_test_assert (file_size == size);
0652 
0653   block_rw_lseek (fd, 0);
0654 
0655   n = read (fd, in, size);
0656   rtems_test_assert (n == (ssize_t) size);
0657 
0658   rtems_test_assert (memcmp (out, in, size) == 0);
0659 }
0660 
0661 static void
0662 block_rw_prepare (const char *t, int fd, char *out, size_t size)
0663 {
0664   int status;
0665 
0666   printf ("test case: %s\n", t);
0667 
0668   memset (out, 0, size);
0669 
0670   status = ftruncate (fd, 0);
0671   rtems_test_assert (status == 0);
0672 
0673   block_rw_lseek (fd, 0);
0674 }
0675 
0676 static void
0677 block_rw_case_0 (int fd, size_t block_size, char *out, char *in)
0678 {
0679   const size_t size = 3 * block_size + 1;
0680 
0681   block_rw_prepare (__func__, fd, out, size);
0682   block_rw_write (fd, out, 0, size);
0683   block_rw_check (fd, out, in, size);
0684 }
0685 
0686 static void
0687 block_rw_case_1 (int fd, size_t block_size, char *out, char *in)
0688 {
0689   const size_t size = 2 * block_size;
0690 
0691   block_rw_prepare (__func__, fd, out, size);
0692   block_rw_write (fd, out, block_size, block_size);
0693   block_rw_check (fd, out, in, size);
0694 }
0695 
0696 static void
0697 block_rw_case_2 (int fd, size_t block_size, char *out, char *in)
0698 {
0699   const size_t size = (5 * block_size) / 2;
0700 
0701   block_rw_prepare (__func__, fd, out, size);
0702   block_rw_write (fd, out, (3 * block_size) / 2, block_size);
0703   block_rw_check (fd, out, in, size);
0704 }
0705 
0706 static void
0707 block_rw_case_3 (int fd, size_t block_size, char *out, char *in)
0708 {
0709   const size_t size = 2 * block_size;
0710 
0711   block_rw_prepare (__func__, fd, out, size);
0712   block_rw_write (fd, out, block_size, block_size / 3);
0713   block_rw_write (fd, out, 2 * block_size - block_size / 3, block_size / 3);
0714   block_rw_check (fd, out, in, size);
0715 }
0716 
0717 static void
0718 block_rw_case_4 (int fd, size_t block_size, char *out, char *in)
0719 {
0720   const size_t size = 3 * block_size + 1;
0721   size_t pos = 0;
0722 
0723   block_rw_prepare (__func__, fd, out, size);
0724   block_rw_write_cont (fd, out, &pos, block_size);
0725   block_rw_write_cont (fd, out, &pos, block_size / 2);
0726   block_rw_write_cont (fd, out, &pos, block_size);
0727   block_rw_write_cont (fd, out, &pos, block_size / 2);
0728   block_rw_write_cont (fd, out, &pos, 1);
0729   block_rw_check (fd, out, in, size);
0730 }
0731 
0732 static void
0733 block_read_and_write (void)
0734 {
0735   int fd;
0736   struct stat st;
0737   int status;
0738   size_t block_size;
0739   size_t size;
0740   char *out;
0741   char *in;
0742 
0743   test_case_enter (__func__);
0744 
0745   fd = open ("file", O_RDWR | O_CREAT | O_TRUNC, mode);
0746   rtems_test_assert (fd >= 0);
0747 
0748   status = fstat (fd, &st);
0749   rtems_test_assert (status == 0);
0750 
0751   block_size = st.st_blksize;
0752   size = 3 * block_size + 1;
0753 
0754   out = malloc (size);
0755   rtems_test_assert (out != NULL);
0756 
0757   in = malloc (size);
0758   rtems_test_assert (in != NULL);
0759 
0760   block_rw_case_0 (fd, block_size, out, in);
0761   block_rw_case_1 (fd, block_size, out, in);
0762   block_rw_case_2 (fd, block_size, out, in);
0763   block_rw_case_3 (fd, block_size, out, in);
0764   block_rw_case_4 (fd, block_size, out, in);
0765 
0766   status = close (fd);
0767   rtems_test_assert (status == 0);
0768 
0769   free (out);
0770   free (in);
0771 
0772   test_case_leave ();
0773 }
0774 
0775 static void
0776 write_until_no_space_is_left (void)
0777 {
0778   static const char file [] = "zero";
0779   int fd;
0780   struct stat st;
0781   int status;
0782   blksize_t block_size;
0783   char *out;
0784   ssize_t chunk_size;
0785   ssize_t written;
0786   off_t total;
0787 
0788   /* Use the root directory to account for some FAT12 or FAT16 specialities */
0789   printf ("test case: %s\n", __func__);
0790 
0791   fd = open (file, O_RDWR | O_CREAT | O_TRUNC, mode);
0792   rtems_test_assert (fd >= 0);
0793 
0794   status = fstat (fd, &st);
0795   rtems_test_assert (status == 0);
0796   rtems_test_assert (st.st_size == 0);
0797   rtems_test_assert (st.st_blksize > 0);
0798   block_size = st.st_blksize;
0799 
0800   out = calloc (1, block_size);
0801   rtems_test_assert (out != NULL);
0802 
0803   total = 0;
0804   chunk_size = block_size / 2;
0805   do {
0806     errno = 0;
0807 
0808     written = write (fd, out, chunk_size);
0809     if (written > 0) {
0810       total += written;
0811     }
0812 
0813     chunk_size = block_size;
0814   } while (written > 0);
0815 
0816   rtems_test_assert (written == -1);
0817   rtems_test_assert (errno == ENOSPC || errno == EFBIG);
0818 
0819   status = close (fd);
0820   rtems_test_assert (status == 0);
0821 
0822   /* Do not use fstat() to do the path evaluation again */
0823   status = lstat (file, &st);
0824   rtems_test_assert (status == 0);
0825   rtems_test_assert (st.st_size == total);
0826 
0827   free (out);
0828 }
0829 
0830 void
0831 test (void)
0832 {
0833   read_write_test ();
0834   lseek_test ();
0835   truncate_test03 ();
0836   truncate_to_zero ();
0837   block_read_and_write ();
0838   write_until_no_space_is_left ();
0839 }