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//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