/* * truncate.c is an executable that is a wrapper around the truncate * system call. * * One possible use of this is as a much faster version of the * following: * * dd if=/dev/zero of= bs= count= */ #include #include #include #include #include #include #include #include static const char* progname; const char* basename(const char* fullpath) { const char* rv = NULL; if( (rv = strrchr(fullpath, '/')) != NULL ) { ++rv; } else { rv = fullpath; } return rv; } void usage(FILE* f, const char* prefix) { if( (prefix != NULL) && (strlen(prefix) > 0) ) { fprintf(f, "\n"); fprintf(f, "Error: %s\n", prefix); } fprintf(f, "\n"); fprintf(f, "Usage: %s [-h] []\n", progname); fprintf(f, " defaults to 0 and accepts an optional " "suffix.\n"); fprintf(f, " Valid suffixes for are k, m, and g.\n"); fprintf(f, " is any non-negative floating point, but is\n"); /* off_t is a "long" on x86 architectures. I assume other * architectures don't use "unsigned" too; hence, the "minus one" in * the formula. */ fprintf(f, " limited to 2 ^ %d bytes.\n", sizeof(off_t) * 8 - 1); fprintf(f, "\n"); if( f == stdout ) { exit(0); } else if( f == stderr ) { exit(1); } } int main(int argc, char* argv[]) { const char* tfilestr; const char* tsizestr; progname = basename(argv[0]); if( (argc == 1) || (argc > 3) ) { usage(stderr, "invalid number of arguments"); } if( (strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ) { usage(stdout, ""); } if( argv[1][0] == '\0' ) { usage(stderr, "empty file name"); } tfilestr = argv[1]; if( argc == 2 ) { tsizestr = "0"; } else if( argv[2][0] == '\0' ) { usage(stderr, "empty size"); } else { tsizestr = argv[2]; } { int fd = -1; double tsize = -1.0; char* endptr = NULL; int valid_size = 0; tsize = strtod(tsizestr, &endptr); if( endptr != NULL ) { if( *endptr == '\0' ) { valid_size = 1; } else if( *(endptr + 1) == '\0' ) { switch( *endptr ) { case 'g': case 'G': tsize *= 1024 * 1024 * 1024; valid_size = 1; break; case 'm': case 'M': tsize *= 1024 * 1024; valid_size = 1; break; case 'k': case 'K': tsize *= 1024; valid_size = 1; break; default: break; } } } if( tsize < 0 ) { valid_size = 0; } if( !valid_size ) { usage(stderr, "invalid size"); } if( (fd = open(tfilestr, O_WRONLY | O_CREAT, 0666)) < 0 ) { perror("open"); } if( ftruncate(fd, (off_t)tsize) < 0 ) { perror("truncate"); } } return 0; }