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//config:config TRUNCATE 9//config: bool "truncate (4.2 kb)" 10//config: default y 11//config: help 12//config: truncate truncates files to a given size. If a file does 13//config: not exist, it is created unless told otherwise. 14 15//applet:IF_TRUNCATE(APPLET_NOFORK(truncate, truncate, BB_DIR_USR_BIN, BB_SUID_DROP, truncate)) 16 17//kbuild:lib-$(CONFIG_TRUNCATE) += truncate.o 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 SIZE\n" 23//usage: "\n -c Do not create files" 24//usage: "\n -s 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_WRONLY | O_NONBLOCK; 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 opts = getopt32(argv, "^" "cs:" "\0" "s:-1", &size_str); 54 55 if (!(opts & OPT_NOCREATE)) 56 flags |= O_CREAT; 57 58 // TODO: coreutils 8.17 also support "m" (lowercase) suffix 59 // with truncate, but not with dd! 60 // We share kMG_suffixes[], so we can't make both tools 61 // compatible at once... 62 size = XATOU_SFX(size_str, kMG_suffixes); 63 64 argv += optind; 65 while (*argv) { 66 int fd = open(*argv, flags, 0666); 67 if (fd < 0) { 68 if (errno != ENOENT || !(opts & OPT_NOCREATE)) { 69 bb_perror_msg("%s: open", *argv); 70 ret = EXIT_FAILURE; 71 } 72 /* else: ENOENT && OPT_NOCREATE: 73 * do not report error, exitcode is also 0. 74 */ 75 } else { 76 if (ftruncate(fd, size) == -1) { 77 bb_perror_msg("%s: truncate", *argv); 78 ret = EXIT_FAILURE; 79 } 80 xclose(fd); 81 } 82 ++argv; 83 } 84 85 return ret; 86} 87