"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