1 /* 2 * Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <getopt.h> 10 #include <stdlib.h> 11 #include <stdint.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <unistd.h> 15 16 #include <OS.h> 17 18 19 extern const char* __progname; 20 const char* kProgramName = __progname; 21 22 const int32_t kDefaultFiles = -1; 23 const off_t kDefaultFileSize = 4096; 24 25 26 static void 27 usage(int status) 28 { 29 printf("usage: %s [--files <num-of-files>] [--size <file-size>]\n", 30 kProgramName); 31 printf("options:\n"); 32 printf(" -f --files Number of files to be created. Defaults to as " 33 "many as fit.\n"); 34 printf(" -s --size Size of each file. Defaults to %lldKB.\n", 35 kDefaultFileSize / 1024); 36 37 exit(status); 38 } 39 40 41 static bool 42 create_file(int32_t i, const char* suffix, const char* buffer, size_t size) 43 { 44 char name[64]; 45 snprintf(name, sizeof(name), "fragments/%06d%s", i, suffix); 46 47 int fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644); 48 if (fd < 0) { 49 fprintf(stderr, "%s: Could not create file %d: %s\n", kProgramName, 50 i, strerror(errno)); 51 return false; 52 } 53 54 if (write(fd, buffer, size) < (ssize_t)size) { 55 fprintf(stderr, "%s: Could not write file %d: %s\n", kProgramName, 56 i, strerror(errno)); 57 return false; 58 } 59 60 close(fd); 61 return true; 62 } 63 64 65 int 66 main(int argc, char** argv) 67 { 68 int32_t numFiles = kDefaultFiles; 69 off_t fileSize = kDefaultFileSize; 70 71 int optionIndex = 0; 72 int opt; 73 static struct option longOptions[] = { 74 {"help", no_argument, 0, 'h'}, 75 {"size", required_argument, 0, 's'}, 76 {"files", required_argument, 0, 'f'}, 77 {0, 0, 0, 0} 78 }; 79 80 do { 81 opt = getopt_long(argc, argv, "hs:f:", longOptions, &optionIndex); 82 switch (opt) { 83 case -1: 84 // end of arguments, do nothing 85 break; 86 87 case 'f': 88 numFiles = strtoul(optarg, NULL, 0); 89 break; 90 91 case 's': 92 fileSize = strtoul(optarg, NULL, 0); 93 break; 94 95 case 'h': 96 default: 97 usage(0); 98 break; 99 } 100 } while (opt != -1); 101 102 // fill buffer 103 104 char* buffer = (char*)malloc(fileSize); 105 if (buffer == NULL) { 106 fprintf(stderr, "%s: not enough memory.\n", kProgramName); 107 exit(1); 108 } 109 110 for (uint32_t i = 0; i < fileSize; i++) { 111 buffer[i] = (char)(i & 0xff); 112 } 113 114 // create files 115 116 if (numFiles > 0) 117 printf("Creating %d files...\n", numFiles); 118 else 119 printf("Creating as many files as fit...\n"); 120 121 mkdir("fragments", 0777); 122 123 int32_t filesCreated = 0; 124 bigtime_t lastTime = 0; 125 126 for (int32_t i = 0; i < numFiles || numFiles < 0; i++) { 127 if (!create_file(i, "", buffer, fileSize) 128 || !create_file(i, ".remove", buffer, fileSize)) 129 break; 130 131 filesCreated++; 132 133 if (lastTime + 250000LL < system_time()) { 134 printf("%10d\33[1A\n", filesCreated); 135 lastTime = system_time(); 136 } 137 } 138 139 free(buffer); 140 141 // delete fragmentation files 142 143 printf("Deleting %d temporary files...\n", filesCreated); 144 145 for (int32_t i = 0; i < filesCreated; i++) { 146 char name[64]; 147 snprintf(name, sizeof(name), "fragments/%06d.remove", i); 148 149 if (remove(name) != 0) { 150 fprintf(stderr, "%s: Could not remove file %d: %s\n", 151 kProgramName, i, strerror(errno)); 152 } 153 154 if (lastTime + 250000LL < system_time()) { 155 printf("%10d\33[1A\n", i); 156 lastTime = system_time(); 157 } 158 } 159 160 printf(" \33[1A\n"); 161 // delete progress count 162 163 return 0; 164 } 165