+static void clearprogress();
+
+// Report an error and exit
+static void fatal(int errno_value, const char *fmt, ...) {
+ va_list ap;
+ clearprogress();
+ fprintf(stderr, "ERROR: ");
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if(errno_value)
+ fprintf(stderr, ": %s", strerror(errno_value));
+ fputc('\n', stderr);
+ exit(1);
+}
+
+// Evict whatever FP points to from RAM
+static void flushCache(FILE *fp) {
+ // drop_caches only evicts clean pages, so first the target file is
+ // synced.
+ if(fsync(fileno(fp)) < 0)
+ fatal(errno, "fsync");
+#if defined DROP_CACHE_FILE
+ int fd;
+ if((fd = open(DROP_CACHE_FILE, O_WRONLY, 0)) < 0)
+ fatal(errno, "%s", DROP_CACHE_FILE);
+ if(write(fd, "3\n", 2) < 0)
+ fatal(errno, "%s", DROP_CACHE_FILE);
+ close(fd);
+#elif defined PURGE_COMMAND
+ int rc;
+ if((rc = system(PURGE_COMMAND)) < 0)
+ fatal(errno, "executing %s", PURGE_COMMAND);
+ else if(rc) {
+ if(WIFSIGNALED(rc)) {
+ fprintf(stderr, "%s%s\n",
+ strsignal(WTERMSIG(rc)),
+ WCOREDUMP(rc) ? " (core dumped)" : "");
+ exit(WTERMSIG(rc) + 128);
+ } else
+ exit(WEXITSTATUS(rc));
+ }
+#endif
+}
+
+static void scale(int shift, long long &value) {
+ switch(shift) {
+ case 'K': shift = 10; break;
+ case 'M': shift = 20; break;
+ case 'G': shift = 30; break;
+ default: fatal(0, "invalid scale");
+ }
+ if(value > (LLONG_MAX >> shift))
+ fatal(0, "invalid size");
+ value <<= shift;
+}
+
+static long long execute(mode_type mode, bool entire, const char *show);
+
+static const char default_seed[] = "hexapodia as the key insight";
+static void *seed;
+static size_t seedlen;
+static const char *seedpath;
+static const char *path;
+static bool entireopt = false;
+static bool flush = false;
+static bool progress = false;
+static long long size;
+