diff --git a/usr.bin/split/split.1 b/usr.bin/split/split.1 --- a/usr.bin/split/split.1 +++ b/usr.bin/split/split.1 @@ -28,7 +28,7 @@ .\" @(#)split.1 8.3 (Berkeley) 4/16/94 .\" $FreeBSD$ .\" -.Dd May 9, 2013 +.Dd May 26, 2023 .Dt SPLIT 1 .Os .Sh NAME @@ -36,12 +36,12 @@ .Nd split a file into pieces .Sh SYNOPSIS .Nm -.Fl d +.Op Fl cd .Op Fl l Ar line_count .Op Fl a Ar suffix_length .Op Ar file Op Ar prefix .Nm -.Fl d +.Op Fl cd .Fl b Ar byte_count Ns .Oo .Sm off @@ -51,12 +51,12 @@ .Op Fl a Ar suffix_length .Op Ar file Op Ar prefix .Nm -.Fl d +.Op Fl cd .Fl n Ar chunk_count .Op Fl a Ar suffix_length .Op Ar file Op Ar prefix .Nm -.Fl d +.Op Fl cd .Fl p Ar pattern .Op Fl a Ar suffix_length .Op Ar file Op Ar prefix @@ -112,6 +112,9 @@ is appended to the number, the file is split into .Ar byte_count gigabyte pieces. +.It Fl c +Continue creating files and do not overwrite existing +output files. .It Fl d Use a numeric suffix instead of a alphabetic suffix. .It Fl l Ar line_count @@ -159,6 +162,15 @@ files named with the prefix .Dq Li x and with suffixes as above. +.Pp +By default, +.Nm +will overwrite any existing output files. +If the +.Fl c +flag is specified, +.Nm +will instead create files with names that do not already exist. .Sh ENVIRONMENT The .Ev LANG , LC_ALL , LC_CTYPE diff --git a/usr.bin/split/split.c b/usr.bin/split/split.c --- a/usr.bin/split/split.c +++ b/usr.bin/split/split.c @@ -67,6 +67,7 @@ static off_t bytecnt; /* Byte count to split on. */ static off_t chunks = 0; /* Chunks count to split into. */ +static bool clobber = true; /* Whether to overwrite existing output files. */ static long numlines; /* Line count to split on. */ static int file_open; /* If a file open. */ static int ifd = -1, ofd = -1; /* Input/output file descriptors. */ @@ -93,7 +94,7 @@ setlocale(LC_ALL, ""); dflag = false; - while ((ch = getopt(argc, argv, "0123456789a:b:dl:n:p:")) != -1) + while ((ch = getopt(argc, argv, "0123456789a:b:cdl:n:p:")) != -1) switch (ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': @@ -124,6 +125,9 @@ if (error == -1) errx(EX_USAGE, "%s: offset too large", optarg); break; + case 'c': /* Continue, don't overwrite output files. */ + clobber = false; + break; case 'd': /* Decimal suffix */ dflag = true; break; @@ -346,6 +350,10 @@ static char *fpnt; char beg, end; int pattlen; + int flags = O_WRONLY | O_CREAT | O_TRUNC; + + if (!clobber) + flags |= O_EXCL; if (ofd == -1) { if (fname[0] == '\0') { @@ -354,9 +362,10 @@ } else { fpnt = fname + strlen(fname); } - ofd = fileno(stdout); - } + } else if (close(ofd) != 0) + err(1, "%s", fname); + again: if (dflag) { beg = '0'; end = '9'; @@ -387,8 +396,11 @@ fpnt[sufflen] = '\0'; ++fnum; - if (!freopen(fname, "w", stdout)) + if ((ofd = open(fname, flags, DEFFILEMODE)) < 0) { + if (!clobber && errno == EEXIST) + goto again; err(EX_IOERR, "%s", fname); + } file_open = 1; } @@ -396,7 +408,7 @@ usage(void) { (void)fprintf(stderr, -"usage: split [-l line_count] [-a suffix_length] [file [prefix]]\n" +"usage: split [-c] [-l line_count] [-a suffix_length] [file [prefix]]\n" " split -b byte_count[K|k|M|m|G|g] [-a suffix_length] [file [prefix]]\n" " split -n chunk_count [-a suffix_length] [file [prefix]]\n" " split -p pattern [-a suffix_length] [file [prefix]]\n");