* written by Mike Frysinger <vapier>
*/
+#pragma GCC diagnostic warning "-Wall"
+#pragma GCC diagnostic warning "-Wextra"
+
#define _FILE_OFFSET_BITS 64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
+#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <locale.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <linux/fs.h>
static const char zero[1024 * 1024];
#define errp(msg, args...) \
do { \
- printf("%s: " msg ": %m\n", argv[0], ## args); \
- return 1; \
+ printf("%s: " msg ": %m\n", program_invocation_short_name, ## args); \
+ exit(1); \
} while (0)
static unsigned long long mbps(struct timespec *stime, struct timespec *etime, off_t len)
return 1000 * len / dtime;
}
+static off_t get_blk_size(int fd)
+{
+ uint64_t size;
+ if (ioctl(fd, BLKGETSIZE64, &size))
+ errp("ioctl(BLKGETSIZE64) failed");
+ return size;
+}
+
+static off_t get_size(int fd)
+{
+ struct stat st;
+
+ if (fstat(fd, &st))
+ errp("could not stat %i", fd);
+
+ if (S_ISREG(st.st_mode))
+ return st.st_size;
+ else if (S_ISBLK(st.st_mode))
+ return get_blk_size(fd);
+
+ errno = EINVAL;
+ errp("unknown type of file");
+}
+
int main(int argc, char *argv[])
{
off_t offset = 0;
if (fd == -1)
errp("open(%s) failed", file);
+ off_t max_size = get_size(fd);
+
if (lseek(fd, offset, SEEK_SET) != offset)
errp("lseek(%"PRIu64"u) failed", offset);
clock_gettime(CLOCK_MONOTONIC, &stime);
itime = stime;
- off_t pos = 0, last_pos = 0;
+ off_t pos = offset, last_pos = 0;
ssize_t ret;
int fsync_pos = 0;
- while (1) {
+ while (pos < max_size) {
ret = write(fd, zero, sizeof(zero));
pos += ret;
if (ret != sizeof(zero)) {
return 0;
}
- printf("%'llu bytes (%'llu MB/s)%20s\r", (unsigned long long)pos, speed, "");
+ printf("%'llu bytes %u%% (%'llu MB/s)%20s\r", (unsigned long long)pos,
+ (unsigned)((pos * 100) / max_size), speed, "");
if ((++fsync_pos % 16) == 0) {
speed = mbps(&stime, &etime, pos - last_pos);
}
}
+ printf("\n");
return 0;
}