Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 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 | */ |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 8 | //config:config TRUNCATE |
Denys Vlasenko | b097a84 | 2018-12-28 03:20:17 +0100 | [diff] [blame] | 9 | //config: bool "truncate (4.2 kb)" |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 10 | //config: default y |
| 11 | //config: help |
Denys Vlasenko | 72089cf | 2017-07-21 09:50:55 +0200 | [diff] [blame] | 12 | //config: truncate truncates files to a given size. If a file does |
| 13 | //config: not exist, it is created unless told otherwise. |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 14 | |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 15 | //applet:IF_TRUNCATE(APPLET_NOFORK(truncate, truncate, BB_DIR_USR_BIN, BB_SUID_DROP, truncate)) |
| 16 | |
Denys Vlasenko | af3f420 | 2016-11-23 14:46:56 +0100 | [diff] [blame] | 17 | //kbuild:lib-$(CONFIG_TRUNCATE) += truncate.o |
| 18 | |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 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 | |
| 39 | int truncate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 40 | int truncate_main(int argc UNUSED_PARAM, char **argv) |
| 41 | { |
| 42 | unsigned opts; |
Mike Frysinger | 6a70db8 | 2016-01-13 13:30:20 -0500 | [diff] [blame] | 43 | int flags = O_WRONLY | O_NONBLOCK; |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 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 | |
Denys Vlasenko | 22542ec | 2017-08-08 21:55:02 +0200 | [diff] [blame] | 53 | opts = getopt32(argv, "^" "cs:" "\0" "s:-1", &size_str); |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 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) { |
Ari Sundholm | e111a16 | 2016-01-04 15:40:37 +0200 | [diff] [blame] | 66 | int fd = open(*argv, flags, 0666); |
Ari Sundholm | fc3e40e | 2015-05-25 15:16:11 +0200 | [diff] [blame] | 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); |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 81 | } |
Denys Vlasenko | 1850d5e | 2015-03-22 18:00:32 +0100 | [diff] [blame] | 82 | ++argv; |
| 83 | } |
| 84 | |
| 85 | return ret; |
| 86 | } |