busybox/coreutils/truncate.c
<<
>>
Prefs
   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