diff options
author | gjb <gjb@FreeBSD.org> | 2016-02-22 12:28:23 +0000 |
---|---|---|
committer | gjb <gjb@FreeBSD.org> | 2016-02-22 12:28:23 +0000 |
commit | 8bfb527a82b3844c875182139d053826902f90d6 (patch) | |
tree | 8a0600337b49dbed7acd411e862bbcfba916c0bc /bin | |
parent | adbdbd2fff21519f0d418a20255dfd18a2381dbc (diff) | |
parent | 6a7ac9da7c8a3a5b9c0a21830670b06935f58332 (diff) | |
download | FreeBSD-src-8bfb527a82b3844c875182139d053826902f90d6.zip FreeBSD-src-8bfb527a82b3844c875182139d053826902f90d6.tar.gz |
MFH
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'bin')
-rw-r--r-- | bin/dd/Makefile | 13 | ||||
-rw-r--r-- | bin/dd/args.c | 14 | ||||
-rw-r--r-- | bin/dd/dd.c | 36 | ||||
-rw-r--r-- | bin/dd/dd.h | 1 | ||||
-rw-r--r-- | bin/dd/gen.c | 13 | ||||
-rw-r--r-- | bin/dd/ref.obs_zeroes | 3 | ||||
-rw-r--r-- | bin/sh/alias.c | 6 | ||||
-rw-r--r-- | bin/sh/input.c | 54 | ||||
-rw-r--r-- | bin/sh/parser.c | 2 | ||||
-rw-r--r-- | bin/sh/tests/parser/Makefile | 3 | ||||
-rw-r--r-- | bin/sh/tests/parser/comment1.0 | 3 | ||||
-rw-r--r-- | bin/sh/tests/parser/comment2.42 | 4 | ||||
-rw-r--r-- | bin/sh/tests/parser/nul1.0 | 12 |
13 files changed, 105 insertions, 59 deletions
diff --git a/bin/dd/Makefile b/bin/dd/Makefile index 07c2a67..df877c8 100644 --- a/bin/dd/Makefile +++ b/bin/dd/Makefile @@ -25,7 +25,18 @@ test: ${PROG} gen LC_ALL=en_US.US-ASCII hexdump -C | \ diff -I FreeBSD - ${.CURDIR}/ref.${conv} .endfor - @rm -f gen + @${ECHO} "testing sparse file (obs zeroes)" + @./gen 189284 | ./dd ibs=16 obs=8 conv=sparse of=obs_zeroes 2> /dev/null + @hexdump -C obs_zeroes | diff -I FreeBSD - ${.CURDIR}/ref.obs_zeroes + + @${ECHO} "testing spase file (all zeroes)" + @./dd if=/dev/zero of=1M_zeroes bs=1048576 count=1 2> /dev/null + @./dd if=1M_zeroes of=1M_zeroes.1 bs=1048576 conv=sparse 2> /dev/null + @./dd if=1M_zeroes of=1M_zeroes.2 bs=1048576 2> /dev/null + @diff 1M_zeroes 1M_zeroes.1 + @diff 1M_zeroes 1M_zeroes.2 + + @rm -f gen 1M_zeroes* obs_zeroes .if ${MK_TESTS} != "no" SUBDIR+= tests diff --git a/bin/dd/args.c b/bin/dd/args.c index db8d445..4607d67 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -422,11 +422,10 @@ get_num(const char *val) errno = 0; num = strtoumax(val, &expr, 0); - if (errno != 0) /* Overflow or underflow. */ - err(1, "%s", oper); - if (expr == val) /* No valid digits. */ - errx(1, "%s: illegal numeric value", oper); + errx(1, "%s: invalid numeric value", oper); + if (errno != 0) + err(1, "%s", oper); mult = postfix_to_mult(*expr); @@ -472,11 +471,10 @@ get_off_t(const char *val) errno = 0; num = strtoimax(val, &expr, 0); - if (errno != 0) /* Overflow or underflow. */ - err(1, "%s", oper); - if (expr == val) /* No valid digits. */ - errx(1, "%s: illegal numeric value", oper); + errx(1, "%s: invalid numeric value", oper); + if (errno != 0) + err(1, "%s", oper); mult = postfix_to_mult(*expr); diff --git a/bin/dd/dd.c b/bin/dd/dd.c index 8ae11a7..4c31a5e 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -77,7 +77,6 @@ STAT st; /* statistics */ void (*cfunc)(void); /* conversion function */ uintmax_t cpy_cnt; /* # of blocks to copy */ static off_t pending = 0; /* pending seek if sparse */ -static off_t last_sp = 0; /* size of last added sparse block */ u_int ddflags = 0; /* conversion options */ size_t cbsz; /* conversion block size */ uintmax_t files_cnt = 1; /* # of files to copy */ @@ -409,6 +408,15 @@ dd_close(void) } if (out.dbcnt || pending) dd_out(1); + + /* + * If the file ends with a hole, ftruncate it to extend its size + * up to the end of the hole (without having to write any data). + */ + if (out.seek_offset > 0 && (out.flags & ISTRUNC)) { + if (ftruncate(out.fd, out.seek_offset) == -1) + err(1, "truncating %s", out.name); + } } void @@ -457,29 +465,27 @@ dd_out(int force) } if (sparse && !force) { pending += cnt; - last_sp = cnt; nw = cnt; } else { if (pending != 0) { - /* If forced to write, and we have no - * data left, we need to write the last - * sparse block explicitly. + /* + * Seek past hole. Note that we need to record the + * reached offset, because we might have no more data + * to write, in which case we'll need to call + * ftruncate to extend the file size. */ - if (force && cnt == 0) { - pending -= last_sp; - assert(outp == out.db); - memset(outp, 0, cnt); - } - if (lseek(out.fd, pending, SEEK_CUR) == - -1) + out.seek_offset = lseek(out.fd, pending, SEEK_CUR); + if (out.seek_offset == -1) err(2, "%s: seek error creating sparse file", out.name); - pending = last_sp = 0; + pending = 0; } - if (cnt) + if (cnt) { nw = write(out.fd, outp, cnt); - else + out.seek_offset = 0; + } else { return; + } } if (nw <= 0) { diff --git a/bin/dd/dd.h b/bin/dd/dd.h index a8b45e5..196f804 100644 --- a/bin/dd/dd.h +++ b/bin/dd/dd.h @@ -54,6 +54,7 @@ typedef struct { const char *name; /* name */ int fd; /* file descriptor */ off_t offset; /* # of blocks to skip */ + off_t seek_offset; /* offset of last seek past output hole */ } IO; typedef struct { diff --git a/bin/dd/gen.c b/bin/dd/gen.c index 9c7571a..d53d8fb 100644 --- a/bin/dd/gen.c +++ b/bin/dd/gen.c @@ -5,13 +5,20 @@ */ #include <stdio.h> +#include <string.h> int -main(int argc __unused, char **argv __unused) +main(int argc, char **argv) { int i; - for (i = 0; i < 256; i++) - putchar(i); + if (argc > 1 && !strcmp(argv[1], "189284")) { + fputs("ABCDEFGH", stdout); + for (i = 0; i < 8; i++) + putchar(0); + } else { + for (i = 0; i < 256; i++) + putchar(i); + } return (0); } diff --git a/bin/dd/ref.obs_zeroes b/bin/dd/ref.obs_zeroes new file mode 100644 index 0000000..473ff7c --- /dev/null +++ b/bin/dd/ref.obs_zeroes @@ -0,0 +1,3 @@ +$FreeBSD$ +00000000 41 42 43 44 45 46 47 48 00 00 00 00 00 00 00 00 |ABCDEFGH........| +00000010 diff --git a/bin/sh/alias.c b/bin/sh/alias.c index a77ce99..a35513b 100644 --- a/bin/sh/alias.c +++ b/bin/sh/alias.c @@ -144,9 +144,11 @@ rmaliases(void) struct alias * lookupalias(const char *name, int check) { - struct alias *ap = *hashalias(name); + struct alias *ap; - for (; ap; ap = ap->next) { + if (aliases == 0) + return (NULL); + for (ap = *hashalias(name); ap; ap = ap->next) { if (equal(name, ap->name)) { if (check && (ap->flag & ALIASINUSE)) return (NULL); diff --git a/bin/sh/input.c b/bin/sh/input.c index 412f144..27b835a 100644 --- a/bin/sh/input.c +++ b/bin/sh/input.c @@ -195,8 +195,7 @@ retry: int preadbuffer(void) { - char *p, *q; - int more; + char *p, *q, *r, *end; char savec; while (parsefile->strpush) { @@ -213,8 +212,6 @@ preadbuffer(void) } if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) return PEOF; - flushout(&output); - flushout(&errout); again: if (parselleft <= 0) { @@ -224,34 +221,31 @@ again: } } - q = p = parsefile->buf + (parsenextc - parsefile->buf); - - /* delete nul characters */ - for (more = 1; more;) { - switch (*p) { - case '\0': - p++; /* Skip nul */ - goto check; - - case '\n': - parsenleft = q - parsenextc; - more = 0; /* Stop processing here */ - break; - - default: - break; - } - - *q++ = *p++; -check: - if (--parselleft <= 0) { - parsenleft = q - parsenextc - 1; - if (parsenleft < 0) - goto again; - *q = '\0'; - more = 0; + p = parsefile->buf + (parsenextc - parsefile->buf); + end = p + parselleft; + *end = '\0'; + q = strchrnul(p, '\n'); + if (q != end && *q == '\0') { + /* delete nul characters */ + for (r = q; q != end; q++) { + if (*q != '\0') + *r++ = *q; } + parselleft -= end - r; + if (parselleft == 0) + goto again; + end = p + parselleft; + *end = '\0'; + q = strchrnul(p, '\n'); + } + if (q == end) { + parsenleft = parselleft; + parselleft = 0; + } else /* *q == '\n' */ { + parsenleft = q - parsenextc + 1; + parselleft -= parsenleft; } + parsenleft--; savec = *q; *q = '\0'; diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 53d7923..d324d88 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1930,6 +1930,8 @@ static void setprompt(int which) { whichprompt = which; + if (which == 0) + return; #ifndef NO_HISTORY if (!el) diff --git a/bin/sh/tests/parser/Makefile b/bin/sh/tests/parser/Makefile index 2027f59..bdbd6ca 100644 --- a/bin/sh/tests/parser/Makefile +++ b/bin/sh/tests/parser/Makefile @@ -28,6 +28,8 @@ FILES+= alias15.0 alias15.0.stdout FILES+= and-pipe-not.0 FILES+= case1.0 FILES+= case2.0 +FILES+= comment1.0 +FILES+= comment2.42 FILES+= dollar-quote1.0 FILES+= dollar-quote2.0 FILES+= dollar-quote3.0 @@ -74,6 +76,7 @@ FILES+= line-cont10.0 FILES+= line-cont11.0 FILES+= no-space1.0 FILES+= no-space2.0 +FILES+= nul1.0 FILES+= only-redir1.0 FILES+= only-redir2.0 FILES+= only-redir3.0 diff --git a/bin/sh/tests/parser/comment1.0 b/bin/sh/tests/parser/comment1.0 new file mode 100644 index 0000000..21e7ade --- /dev/null +++ b/bin/sh/tests/parser/comment1.0 @@ -0,0 +1,3 @@ +# $FreeBSD$ + +${SH} -c '#' diff --git a/bin/sh/tests/parser/comment2.42 b/bin/sh/tests/parser/comment2.42 new file mode 100644 index 0000000..196b733 --- /dev/null +++ b/bin/sh/tests/parser/comment2.42 @@ -0,0 +1,4 @@ +# $FreeBSD$ + +${SH} -c '# +exit 42' diff --git a/bin/sh/tests/parser/nul1.0 b/bin/sh/tests/parser/nul1.0 new file mode 100644 index 0000000..49c5ab1 --- /dev/null +++ b/bin/sh/tests/parser/nul1.0 @@ -0,0 +1,12 @@ +# $FreeBSD$ +# Although POSIX does not specify the effect of NUL bytes in scripts, +# we ignore them. + +{ + printf 'v=%03000d\0%02000d' 7 2 + dd if=/dev/zero bs=1000 count=1 status=none + printf '1 w=%03000d%02000d1\0\n' 7 2 + printf '\0l\0v\0=\0$\0{\0#\0v\0}\n' + printf '\0l\0w\0=\0\0$\0{\0#\0w}\0\0\0\n' + printf '[ "$lv.$lw.$v" = "5001.5001.$w" ]\n' +} | ${SH} |