1/* 2 * Mini truncate implementation for busybox 3 * 4 * Copyright (C) 2015 by Ari Sundholm <ari@tuxera.com> 5 * 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 */ 8 9//config:config TRUNCATE 10//config: bool "truncate" 11//config: default y 12//config: help 13//config: truncate truncates files to a given size. If a file does 14//config: not exist, it is created unless told otherwise. 15 16//kbuild:lib-$(CONFIG_TRUNCATE) += truncate.o 17//applet:IF_TRUNCATE(APPLET_NOFORK(truncate, truncate, BB_DIR_USR_BIN, BB_SUID_DROP, truncate)) 18 19//usage:#define truncate_trivial_usage 20//usage: "[-c] -s SIZE FILE..." 21//usage:#define truncate_full_usage "\n\n" 22//usage: "Truncate FILEs to the given size\n" 23//usage: "\n -c Do not create files" 24//usage: "\n -s SIZE Truncate to SIZE" 25//usage: 26//usage:#define truncate_example_usage 27//usage: "$ truncate -s 1G foo" 28 29#include "libbb.h" 30 31#if ENABLE_LFS 32# define XATOU_SFX xatoull_sfx 33#else 34# define XATOU_SFX xatoul_sfx 35#endif 36 37/* This is a NOFORK applet. Be very careful! */ 38 39int truncate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 40int truncate_main(int argc UNUSED_PARAM, char **argv) 41{ 42 unsigned opts; 43 int flags = O_RDWR; 44 int ret = EXIT_SUCCESS; 45 char *size_str; 46 off_t size; 47 48 enum { 49 OPT_NOCREATE = (1 << 0), 50 OPT_SIZE = (1 << 1), 51 }; 52 53 opt_complementary = "s:-1"; 54 opts = getopt32(argv, "cs:", &size_str); 55 56 if (!(opts & OPT_NOCREATE)) 57 flags |= O_CREAT; 58 59 // TODO: coreutils 8.17 also support "m" (lowercase) suffix 60 // with truncate, but not with dd! 61 // We share kMG_suffixes[], so we can't make both tools 62 // compatible at once... 63 size = XATOU_SFX(size_str, kMG_suffixes); 64 65 argv += optind; 66 while (*argv) { 67 int fd = open(*argv, flags); 68 if (fd < 0) { 69 if (errno != ENOENT || !(opts & OPT_NOCREATE)) { 70 bb_perror_msg("%s: open", *argv); 71 ret = EXIT_FAILURE; 72 } 73 /* else: ENOENT && OPT_NOCREATE: 74 * do not report error, exitcode is also 0. 75 */ 76 } else { 77 if (ftruncate(fd, size) == -1) { 78 bb_perror_msg("%s: truncate", *argv); 79 ret = EXIT_FAILURE; 80 } 81 xclose(fd); 82 } 83 ++argv; 84 } 85 86 return ret; 87} 88