LCOV - code coverage report
Current view: top level - cmdline - mktest.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 221 237 93.2 %
Date: 2025-10-28 11:59:11 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2011 Andrea Mazzoleni
       3             :  *
       4             :  * This program is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 3 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "portable.h"
      19             : 
      20             : #include "support.h"
      21             : 
      22             : volatile int global_interrupt = 0;
      23             : 
      24             : /****************************************************************************/
      25             : /* random */
      26             : 
      27             : /**
      28             :  * Pseudo random number generator.
      29             :  */
      30             : unsigned long long seed = 0;
      31             : 
      32    56065885 : unsigned rnd(unsigned max)
      33             : {
      34    56065885 :         seed = seed * 6364136223846793005LL + 1442695040888963407LL;
      35             : 
      36    56065885 :         return (seed >> 32) % max;
      37             : }
      38             : 
      39    55654613 : unsigned rndnz(unsigned max)
      40             : {
      41    55654613 :         if (max <= 1)
      42        2831 :                 return 1;
      43             :         else
      44    55651782 :                 return rnd(max - 1) + 1;
      45             : }
      46             : 
      47       32703 : void rndnz_range(unsigned char* data, int size)
      48             : {
      49             :         int i;
      50             : 
      51    55680550 :         for (i = 0; i < size; ++i)
      52    55647847 :                 data[i] = rndnz(256);
      53       32703 : }
      54             : 
      55        1821 : void rndnz_damage(unsigned char* data, int size)
      56             : {
      57             :         int i;
      58             : 
      59             :         /* corrupt ensuring always different data */
      60        3642 :         for (i = 0; i < size; ++i) {
      61             :                 unsigned char c;
      62             : 
      63             :                 do {
      64        1835 :                         c = rndnz(256);
      65        1835 :                 } while (c == data[i]);
      66             : 
      67        1821 :                 data[i] = c;
      68             :         }
      69        1821 : }
      70             : 
      71             : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+";
      72             : #define CHARSET_LEN (sizeof(CHARSET) - 1)
      73             : 
      74       26839 : void rnd_name(char* file)
      75             : {
      76       26839 :         int l = 1 + rnd(20);
      77             : 
      78      308569 :         while (l) {
      79      281730 :                 *file++ = CHARSET[rnd(CHARSET_LEN)];
      80      281730 :                 --l;
      81             :         }
      82       26839 :         *file = 0;
      83       26839 : }
      84             : 
      85             : /****************************************************************************/
      86             : /* file */
      87             : 
      88      146710 : int file_cmp(const void* a, const void* b)
      89             : {
      90      146710 :         return strcmp(a, b);
      91             : }
      92             : 
      93        1821 : int fallback(int f, struct stat* st)
      94             : {
      95             : #if HAVE_FUTIMENS
      96             :         struct timespec tv[2];
      97             : #else
      98             :         struct timeval tv[2];
      99             : #endif
     100             :         int ret;
     101             : 
     102             : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
     103        1821 :         tv[0].tv_sec = st->st_mtime;
     104        1821 :         if (STAT_NSEC(st) != STAT_NSEC_INVALID)
     105        1821 :                 tv[0].tv_nsec = STAT_NSEC(st);
     106             :         else
     107           0 :                 tv[0].tv_nsec = 0;
     108        1821 :         tv[1].tv_sec = tv[0].tv_sec;
     109        1821 :         tv[1].tv_nsec = tv[0].tv_nsec;
     110             : 
     111        1821 :         ret = futimens(f, tv);
     112             : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
     113             :         tv[0].tv_sec = st->st_mtime;
     114             :         if (STAT_NSEC(st) != STAT_NSEC_INVALID)
     115             :                 tv[0].tv_usec = STAT_NSEC(st) / 1000;
     116             :         else
     117             :                 tv[0].tv_usec = 0;
     118             :         tv[1].tv_sec = tv[0].tv_sec;
     119             :         tv[1].tv_usec = tv[0].tv_usec;
     120             : 
     121             :         ret = futimes(f, tv);
     122             : #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
     123             :         tv[0].tv_sec = st->st_mtime;
     124             :         if (STAT_NSEC(st) != STAT_NSEC_INVALID)
     125             :                 tv[0].tv_usec = STAT_NSEC(st) / 1000;
     126             :         else
     127             :                 tv[0].tv_usec = 0;
     128             :         tv[1].tv_sec = tv[0].tv_sec;
     129             :         tv[1].tv_usec = tv[0].tv_usec;
     130             : 
     131             :         ret = futimesat(f, 0, tv);
     132             : #else
     133             : #error No function available to set file timestamps
     134             : #endif
     135        1821 :         return ret;
     136             : }
     137             : 
     138             : /****************************************************************************/
     139             : /* cmd */
     140             : 
     141             : /**
     142             :  * Create a file with random content.
     143             :  * - If the file exists it's rewritten, but avoiding to truncating it to 0.
     144             :  */
     145       23267 : void cmd_generate_file(const char* path, int size)
     146             : {
     147             :         unsigned char* data;
     148             :         int f;
     149             : 
     150             :         /* remove the existing file/symlink if any */
     151       23267 :         if (remove(path) != 0) {
     152       22446 :                 if (errno != ENOENT) {
     153             :                         /* LCOV_EXCL_START */
     154             :                         log_fatal("Error removing file %s\n", path);
     155             :                         exit(EXIT_FAILURE);
     156             :                         /* LCOV_EXCL_STOP */
     157             :                 }
     158             :         } else {
     159             :                 /* don't truncate files to 0 size to avoid ZERO file size protection */
     160         821 :                 ++size;
     161             :         }
     162             : 
     163       23267 :         data = malloc(size);
     164             : 
     165             :         /* We don't write zero bytes because we want to test */
     166             :         /* the recovering of new files, after an aborted sync */
     167             :         /* If the files contains full blocks at zero */
     168             :         /* this is an impossible condition to recover */
     169             :         /* because we cannot differentiate between an unused block */
     170             :         /* and a file filled with 0 */
     171       23267 :         rndnz_range(data, size);
     172             : 
     173       23267 :         f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
     174       23267 :         if (f < 0) {
     175             :                 /* LCOV_EXCL_START */
     176             :                 log_fatal("Error creating file %s\n", path);
     177             :                 exit(EXIT_FAILURE);
     178             :                 /* LCOV_EXCL_STOP */
     179             :         }
     180             : 
     181       23267 :         if (write(f, data, size) != size) {
     182             :                 /* LCOV_EXCL_START */
     183             :                 log_fatal("Error writing file %s\n", path);
     184             :                 exit(EXIT_FAILURE);
     185             :                 /* LCOV_EXCL_STOP */
     186             :         }
     187             : 
     188       23267 :         if (close(f) != 0) {
     189             :                 /* LCOV_EXCL_START */
     190             :                 log_fatal("Error closing file %s\n", path);
     191             :                 exit(EXIT_FAILURE);
     192             :                 /* LCOV_EXCL_STOP */
     193             :         }
     194             : 
     195       23267 :         free(data);
     196       23267 : }
     197             : 
     198             : /**
     199             :  * Create a symlink.
     200             :  * - If the file already exists, it's removed.
     201             :  */
     202         930 : void cmd_generate_symlink(const char* path, const char* linkto)
     203             : {
     204             :         /* remove the existing file/symlink if any */
     205         930 :         if (remove(path) != 0) {
     206         909 :                 if (errno != ENOENT) {
     207             :                         /* LCOV_EXCL_START */
     208             :                         log_fatal("Error removing file %s\n", path);
     209             :                         exit(EXIT_FAILURE);
     210             :                         /* LCOV_EXCL_STOP */
     211             :                 }
     212             :         }
     213             : 
     214         930 :         if (symlink(linkto, path) != 0) {
     215             :                 /* LCOV_EXCL_START */
     216             :                 log_fatal("Error writing symlink %s\n", path);
     217             :                 exit(EXIT_FAILURE);
     218             :                 /* LCOV_EXCL_STOP */
     219             :         }
     220         930 : }
     221             : 
     222             : /**
     223             :  * Create a file or a symlink with a random name.
     224             :  */
     225       24000 : void cmd_generate(int disk, int size)
     226             : {
     227             :         char path[PATH_MAX];
     228             :         char* file;
     229             : 
     230       24000 :         snprintf(path, sizeof(path), "bench/disk%d/", disk);
     231       24000 :         file = path + strlen(path);
     232             : 
     233             :         /* add a directory */
     234       24000 :         *file++ = 'a' + rnd(2);
     235       24000 :         *file = 0;
     236             : 
     237             :         /* create it */
     238       24000 :         if (mkdir(path, 0777) != 0) {
     239       23988 :                 if (errno != EEXIST) {
     240             :                         /* LCOV_EXCL_START */
     241             :                         log_fatal("Error creating directory %s\n", path);
     242             :                         exit(EXIT_FAILURE);
     243             :                         /* LCOV_EXCL_STOP */
     244             :                 }
     245             :         }
     246             : 
     247       24000 :         *file++ = '/';
     248             : 
     249             :         while (1) {
     250             :                 /* add a random file */
     251       25909 :                 rnd_name(file);
     252             : 
     253             :                 /* skip some invalid file name, see http://en.wikipedia.org/wiki/Filename */
     254       25909 :                 if (strcmp(file, ".") == 0
     255       25874 :                         || strcmp(file, "..") == 0
     256       25874 :                         || strcmp(file, "prn") == 0
     257       25874 :                         || strcmp(file, "con") == 0
     258       25873 :                         || strcmp(file, "nul") == 0
     259       25873 :                         || strcmp(file, "aux") == 0
     260       25873 :                         || file[0] == ' '
     261       25199 :                         || file[strlen(file) - 1] == ' '
     262       24608 :                         || file[strlen(file) - 1] == '.'
     263             :                 ) {
     264        1909 :                         continue;
     265             :                 }
     266             : 
     267       24000 :                 break;
     268             :         }
     269             : 
     270             : #ifndef WIN32 /* Windows XP doesn't support symlinks */
     271       24000 :         if (rnd(32) == 0) {
     272             :                 /* symlink */
     273             :                 char linkto[PATH_MAX];
     274             : 
     275         733 :                 rnd_name(linkto);
     276             : 
     277         733 :                 cmd_generate_symlink(path, linkto);
     278             :         } else
     279             : #endif
     280             :         {
     281             :                 /* file */
     282       23267 :                 cmd_generate_file(path, size);
     283             :         }
     284       24000 : }
     285             : 
     286             : /**
     287             :  * Write a partially a file.
     288             :  * - The file must exist.
     289             :  * - The file size is not changed.
     290             :  * - The written data may be equal or not at the already existing one.
     291             :  * - If it's a symlink nothing is done.
     292             :  */
     293        6264 : void cmd_write(const char* path, int size)
     294             : {
     295             :         struct stat st;
     296             : 
     297        6264 :         if (lstat(path, &st) != 0) {
     298             :                 /* LCOV_EXCL_START */
     299             :                 log_fatal("Error accessing %s\n", path);
     300             :                 exit(EXIT_FAILURE);
     301             :                 /* LCOV_EXCL_STOP */
     302             :         }
     303             : 
     304        6264 :         if (S_ISREG(st.st_mode)) {
     305             :                 unsigned char* data;
     306             :                 off_t off;
     307             :                 int f;
     308             : 
     309             :                 /* not over the end */
     310        6237 :                 if (size > st.st_size)
     311         704 :                         size = st.st_size;
     312             : 
     313             :                 /* start at random position inside the file */
     314        6237 :                 if (size < st.st_size)
     315        5532 :                         off = rnd(st.st_size - size);
     316             :                 else
     317         705 :                         off = 0;
     318             : 
     319        6237 :                 data = malloc(size);
     320             : 
     321        6237 :                 rndnz_range(data, size);
     322             : 
     323        6237 :                 f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
     324        6237 :                 if (f < 0) {
     325             :                         /* LCOV_EXCL_START */
     326             :                         log_fatal("Error creating file %s\n", path);
     327             :                         exit(EXIT_FAILURE);
     328             :                         /* LCOV_EXCL_STOP */
     329             :                 }
     330             : 
     331        6237 :                 if (lseek(f, off, SEEK_SET) != off) {
     332             :                         /* LCOV_EXCL_START */
     333             :                         log_fatal("Error seeking file %s\n", path);
     334             :                         exit(EXIT_FAILURE);
     335             :                         /* LCOV_EXCL_STOP */
     336             :                 }
     337             : 
     338        6237 :                 if (write(f, data, size) != size) {
     339             :                         /* LCOV_EXCL_START */
     340             :                         log_fatal("Error writing file %s\n", path);
     341             :                         exit(EXIT_FAILURE);
     342             :                         /* LCOV_EXCL_STOP */
     343             :                 }
     344             : 
     345        6237 :                 if (close(f) != 0) {
     346             :                         /* LCOV_EXCL_START */
     347             :                         log_fatal("Error closing file %s\n", path);
     348             :                         exit(EXIT_FAILURE);
     349             :                         /* LCOV_EXCL_STOP */
     350             :                 }
     351             : 
     352        6237 :                 free(data);
     353             :         }
     354        6264 : }
     355             : 
     356             : /**
     357             :  * Damage a file.
     358             :  * - The file must exist.
     359             :  * - The file size is not changed.
     360             :  * - The written data is SURELY different than the already existing one.
     361             :  * - The file timestamp is NOT modified.
     362             :  * - If it's a symlink nothing is done.
     363             :  */
     364        1882 : void cmd_damage(const char* path, int size)
     365             : {
     366             :         struct stat st;
     367             : 
     368             :         /* here a 0 size means to change nothing */
     369             :         /* as also the timestamp should not be changed */
     370        1882 :         if (!size)
     371           3 :                 return;
     372             : 
     373        1882 :         if (lstat(path, &st) != 0) {
     374             :                 /* LCOV_EXCL_START */
     375             :                 log_fatal("Error accessing %s\n", path);
     376             :                 exit(EXIT_FAILURE);
     377             :                 /* LCOV_EXCL_STOP */
     378             :         }
     379             : 
     380        1882 :         if (st.st_size == 0)
     381           3 :                 return;
     382             : 
     383        1879 :         if (S_ISREG(st.st_mode)) {
     384             :                 off_t off;
     385             :                 unsigned char* data;
     386             :                 int f;
     387             : 
     388             :                 /* not over the end */
     389        1821 :                 if (size > st.st_size)
     390           0 :                         size = st.st_size;
     391             : 
     392             :                 /* start at random position inside the file */
     393        1821 :                 if (size < st.st_size)
     394        1820 :                         off = rnd(st.st_size - size);
     395             :                 else
     396           1 :                         off = 0;
     397             : 
     398        1821 :                 data = malloc(size);
     399             : 
     400        1821 :                 f = open(path, O_RDWR | O_BINARY | O_NOFOLLOW);
     401        1821 :                 if (f < 0) {
     402             :                         /* LCOV_EXCL_START */
     403             :                         log_fatal("Error creating file %s\n", path);
     404             :                         exit(EXIT_FAILURE);
     405             :                         /* LCOV_EXCL_STOP */
     406             :                 }
     407             : 
     408        1821 :                 if (lseek(f, off, SEEK_SET) != off) {
     409             :                         /* LCOV_EXCL_START */
     410             :                         log_fatal("Error seeking file %s\n", path);
     411             :                         exit(EXIT_FAILURE);
     412             :                         /* LCOV_EXCL_STOP */
     413             :                 }
     414             : 
     415        1821 :                 if (read(f, data, size) != size) {
     416             :                         /* LCOV_EXCL_START */
     417             :                         log_fatal("Error writing file %s\n", path);
     418             :                         exit(EXIT_FAILURE);
     419             :                         /* LCOV_EXCL_STOP */
     420             :                 }
     421             : 
     422        1821 :                 rndnz_damage(data, size);
     423             : 
     424        1821 :                 if (lseek(f, off, SEEK_SET) != off) {
     425             :                         /* LCOV_EXCL_START */
     426             :                         log_fatal("Error seeking file %s\n", path);
     427             :                         exit(EXIT_FAILURE);
     428             :                         /* LCOV_EXCL_STOP */
     429             :                 }
     430             : 
     431        1821 :                 if (write(f, data, size) != size) {
     432             :                         /* LCOV_EXCL_START */
     433             :                         log_fatal("Error writing file %s\n", path);
     434             :                         exit(EXIT_FAILURE);
     435             :                         /* LCOV_EXCL_STOP */
     436             :                 }
     437             : 
     438        1821 :                 if (fallback(f, &st) != 0) {
     439             :                         /* LCOV_EXCL_START */
     440             :                         log_fatal("Error setting time for file %s\n", path);
     441             :                         exit(EXIT_FAILURE);
     442             :                         /* LCOV_EXCL_STOP */
     443             :                 }
     444             : 
     445        1821 :                 if (close(f) != 0) {
     446             :                         /* LCOV_EXCL_START */
     447             :                         log_fatal("Error closing file %s\n", path);
     448             :                         exit(EXIT_FAILURE);
     449             :                         /* LCOV_EXCL_STOP */
     450             :                 }
     451             : 
     452        1821 :                 free(data);
     453             :         }
     454             : }
     455             : 
     456             : /**
     457             :  * Append to a file.
     458             :  * - The file must exist.
     459             :  * - If it's a symlink nothing is done.
     460             :  */
     461        3199 : void cmd_append(const char* path, int size)
     462             : {
     463             :         struct stat st;
     464             : 
     465        3199 :         if (lstat(path, &st) != 0) {
     466             :                 /* LCOV_EXCL_START */
     467             :                 log_fatal("Error accessing %s\n", path);
     468             :                 exit(EXIT_FAILURE);
     469             :                 /* LCOV_EXCL_STOP */
     470             :         }
     471             : 
     472        3199 :         if (S_ISREG(st.st_mode)) {
     473             :                 unsigned char* data;
     474             :                 int f;
     475             : 
     476        3199 :                 data = malloc(size);
     477             : 
     478        3199 :                 rndnz_range(data, size);
     479             : 
     480        3199 :                 f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
     481        3199 :                 if (f < 0) {
     482             :                         /* LCOV_EXCL_START */
     483             :                         log_fatal("Error opening file %s\n", path);
     484             :                         exit(EXIT_FAILURE);
     485             :                         /* LCOV_EXCL_STOP */
     486             :                 }
     487             : 
     488        3199 :                 if (write(f, data, size) != size) {
     489             :                         /* LCOV_EXCL_START */
     490             :                         log_fatal("Error writing file %s\n", path);
     491             :                         exit(EXIT_FAILURE);
     492             :                         /* LCOV_EXCL_STOP */
     493             :                 }
     494             : 
     495        3199 :                 if (close(f) != 0) {
     496             :                         /* LCOV_EXCL_START */
     497             :                         log_fatal("Error closing file %s\n", path);
     498             :                         exit(EXIT_FAILURE);
     499             :                         /* LCOV_EXCL_STOP */
     500             :                 }
     501             : 
     502        3199 :                 free(data);
     503             :         }
     504        3199 : }
     505             : 
     506             : /**
     507             :  * Truncate a file.
     508             :  * - The file must exist.
     509             :  * - The file is NEVER truncated to 0.
     510             :  * - If it's a symlink nothing is done.
     511             :  */
     512        3153 : void cmd_truncate(const char* path, int size)
     513             : {
     514             :         struct stat st;
     515             : 
     516        3153 :         if (lstat(path, &st) != 0) {
     517             :                 /* LCOV_EXCL_START */
     518             :                 log_fatal("Error accessing %s\n", path);
     519             :                 exit(EXIT_FAILURE);
     520             :                 /* LCOV_EXCL_STOP */
     521             :         }
     522             : 
     523        3153 :         if (S_ISREG(st.st_mode)) {
     524             :                 off_t off;
     525             :                 int f;
     526             : 
     527             :                 /* if file is empty, just rewrite it */
     528        3153 :                 if (st.st_size == 0) {
     529           3 :                         size = 0;
     530             :                 } else {
     531             :                         /* don't truncate files to 0 size to avoid ZERO file size protection */
     532        3150 :                         if (size >= st.st_size)
     533         193 :                                 size = st.st_size - 1;
     534             :                 }
     535             : 
     536        3153 :                 off = st.st_size - size;
     537             : 
     538        3153 :                 f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
     539        3153 :                 if (f < 0) {
     540             :                         /* LCOV_EXCL_START */
     541             :                         log_fatal("Error opening file %s\n", path);
     542             :                         exit(EXIT_FAILURE);
     543             :                         /* LCOV_EXCL_STOP */
     544             :                 }
     545             : 
     546        3153 :                 if (ftruncate(f, off) != 0) {
     547             :                         /* LCOV_EXCL_START */
     548             :                         log_fatal("Error truncating file %s\n", path);
     549             :                         exit(EXIT_FAILURE);
     550             :                         /* LCOV_EXCL_STOP */
     551             :                 }
     552             : 
     553        3153 :                 if (close(f) != 0) {
     554             :                         /* LCOV_EXCL_START */
     555             :                         log_fatal("Error closing file %s\n", path);
     556             :                         exit(EXIT_FAILURE);
     557             :                         /* LCOV_EXCL_STOP */
     558             :                 }
     559             :         }
     560        3153 : }
     561             : 
     562             : /**
     563             :  * Delete a file.
     564             :  * - The file must exist.
     565             :  */
     566        3141 : void cmd_delete(const char* path)
     567             : {
     568        3141 :         if (remove(path) != 0) {
     569             :                 /* LCOV_EXCL_START */
     570             :                 log_fatal("Error removing %s\n", path);
     571             :                 exit(EXIT_FAILURE);
     572             :                 /* LCOV_EXCL_STOP */
     573             :         }
     574        3141 : }
     575             : 
     576             : /**
     577             :  * Change a file. Or deleted/truncated/append/created.
     578             :  * - The file must exist.
     579             :  */
     580       13128 : void cmd_change(const char* path, int size)
     581             : {
     582             :         struct stat st;
     583             : 
     584       13128 :         if (!size)
     585          26 :                 return;
     586             : 
     587       13102 :         if (lstat(path, &st) != 0) {
     588             :                 /* LCOV_EXCL_START */
     589             :                 log_fatal("Error accessing %s\n", path);
     590             :                 exit(EXIT_FAILURE);
     591             :                 /* LCOV_EXCL_STOP */
     592             :         }
     593             : 
     594       13102 :         if (S_ISLNK(st.st_mode)) {
     595             :                 /* symlink */
     596         394 :                 if (rnd(2) == 0) {
     597             :                         /* delete */
     598         197 :                         if (remove(path) != 0) {
     599             :                                 /* LCOV_EXCL_START */
     600             :                                 log_fatal("Error removing %s\n", path);
     601             :                                 exit(EXIT_FAILURE);
     602             :                                 /* LCOV_EXCL_STOP */
     603             :                         }
     604             :                 } else {
     605             :                         /* recreate */
     606             :                         char linkto[PATH_MAX];
     607             : 
     608         197 :                         if (remove(path) != 0) {
     609             :                                 /* LCOV_EXCL_START */
     610             :                                 log_fatal("Error removing %s\n", path);
     611             :                                 exit(EXIT_FAILURE);
     612             :                                 /* LCOV_EXCL_STOP */
     613             :                         }
     614             : 
     615         197 :                         rnd_name(linkto);
     616             : 
     617         197 :                         cmd_generate_symlink(path, linkto);
     618             :                 }
     619       12708 :         } else if (S_ISREG(st.st_mode)) {
     620             :                 int r;
     621             : 
     622       12708 :                 r = rnd(4);
     623             : 
     624       12708 :                 if (r == 0) {
     625        3215 :                         cmd_write(path, size);
     626        9493 :                 } else if (r == 1) {
     627        3199 :                         cmd_append(path, size);
     628        6294 :                 } else if (r == 2) {
     629        3153 :                         cmd_truncate(path, size);
     630             :                 } else {
     631        3141 :                         cmd_delete(path);
     632             :                 }
     633             :         }
     634             : }
     635             : 
     636           1 : void help(void)
     637             : {
     638           1 :         printf("Test for " PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
     639           1 :         printf("Usage:\n");
     640           1 :         printf("\tmktest generate SEED DISK_NUM FILE_NUM FILE_SIZE\n");
     641           1 :         printf("\tmktest damage SEED NUM SIZE FILE\n");
     642           1 :         printf("\tmktest write SEED NUM SIZE FILE\n");
     643           1 :         printf("\tmktest change SEED SIZE FILE\n");
     644           1 :         printf("\tmktest append SEED SIZE FILE\n");
     645           1 :         printf("\tmktest truncate SEED SIZE FILE\n");
     646           1 : }
     647             : 
     648          22 : int main(int argc, char* argv[])
     649             : {
     650             :         int i, j, b;
     651             : 
     652          22 :         lock_init();
     653             : 
     654          22 :         if (argc < 2) {
     655           1 :                 help();
     656           1 :                 exit(EXIT_SUCCESS);
     657             :         }
     658             : 
     659          21 :         if (strcmp(argv[1], "generate") == 0) {
     660             :                 int disk, file, size;
     661             : 
     662           4 :                 if (argc != 6) {
     663             :                         /* LCOV_EXCL_START */
     664             :                         help();
     665             :                         exit(EXIT_FAILURE);
     666             :                         /* LCOV_EXCL_STOP */
     667             :                 }
     668             : 
     669           4 :                 seed = atoi(argv[2]);
     670           4 :                 disk = atoi(argv[3]);
     671           4 :                 file = atoi(argv[4]);
     672           4 :                 size = atoi(argv[5]);
     673             : 
     674          28 :                 for (i = 0; i < disk; ++i) {
     675       24024 :                         for (j = 0; j < file; ++j) {
     676       24000 :                                 if (j == 0)
     677             :                                         /* create at least a big one */
     678          24 :                                         cmd_generate(i + 1, size);
     679       23976 :                                 else if (j == 1)
     680             :                                         /* create at least an empty one */
     681          24 :                                         cmd_generate(i + 1, 0);
     682             :                                 else
     683       23952 :                                         cmd_generate(i + 1, rnd(size));
     684             :                         }
     685             :                 }
     686          17 :         } else if (strcmp(argv[1], "write") == 0) {
     687             :                 int fail, size;
     688             : 
     689           7 :                 if (argc < 6) {
     690             :                         /* LCOV_EXCL_START */
     691             :                         help();
     692             :                         exit(EXIT_FAILURE);
     693             :                         /* LCOV_EXCL_STOP */
     694             :                 }
     695             : 
     696           7 :                 seed = atoi(argv[2]);
     697           7 :                 fail = atoi(argv[3]);
     698           7 :                 size = atoi(argv[4]);
     699           7 :                 b = 5;
     700             : 
     701             :                 /* sort the file names */
     702           7 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     703             : 
     704         977 :                 for (i = b; i < argc; ++i)
     705        4019 :                         for (j = 0; j < fail; ++j)
     706        3049 :                                 cmd_write(argv[i], rndnz(size));
     707          10 :         } else if (strcmp(argv[1], "damage") == 0) {
     708             :                 int fail, size;
     709             : 
     710           3 :                 if (argc < 6) {
     711             :                         /* LCOV_EXCL_START */
     712             :                         help();
     713             :                         exit(EXIT_FAILURE);
     714             :                         /* LCOV_EXCL_STOP */
     715             :                 }
     716             : 
     717           3 :                 seed = atoi(argv[2]);
     718           3 :                 fail = atoi(argv[3]);
     719           3 :                 size = atoi(argv[4]);
     720           3 :                 b = 5;
     721             : 
     722             :                 /* sort the file names */
     723           3 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     724             : 
     725        1885 :                 for (i = b; i < argc; ++i)
     726        3764 :                         for (j = 0; j < fail; ++j)
     727        1882 :                                 cmd_damage(argv[i], rndnz(size)); /* at least one byte */
     728           7 :         } else if (strcmp(argv[1], "append") == 0) {
     729             :                 int size;
     730             : 
     731           0 :                 if (argc < 5) {
     732             :                         /* LCOV_EXCL_START */
     733             :                         help();
     734             :                         exit(EXIT_FAILURE);
     735             :                         /* LCOV_EXCL_STOP */
     736             :                 }
     737             : 
     738           0 :                 seed = atoi(argv[2]);
     739           0 :                 size = atoi(argv[3]);
     740           0 :                 b = 4;
     741             : 
     742             :                 /* sort the file names */
     743           0 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     744             : 
     745           0 :                 for (i = b; i < argc; ++i)
     746           0 :                         cmd_append(argv[i], rndnz(size)); /* at least one byte */
     747           7 :         } else if (strcmp(argv[1], "truncate") == 0) {
     748             :                 int size;
     749             : 
     750           0 :                 if (argc < 5) {
     751             :                         /* LCOV_EXCL_START */
     752             :                         help();
     753             :                         exit(EXIT_FAILURE);
     754             :                         /* LCOV_EXCL_STOP */
     755             :                 }
     756             : 
     757           0 :                 seed = atoi(argv[2]);
     758           0 :                 size = atoi(argv[3]);
     759           0 :                 b = 4;
     760             : 
     761             :                 /* sort the file names */
     762           0 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     763             : 
     764           0 :                 for (i = b; i < argc; ++i)
     765           0 :                         cmd_truncate(argv[i], rnd(size));
     766           7 :         } else if (strcmp(argv[1], "change") == 0) {
     767             :                 int size;
     768             : 
     769           7 :                 if (argc < 5) {
     770             :                         /* LCOV_EXCL_START */
     771             :                         help();
     772             :                         exit(EXIT_FAILURE);
     773             :                         /* LCOV_EXCL_STOP */
     774             :                 }
     775             : 
     776           7 :                 seed = atoi(argv[2]);
     777           7 :                 size = atoi(argv[3]);
     778           7 :                 b = 4;
     779             : 
     780             :                 /* sort the file names */
     781           7 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     782             : 
     783       13135 :                 for (i = b; i < argc; ++i)
     784       13128 :                         cmd_change(argv[i], rnd(size));
     785             :         } else {
     786             :                 /* LCOV_EXCL_START */
     787             :                 help();
     788             :                 exit(EXIT_FAILURE);
     789             :                 /* LCOV_EXCL_STOP */
     790             :         }
     791             : 
     792          21 :         lock_done();
     793             : 
     794          21 :         return 0;
     795             : }
     796             : 

Generated by: LCOV version 1.0