summaryrefslogtreecommitdiffstats
path: root/usr.bin/truncate
diff options
context:
space:
mode:
authorsheldonh <sheldonh@FreeBSD.org>2000-07-18 17:03:58 +0000
committersheldonh <sheldonh@FreeBSD.org>2000-07-18 17:03:58 +0000
commit5df055483d2201b685994082d68c1235a690c99a (patch)
tree8ec7aa73a358269417e0aa48c324f93db82f4b99 /usr.bin/truncate
parentbbe00ac533441c4cafca8001a4e8d43cf41406d5 (diff)
downloadFreeBSD-src-5df055483d2201b685994082d68c1235a690c99a.zip
FreeBSD-src-5df055483d2201b685994082d68c1235a690c99a.tar.gz
Import the new truncate(1) utility.
Approved by: jdp
Diffstat (limited to 'usr.bin/truncate')
-rw-r--r--usr.bin/truncate/Makefile5
-rw-r--r--usr.bin/truncate/truncate.1144
-rw-r--r--usr.bin/truncate/truncate.c202
3 files changed, 351 insertions, 0 deletions
diff --git a/usr.bin/truncate/Makefile b/usr.bin/truncate/Makefile
new file mode 100644
index 0000000..4752c5c
--- /dev/null
+++ b/usr.bin/truncate/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+PROG= truncate
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/truncate/truncate.1 b/usr.bin/truncate/truncate.1
new file mode 100644
index 0000000..800deb6
--- /dev/null
+++ b/usr.bin/truncate/truncate.1
@@ -0,0 +1,144 @@
+.\"
+.\" Copyright (c) 2000 Sheldon Hearn <sheldonh@FreeBSD.org>.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd Jul 4, 2000
+.Dt TRUNCATE 1
+.Os
+.Sh NAME
+.Nm truncate
+.Nd truncate or extend the length of files
+.Sh SYNOPSIS
+.Nm truncate
+.Op Fl c
+.Bk -words
+.Fl s Xo
+.Sm off
+.Op + | -
+.Ar size
+.Op K | M | G
+.Sm on
+.Xc
+.Ek
+.Ar
+.Nm truncate
+.Op Fl c
+.Bk -words
+.Fl r Ar rfile
+.Ek
+.Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility adjusts the length of each regular file given on the command-line.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl c
+Do not create files if they do not exist.
+The
+.Nm
+utility does not treat this as an error.
+No error messages are displayed
+and the exit value is not affected.
+.It Fl r Ar rfile
+Truncate files to the length of the file
+.Ar rfile .
+.It Fl s Xo
+.Sm off
+.Op + | -
+.Ar size
+.Op K | M | G
+.Sm on
+.Xc
+If the
+.Ar size
+argument is preceded by a plus sign
+.Pq Sq + ,
+files will be extended by this number of bytes.
+If the
+.Ar size
+argument is preceded by a dash
+.Pq Sq - ,
+file lengths will be reduced by no more than this number of bytes,
+to a minimum length of zero bytes.
+Otherwise, the
+.Ar size
+argument specifies an absolute length to which all files
+should be extended or reduced as appropriate.
+.Pp
+The
+.Ar size
+argument may be suffixed with one of
+.Sq K ,
+.Sq M ,
+.Sq G
+to indicate a multiple of
+Kilobytes, Megabytes or Gigabytes
+respectively.
+.El
+.Pp
+Exactly one of the
+.Fl r
+and
+.Fl s
+options must be specified.
+.Pp
+If a file is made smaller, its extra data is lost.
+If a file is made larger,
+it will be extended as if by writing bytes with the value zero.
+If the file does not exist,
+it is created unless the
+.Fl c
+option is specified.
+.Pp
+Note that,
+while truncating a file causes space on disk to be freed,
+extending a file does not cause space to be allocated.
+To extend a file and actually allocate the space,
+it is necessary to explicitly write data to it,
+using (for example) the shell's
+.Ql >>
+redirection syntax, or
+.Xr dd 1 .
+.Sh DIAGNOSTICS
+The
+.Nm
+utility exits 0 on success,
+and >0 if an error occurs.
+If the operation fails for an argument,
+.Nm
+will issue a diagnostic
+and continue processing the remaining arguments.
+.Sh SEE ALSO
+.Xr dd 1 ,
+.Xr touch 1 ,
+.Xr truncate 2
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 5.0 .
diff --git a/usr.bin/truncate/truncate.c b/usr.bin/truncate/truncate.c
new file mode 100644
index 0000000..0b6fef4
--- /dev/null
+++ b/usr.bin/truncate/truncate.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2000 FreeBSD, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static off_t parselength __P((char *, off_t *));
+static void usage __P((void));
+
+static int no_create;
+static int do_relative;
+static int do_refer;
+static int got_size;
+
+int
+main(int argc, char **argv)
+{
+ struct stat sb;
+ mode_t omode;
+ off_t oflow, rsize, sz, tsize;
+ int ch, error, fd, oflags;
+ char *fname, *rname;
+
+ error = 0;
+ while ((ch = getopt(argc, argv, "cr:s:")) != -1)
+ switch (ch) {
+ case 'c':
+ no_create++;
+ break;
+ case 'r':
+ do_refer++;
+ rname = optarg;
+ break;
+ case 's':
+ if (parselength(optarg, &sz) == -1)
+ errx(EXIT_FAILURE,
+ "invalid size argument `%s'", optarg);
+ if (*optarg == '+' || *optarg == '-')
+ do_relative++;
+ got_size++;
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+
+ argv += optind;
+ argc -= optind;
+
+ /*
+ * Exactly one of do_refer or got_size must be specified. Since
+ * do_relative implies got_size, do_relative and do_refer are
+ * also mutually exclusive. See usage() for allowed invocations.
+ */
+ if (!(do_refer || got_size) || (do_refer && got_size) || argc < 1)
+ usage();
+ if (do_refer) {
+ if (stat(rname, &sb) == -1)
+ err(EXIT_FAILURE, "%s", rname);
+ tsize = sb.st_size;
+ } else if (got_size) {
+ if (do_relative)
+ rsize = sz;
+ else
+ tsize = sz;
+ }
+
+ if (no_create)
+ oflags = O_WRONLY;
+ else
+ oflags = O_WRONLY | O_CREAT;
+ omode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+
+ while ((fname = *argv++) != NULL) {
+ if ((fd = open(fname, oflags, omode)) == -1) {
+ if (errno != ENOENT) {
+ warn("%s", fname);
+ error++;
+ }
+ continue;
+ }
+ if (do_relative) {
+ if (fstat(fd, &sb) == -1) {
+ warn("%s", fname);
+ error++;
+ continue;
+ }
+ oflow = sb.st_size + rsize;
+ if (oflow < (sb.st_size + rsize)) {
+ errno = EFBIG;
+ warn("%s", fname);
+ error++;
+ continue;
+ }
+ tsize = oflow;
+ }
+ if (tsize < 0)
+ tsize = 0;
+
+ if (ftruncate(fd, tsize) == -1) {
+ warn("%s", fname);
+ error++;
+ continue;
+ }
+ }
+
+ return error ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+/*
+ * Return the numeric value of a string given in the form [+-][0-9]+[GMK]
+ * or -1 on format error or overflow.
+ */
+static off_t
+parselength(char *ls, off_t *sz)
+{
+ off_t length, oflow;
+ int lsign;
+
+ length = 0;
+ lsign = 1;
+
+ switch (*ls) {
+ case '-':
+ lsign = -1;
+ case '+':
+ ls++;
+ }
+
+#define ASSIGN_CHK_OFLOW(x, y) if (x < y) return -1; y = x
+ /*
+ * Calculate the value of the decimal digit string, failing
+ * on overflow.
+ */
+ while (isdigit(*ls)) {
+ oflow = length * 10 + *ls++ - '0';
+ ASSIGN_CHK_OFLOW(oflow, length);
+ }
+
+ switch (*ls) {
+ case 'G':
+ oflow = length * 1024;
+ ASSIGN_CHK_OFLOW(oflow, length);
+ case 'M':
+ oflow = length * 1024;
+ ASSIGN_CHK_OFLOW(oflow, length);
+ case 'K':
+ if (ls[1] != '\0')
+ return -1;
+ oflow = length * 1024;
+ ASSIGN_CHK_OFLOW(oflow, length);
+ case '\0':
+ break;
+ default:
+ return -1;
+ }
+
+ *sz = length * lsign;
+ return 0;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "%s\n%s\n",
+ "usage: truncate [-c] -s [+|-]size[K|M|G] file ...",
+ " truncate [-c] -r rfile file ...");
+ exit(EXIT_FAILURE);
+}
OpenPOWER on IntegriCloud