"Fossies" - the Fresh Open Source Software Archive

Member "bonnie++-1.04/bon_file.cpp" (3 Jul 2009, 14893 Bytes) of package /linux/privat/bonnie++_1.04.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "bon_file.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.97_vs_1.97.3.

    1 #ifdef OS2
    2 #define INCL_DOSFILEMGR
    3 #include <os2.h>
    4 #else
    5 #include <dirent.h>
    6 #include <unistd.h>
    7 #endif
    8 #include <string.h>
    9 #include <stdlib.h>
   10 
   11 #include "bon_file.h"
   12 #include "bon_time.h"
   13 
   14 CPCCHAR rand_chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   15 
   16 
   17 COpenTest::COpenTest(int chunk_size, bool use_sync, bool *doExit)
   18  : m_chunk_size(chunk_size)
   19  , m_number(0)
   20  , m_number_directories(1)
   21  , m_max(0)
   22  , m_min(0)
   23  , m_size_range(0)
   24  , m_dirname(NULL)
   25  , m_file_name_buf(NULL)
   26  , m_file_names(NULL)
   27  , m_sync(use_sync)
   28  , m_directoryHandles(NULL)
   29  , m_dirIndex(NULL)
   30  , m_buf(new char[m_chunk_size])
   31  , m_exit(doExit)
   32  , m_sync_dir(true)
   33 {
   34 }
   35 
   36 void COpenTest::random_sort()
   37 {
   38   for(int i = 0; i < m_number; i++)
   39   {
   40     char *tmp = m_file_names[i];
   41     int newind = rand() % m_number;
   42     m_file_names[i] = m_file_names[newind];
   43     m_file_names[newind] = tmp;
   44     if(m_dirIndex)
   45     {
   46       int tmpInd = m_dirIndex[i];
   47       m_dirIndex[i] = m_dirIndex[newind];
   48       m_dirIndex[newind] = tmpInd;
   49     }
   50     if(*m_exit) return;
   51   }
   52 }
   53 
   54 COpenTest::~COpenTest()
   55 {
   56   int i;
   57   if(m_dirname)
   58   {
   59     fprintf(stderr, "Cleaning up test directory after error.\n");
   60     if(m_file_names)
   61     {
   62       for(i = 0; i < m_number; i++)
   63         unlink(m_file_names[i]);
   64     }
   65     if(m_number_directories > 1)
   66     {
   67       char buf[6];
   68       for(i = 0; i < m_number_directories; i++)
   69       {
   70         sprintf(buf, "%05d", i);
   71         if(rmdir(buf))
   72           io_error("rmdir");
   73       }
   74     }
   75     if(chdir("..") || rmdir(m_dirname))
   76       io_error("rmdir");
   77     delete m_dirname;
   78   }
   79   if(m_directoryHandles)
   80   {
   81     for(i = 0; i < m_number_directories; i++)
   82       close(m_directoryHandles[i]);
   83     delete m_directoryHandles;
   84   }
   85   delete m_file_name_buf;
   86   delete m_file_names;
   87   delete m_dirIndex;
   88   delete m_buf;
   89 }
   90 
   91 void COpenTest::make_names(bool do_random)
   92 {
   93   delete m_file_name_buf;
   94   delete m_file_names;
   95   int names_per_directory = m_number / m_number_directories;
   96   int names_in_dir = 0;
   97   int directory_num = 0;
   98   if(!m_dirIndex && m_sync)
   99     m_dirIndex = new int[m_number];
  100   if(m_number_directories == 1)
  101   {
  102     m_file_name_buf = new char[(MaxNameLen + 1) * m_number];
  103   }
  104   else
  105   {
  106     m_file_name_buf = new char[(MaxNameLen + 1 + 6) * m_number];
  107   }
  108   m_file_names = new PCHAR[m_number];
  109   PCHAR buf = m_file_name_buf;
  110   for(int i = 0; i < m_number; i++)
  111   {
  112     if(*m_exit)
  113     {
  114       delete m_file_names;
  115       m_file_names = NULL;
  116       return;
  117     }
  118     char rand_buf[RandExtraLen + 1];
  119     int len = rand() % (RandExtraLen + 1);
  120     int j;
  121     for(j = 0; j < len; j++)
  122     {
  123       rand_buf[j] = rand_chars[rand() % strlen(rand_chars)];
  124     }
  125     rand_buf[j] = '\0';
  126     m_file_names[i] = buf;
  127     if(m_number_directories != 1)
  128     {
  129       sprintf(buf, "%05d/", directory_num);
  130       buf += strlen(buf);
  131     }
  132     if(m_sync)
  133       m_dirIndex[i] = directory_num;
  134     names_in_dir++;
  135     if(names_in_dir > names_per_directory)
  136     {
  137       names_in_dir = 0;
  138       directory_num++;
  139     }
  140     if(do_random)
  141     {
  142       sprintf(buf, "%s%07x", rand_buf, i);
  143     }
  144     else
  145     {
  146       sprintf(buf, "%07x%s", i, rand_buf);
  147     }
  148     buf += strlen(buf) + 1;
  149   }
  150 }
  151 
  152 int COpenTest::create_a_file(const char *filename, char *buf, int size, int dir)
  153 {
  154   FILE_TYPE fd = 0;
  155 #ifdef OS2
  156   ULONG action = 0;
  157   ULONG rc = DosOpen(filename, &fd, &action, 0, FILE_NORMAL
  158                    , OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS
  159                    , OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE
  160                    , NULL);
  161 #else
  162   fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR | S_IWUSR);
  163 #endif
  164   if(fd == -1)
  165   {
  166     fprintf(stderr, "Can't create file %s\n", filename);
  167     return -1;
  168   }
  169   if(m_max)
  170   {
  171     for(int i = 0; i < size; i += m_chunk_size)
  172     {
  173       int to_write = size - i;
  174       if(to_write > m_chunk_size) to_write = m_chunk_size;
  175 #ifdef OS2
  176       ULONG actual = 0;
  177       if(DosWrite(fd, PVOID(buf), to_write, &actual))
  178       {
  179         fprintf(stderr, "Can't write data.\n");
  180         return -1;
  181       }
  182 #else
  183       if(to_write != write(fd, static_cast<void *>(buf), to_write))
  184       {
  185         fprintf(stderr, "Can't write data.\n");
  186         return -1;
  187       }
  188 #endif
  189     }
  190   }
  191   if(m_sync)
  192   {
  193     if(fsync(fd))
  194     {
  195       fprintf(stderr, "Can't sync file.\n");
  196       return -1;
  197     }
  198     if(m_sync_dir && fsync(m_directoryHandles[dir]))
  199     {
  200       fprintf(stderr, "Can't sync directory, turning off dir-sync.\n");
  201       m_sync_dir = false;
  202     }
  203   }
  204   file_close(fd);
  205   return 0;
  206 }
  207 
  208 int COpenTest::create_a_link(const char *original, const char *filename, int dir)
  209 {
  210 #ifdef OS2
  211   fprintf(stderr, "Not supported on OS/2\n");
  212   return -1;
  213 #else
  214   if(m_max == -1)
  215   {
  216     if(link(original, filename))
  217     {
  218       fprintf(stderr, "Can't create link %s\n", filename);
  219       return -1;
  220     }
  221     if(m_sync)
  222     {
  223       if(fsync(m_directoryHandles[dir]))
  224       {
  225         fprintf(stderr, "Can't sync file.\n");
  226         return -1;
  227       }
  228     }
  229   }
  230   else
  231   {
  232     if(symlink(original, filename))
  233     {
  234       fprintf(stderr, "Can't create symlink %s\n", filename);
  235       return -1;
  236     }
  237     if(m_sync)
  238     {
  239       if(fsync(m_directoryHandles[dir]))
  240       {
  241         fprintf(stderr, "Can't sync file.\n");
  242         return -1;
  243       }
  244     }
  245   }
  246   return 0;
  247 #endif
  248 }
  249 
  250 int COpenTest::create(CPCCHAR dirname, BonTimer &timer, int num, int max_size
  251                     , int min_size, int num_directories, bool do_random)
  252 {
  253   if(num_directories >= 100000)
  254   {
  255     fprintf(stderr, "Can't have more than 99,999 directories.\n");
  256     return -1;
  257   }
  258 
  259   m_number = num * DirectoryUnit;
  260   m_number_directories = num_directories;
  261   make_names(do_random);
  262   m_max = max_size;
  263   m_min = min_size;
  264   m_size_range = m_max - m_min;
  265   m_dirname = new char[strlen(dirname) + 1];
  266   strcpy(m_dirname, dirname);
  267 
  268   if(make_directory(dirname))
  269   {
  270     fprintf(stderr, "Can't make directory %s\n", dirname);
  271     return -1;
  272   }
  273   if(chdir(dirname))
  274   {
  275     fprintf(stderr, "Can't change to directory %s\n", dirname);
  276     return -1;
  277   }
  278   int i;
  279   if(m_sync)
  280     m_directoryHandles = new FILE_TYPE[num_directories];
  281   if(num_directories > 1)
  282   {
  283     for(i = 0; i < num_directories; i++)
  284     {
  285       sprintf(m_buf, "%05d", i);
  286       if(make_directory(m_buf))
  287       {
  288         fprintf(stderr, "Can't make directory %s\n", m_buf);
  289         return -1;
  290       }
  291       if(m_sync)
  292       {
  293         m_directoryHandles[i] = open(m_buf, O_RDONLY);
  294         if(m_directoryHandles[i] == -1)
  295         {
  296           fprintf(stderr, "Can't get directory handle.\n");
  297           return -1;
  298         }
  299       }
  300     }
  301   }
  302   else if(m_sync)
  303   {
  304     m_directoryHandles[0] = open(".", O_RDONLY);
  305     if(m_directoryHandles[0] == -1)
  306     {
  307       fprintf(stderr, "Can't get directory handle.\n");
  308       return -1;
  309     }
  310   }
  311 
  312   timer.timestamp();
  313   for(i = 0; i < m_number; i++)
  314   {
  315     if(*m_exit)
  316     {
  317       return EXIT_CTRL_C;
  318     }
  319     // m_max < 0 means link or sym-link
  320     if(m_max < 0)
  321     {
  322       if(i == 0)
  323       {
  324         if(create_a_file(m_file_names[0], m_buf, 0, m_dirIndex ? m_dirIndex[0] : 0))
  325           return -1;
  326       }
  327       else
  328       {
  329         // create_a_link() looks at m_max to see what to do
  330         if(create_a_link(m_file_names[0], m_file_names[i], m_dirIndex ? m_dirIndex[i] : 0))
  331           return -1;
  332       }
  333     }
  334     else
  335     {
  336       int size;
  337       if(m_size_range)
  338         size = m_min + (rand() % (m_size_range + 1));
  339       else
  340         size = m_max;
  341       if(create_a_file(m_file_names[i], m_buf, size, m_dirIndex ? m_dirIndex[i] : 0))
  342         return -1;
  343     }
  344   }
  345   timer.get_delta_t(do_random ? CreateRand : CreateSeq);
  346   return 0;
  347 }
  348 
  349 int COpenTest::delete_random(BonTimer &timer)
  350 {
  351   random_sort();
  352   timer.timestamp();
  353   int i;
  354   for(i = 0; i < m_number; i++)
  355   {
  356     if(unlink(m_file_names[i]))
  357     {
  358       fprintf(stderr, "Can't delete file %s\n", m_file_names[i]);
  359       return -1;
  360     }
  361     if(m_sync && m_sync_dir)
  362     {
  363       if(fsync(m_directoryHandles[m_dirIndex[i]]))
  364       {
  365         fprintf(stderr, "Can't sync directory, turning off dir-sync.\n");
  366         m_sync_dir = false;
  367       }
  368     }
  369   }
  370   if(m_number_directories > 1)
  371   {
  372     char buf[6];
  373     for(i = 0; i < m_number_directories; i++)
  374     {
  375       sprintf(buf, "%05d", i);
  376       if(m_sync)
  377       {
  378         close(m_directoryHandles[i]);
  379       }
  380       if(rmdir(buf))
  381       {
  382         io_error("rmdir");
  383         return -1;
  384       }
  385     }
  386   }
  387   else
  388   {
  389     if(m_sync)
  390     {
  391       close(m_directoryHandles[0]);
  392     }
  393   }
  394   if(chdir("..") || rmdir(m_dirname))
  395   {
  396     io_error("rmdir");
  397     return -1;
  398   }
  399   delete m_dirname;
  400   m_dirname = NULL;
  401   timer.get_delta_t(DelRand);
  402   return 0;
  403 }
  404 
  405 int COpenTest::delete_sequential(BonTimer &timer)
  406 {
  407   timer.timestamp();
  408   int count = 0;
  409   for(int i = 0; i < m_number_directories; i++)
  410   {
  411     char buf[6];
  412     if(m_number_directories != 1)
  413     {
  414       sprintf(buf, "%05d", i);
  415       if(chdir(buf))
  416       {
  417         fprintf(stderr, "Can't change to directory %s\n", buf);
  418         return -1;
  419       }
  420     }
  421 #ifdef OS2
  422     HDIR d = 0;
  423     ULONG entries = 1;
  424     FILEFINDBUF3 findBuf;
  425     ULONG rc = DosFindFirst("*", &d
  426                           , FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY
  427                           , &findBuf, sizeof(findBuf), &entries, FIL_STANDARD);
  428     if(rc || !entries)
  429     {
  430       fprintf(stderr, "Can't open directory.\n");
  431       return -1;
  432     }
  433     do
  434     {
  435       if(unlink(findBuf.achName))
  436       {
  437         fprintf(stderr, "Can't delete file %s\n", findBuf.achName);
  438         DosFindClose(d);
  439         return -1;
  440       }
  441       count++;
  442       rc = DosFindNext(d, &findBuf, sizeof(findBuf), &entries);
  443     } while(!rc && entries == 1);
  444     DosFindClose(d);
  445 #else
  446     DIR *d = opendir(".");
  447     if(!d)
  448     {
  449       fprintf(stderr, "Can't open directory.\n");
  450       return -1;
  451     }
  452     dirent *file_ent;
  453 
  454     while((file_ent = readdir(d)) != NULL)
  455     {
  456       if(file_ent->d_name[0] != '.')
  457       {
  458         if(unlink(file_ent->d_name))
  459         {
  460           fprintf(stderr, "Can't delete file %s\n", file_ent->d_name);
  461           return -1;
  462         }
  463 
  464 
  465         if(m_sync && m_sync_dir)
  466         {
  467           if(fsync(m_directoryHandles[i]))
  468           {
  469             fprintf(stderr, "Can't sync directory, turning off dir-sync.\n");
  470             m_sync_dir = false;
  471           }
  472         }
  473         count++;
  474       }
  475     }
  476     closedir(d);
  477 #endif
  478     if(m_sync)
  479     {
  480       close(m_directoryHandles[i]);
  481     }
  482     if(m_number_directories != 1)
  483     {
  484       if(chdir("..") || rmdir(buf))
  485       {
  486         io_error("rmdir");
  487         return -1;
  488       }
  489     }
  490   }
  491   if(chdir("..") || rmdir(m_dirname))
  492   {
  493     io_error("rmdir");
  494     return -1;
  495   }
  496   delete m_dirname;
  497   m_dirname = NULL;
  498   if(count != m_number)
  499   {
  500     fprintf(stderr, "Expected %d files but only got %d\n", m_number, count);
  501     return -1;
  502   }
  503   timer.get_delta_t(DelSeq);
  504   return 0;
  505 }
  506 
  507 int COpenTest::stat_file(CPCCHAR file)
  508 {
  509   struct stat st;
  510   if(stat(file, &st))
  511   {
  512     fprintf(stderr, "Can't stat file %s\n", file);
  513     return -1;
  514   }
  515   if(st.st_size)
  516   {
  517     FILE_TYPE fd = 0;
  518 #ifdef OS2
  519     ULONG action = 0;
  520     ULONG rc = DosOpen(file, &fd, &action, 0, FILE_NORMAL
  521                      , OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS
  522                      , OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE
  523                      , NULL);
  524     if(rc)
  525       fd = -1;
  526 #else
  527     fd = open(file, O_RDONLY);
  528 #endif
  529     if(fd == -1)
  530     {
  531       fprintf(stderr, "Can't open file %s\n", file);
  532       return -1;
  533     }
  534     for(int i = 0; i < st.st_size; i += m_chunk_size)
  535     {
  536       int to_read = st.st_size - i;
  537       if(to_read > m_chunk_size) to_read = m_chunk_size;
  538 #ifdef OS2
  539       ULONG actual = 0;
  540       rc = DosRead(fd, PVOID(m_buf), to_read, &actual);
  541       if(to_read != actual || rc)
  542 #else
  543       if(to_read != read(fd, static_cast<void *>(m_buf), to_read))
  544 #endif
  545       {
  546         fprintf(stderr, "Can't read data.\n");
  547         return -1;
  548       }
  549     }
  550     file_close(fd);
  551   }
  552   return 0;
  553 }
  554 
  555 int COpenTest::stat_random(BonTimer &timer)
  556 {
  557   random_sort();
  558   timer.timestamp();
  559 
  560   int i;
  561   for(i = 0; i < m_number; i++)
  562   {
  563     if(-1 == stat_file(m_file_names[i]))
  564       return -1;
  565   }
  566   timer.get_delta_t(StatRand);
  567   return 0;
  568 }
  569 
  570 int COpenTest::stat_sequential(BonTimer &timer)
  571 {
  572   timer.timestamp();
  573   int count = 0;
  574   for(int i = 0; i < m_number_directories; i++)
  575   {
  576     char buf[6];
  577     if(m_number_directories != 1)
  578     {
  579       sprintf(buf, "%05d", i);
  580       if(chdir(buf))
  581       {
  582         fprintf(stderr, "Can't change to directory %s\n", buf);
  583         return -1;
  584       }
  585     }
  586 #ifdef OS2
  587     HDIR d = 0;
  588     ULONG entries = 1;
  589     FILEFINDBUF3 findBuf;
  590     ULONG rc = DosFindFirst("*", &d
  591                           , FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY
  592                           , &findBuf, sizeof(findBuf), &entries, FIL_STANDARD);
  593     if(rc || !entries)
  594     {
  595       fprintf(stderr, "Can't open directory.\n");
  596       if(m_number_directories != 1)
  597       {
  598         if(chdir(".."))
  599           fprintf(stderr, "Can't chdir().\n");
  600       }
  601       return -1;
  602     }
  603     do
  604     {
  605       if(*m_exit)
  606       {
  607         return EXIT_CTRL_C;
  608       }
  609       if(findBuf.achName[0] != '.') // our files do not start with a dot
  610       {
  611         if(-1 == stat_file(findBuf.achName))
  612         {
  613           if(m_number_directories != 1)
  614           {
  615             if(chdir(".."))
  616               fprintf(stderr, "Can't chdir().\n");
  617           }
  618           return -1;
  619         }
  620         count++;
  621       }
  622       rc = DosFindNext(d, &findBuf, sizeof(findBuf), &entries);
  623     } while(!rc && entries == 1);
  624     DosFindClose(d);
  625 #else
  626     DIR *d = opendir(".");
  627     if(!d)
  628     {
  629       fprintf(stderr, "Can't open directory.\n");
  630       if(m_number_directories != 1)
  631       {
  632         if(chdir(".."))
  633           fprintf(stderr, "Can't chdir().\n");
  634       }
  635       return -1;
  636     }
  637     dirent *file_ent;
  638     while((file_ent = readdir(d)) != NULL)
  639     {
  640       if(*m_exit)
  641       {
  642         if(m_number_directories != 1 && chdir(".."))
  643         {
  644           fprintf(stderr, "Can't change to directory ..\n");
  645           return -1;
  646         }
  647         return EXIT_CTRL_C;
  648       }
  649       if(file_ent->d_name[0] != '.') // our files do not start with a dot
  650       {
  651         if(-1 == stat_file(file_ent->d_name))
  652         {
  653           if(m_number_directories != 1)
  654           {
  655             if(chdir(".."))
  656               fprintf(stderr, "Can't chdir().\n");
  657           }
  658           return -1;
  659         }
  660         count++;
  661       }
  662     }
  663     closedir(d);
  664 #endif
  665     if(m_number_directories != 1 && chdir(".."))
  666     {
  667       fprintf(stderr, "Can't change to directory ..\n");
  668       return -1;
  669     }
  670   }
  671   if(count != m_number)
  672   {
  673     fprintf(stderr, "Expected %d files but only got %d\n", m_number, count);
  674     return -1;
  675   }
  676   timer.get_delta_t(StatSeq);
  677   return 0;
  678 }
  679