summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2011-07-17 21:42:22 +0000
committermm <mm@FreeBSD.org>2011-07-17 21:42:22 +0000
commit84c56da91a08ce9f1a669fa732a156e36b3ad358 (patch)
treee2aa60b473bd88d42e965988a7bd13041fd17954 /usr.bin
parent867c8ddd4db0c581c7d6f04f5317cdc34c07dd5c (diff)
downloadFreeBSD-src-84c56da91a08ce9f1a669fa732a156e36b3ad358.zip
FreeBSD-src-84c56da91a08ce9f1a669fa732a156e36b3ad358.tar.gz
Update bsdcpio to 2.8.4
Use common code from lib/libarchive/libarchive_fe Approved by: kientzle MFC after: 2 weeks
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/cpio/Makefile15
-rw-r--r--usr.bin/cpio/cmdline.c10
-rw-r--r--usr.bin/cpio/config_freebsd.h1
-rw-r--r--usr.bin/cpio/cpio.c146
-rw-r--r--usr.bin/cpio/cpio.h2
-rw-r--r--usr.bin/cpio/line_reader.c171
-rw-r--r--usr.bin/cpio/matching.c284
-rw-r--r--usr.bin/cpio/matching.h46
-rw-r--r--usr.bin/cpio/pathmatch.c255
-rw-r--r--usr.bin/cpio/test/Makefile23
-rw-r--r--usr.bin/cpio/test/main.c2030
-rw-r--r--usr.bin/cpio/test/test.h216
-rw-r--r--usr.bin/cpio/test/test_0.c6
-rw-r--r--usr.bin/cpio/test/test_basic.c177
-rw-r--r--usr.bin/cpio/test/test_cmdline.c107
-rw-r--r--usr.bin/cpio/test/test_format_newc.c146
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat.c122
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu17
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu17
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu17
-rw-r--r--usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu74
-rw-r--r--usr.bin/cpio/test/test_option_B_upper.c (renamed from usr.bin/cpio/test/test_option_B.c)12
-rw-r--r--usr.bin/cpio/test/test_option_C_upper.c (renamed from usr.bin/cpio/pathmatch.h)48
-rw-r--r--usr.bin/cpio/test/test_option_J_upper.c (renamed from usr.bin/cpio/err.h)47
-rw-r--r--usr.bin/cpio/test/test_option_L_upper.c (renamed from usr.bin/cpio/test/test_option_L.c)75
-rw-r--r--usr.bin/cpio/test/test_option_Z_upper.c (renamed from usr.bin/cpio/line_reader.h)41
-rw-r--r--usr.bin/cpio/test/test_option_a.c25
-rw-r--r--usr.bin/cpio/test/test_option_c.c108
-rw-r--r--usr.bin/cpio/test/test_option_d.c26
-rw-r--r--usr.bin/cpio/test/test_option_f.c40
-rw-r--r--usr.bin/cpio/test/test_option_help.c3
-rw-r--r--usr.bin/cpio/test/test_option_l.c (renamed from usr.bin/cpio/test/test_option_ell.c)24
-rw-r--r--usr.bin/cpio/test/test_option_lzma.c (renamed from usr.bin/cpio/err.c)76
-rw-r--r--usr.bin/cpio/test/test_option_m.c25
-rw-r--r--usr.bin/cpio/test/test_option_t.c22
-rw-r--r--usr.bin/cpio/test/test_option_u.c17
-rw-r--r--usr.bin/cpio/test/test_option_version.c12
-rw-r--r--usr.bin/cpio/test/test_option_y.c30
-rw-r--r--usr.bin/cpio/test/test_option_z.c29
-rw-r--r--usr.bin/cpio/test/test_owner_parse.c52
-rw-r--r--usr.bin/cpio/test/test_passthrough_dotdot.c45
-rw-r--r--usr.bin/cpio/test/test_passthrough_reverse.c55
-rw-r--r--usr.bin/cpio/test/test_pathmatch.c280
43 files changed, 2692 insertions, 2282 deletions
diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile
index fe339cd..5868e52 100644
--- a/usr.bin/cpio/Makefile
+++ b/usr.bin/cpio/Makefile
@@ -3,17 +3,24 @@
.include <bsd.own.mk>
PROG= bsdcpio
-BSDCPIO_VERSION_STRING=2.8.3
-SRCS= cpio.c cmdline.c err.c line_reader.c matching.c pathmatch.c
+BSDCPIO_VERSION_STRING=2.8.4
+
+SRCS= cpio.c cmdline.c
+
+.PATH: ${.CURDIR}/../../lib/libarchive/libarchive_fe
+SRCS+= err.c line_reader.c matching.c pathmatch.c
+
CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\"
CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
+CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../lib/libarchive/libarchive_fe
+
.ifdef RELEASE_CRUNCH
# FreeBSD's installer uses cpio in crunched binaries that are
# statically linked, cannot use -lcrypto, and are size sensitive.
CFLAGS+= -DSMALLER
.endif
-DPADD= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2} ${LIBMD} ${LIBLZMA}
-LDADD= -larchive -lz -lbz2 -lmd -llzma
+DPADD= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2} ${LIBMD} ${LIBLZMA} ${LIBBSDXML}
+LDADD= -larchive -lz -lbz2 -lmd -llzma -lbsdxml
.if ${MK_OPENSSL} != "no"
DPADD+= ${LIBCRYPTO}
LDADD+= -lcrypto
diff --git a/usr.bin/cpio/cmdline.c b/usr.bin/cpio/cmdline.c
index f0e8ba20..687fa62 100644
--- a/usr.bin/cpio/cmdline.c
+++ b/usr.bin/cpio/cmdline.c
@@ -175,7 +175,7 @@ cpio_getopt(struct cpio *cpio)
/* Otherwise, pick up the next word. */
opt_word = *cpio->argv;
if (opt_word == NULL) {
- warnc(0,
+ lafe_warnc(0,
"Option -%c requires an argument",
opt);
return ('?');
@@ -226,13 +226,13 @@ cpio_getopt(struct cpio *cpio)
/* Fail if there wasn't a unique match. */
if (match == NULL) {
- warnc(0,
+ lafe_warnc(0,
"Option %s%s is not supported",
long_prefix, opt_word);
return ('?');
}
if (match2 != NULL) {
- warnc(0,
+ lafe_warnc(0,
"Ambiguous option %s%s (matches --%s and --%s)",
long_prefix, opt_word, match->name, match2->name);
return ('?');
@@ -244,7 +244,7 @@ cpio_getopt(struct cpio *cpio)
if (cpio->optarg == NULL) {
cpio->optarg = *cpio->argv;
if (cpio->optarg == NULL) {
- warnc(0,
+ lafe_warnc(0,
"Option %s%s requires an argument",
long_prefix, match->name);
return ('?');
@@ -255,7 +255,7 @@ cpio_getopt(struct cpio *cpio)
} else {
/* Argument forbidden: fail if there is one. */
if (cpio->optarg != NULL) {
- warnc(0,
+ lafe_warnc(0,
"Option %s%s does not allow an argument",
long_prefix, match->name);
return ('?');
diff --git a/usr.bin/cpio/config_freebsd.h b/usr.bin/cpio/config_freebsd.h
index ec4e441..bf24b9e 100644
--- a/usr.bin/cpio/config_freebsd.h
+++ b/usr.bin/cpio/config_freebsd.h
@@ -53,4 +53,5 @@
#define HAVE_UNSIGNED_LONG_LONG 1
#define HAVE_UTIME_H 1
#define HAVE_UTIMES 1
+#define HAVE_WCSCMP 1
diff --git a/usr.bin/cpio/cpio.c b/usr.bin/cpio/cpio.c
index ab32224..cd81050 100644
--- a/usr.bin/cpio/cpio.c
+++ b/usr.bin/cpio/cpio.c
@@ -136,19 +136,19 @@ main(int argc, char *argv[])
cpio->buff = buff;
cpio->buff_size = sizeof(buff);
- /* Need progname before calling warnc. */
+ /* Need lafe_progname before calling lafe_warnc. */
if (*argv == NULL)
- progname = "bsdcpio";
+ lafe_progname = "bsdcpio";
else {
#if defined(_WIN32) && !defined(__CYGWIN__)
- progname = strrchr(*argv, '\\');
+ lafe_progname = strrchr(*argv, '\\');
#else
- progname = strrchr(*argv, '/');
+ lafe_progname = strrchr(*argv, '/');
#endif
- if (progname != NULL)
- progname++;
+ if (lafe_progname != NULL)
+ lafe_progname++;
else
- progname = *argv;
+ lafe_progname = *argv;
}
cpio->uid_override = -1;
@@ -189,7 +189,7 @@ main(int argc, char *argv[])
case 'C': /* NetBSD/OpenBSD */
cpio->bytes_per_block = atoi(cpio->optarg);
if (cpio->bytes_per_block <= 0)
- errc(1, 0, "Invalid blocksize %s", cpio->optarg);
+ lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg);
break;
case 'c': /* POSIX 1997 */
cpio->format = "odc";
@@ -198,14 +198,14 @@ main(int argc, char *argv[])
cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
break;
case 'E': /* NetBSD/OpenBSD */
- include_from_file(&cpio->matching,
+ lafe_include_from_file(&cpio->matching,
cpio->optarg, cpio->option_null);
break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */
cpio->filename = cpio->optarg;
break;
case 'f': /* POSIX 1997 */
- exclude(&cpio->matching, cpio->optarg);
+ lafe_exclude(&cpio->matching, cpio->optarg);
break;
case 'H': /* GNU cpio (also --format) */
cpio->format = cpio->optarg;
@@ -218,7 +218,7 @@ main(int argc, char *argv[])
break;
case 'i': /* POSIX 1997 */
if (cpio->mode != '\0')
- errc(1, 0,
+ lafe_errc(1, 0,
"Cannot use both -i and -%c", cpio->mode);
cpio->mode = opt;
break;
@@ -255,13 +255,13 @@ main(int argc, char *argv[])
break;
case 'o': /* POSIX 1997 */
if (cpio->mode != '\0')
- errc(1, 0,
+ lafe_errc(1, 0,
"Cannot use both -o and -%c", cpio->mode);
cpio->mode = opt;
break;
case 'p': /* POSIX 1997 */
if (cpio->mode != '\0')
- errc(1, 0,
+ lafe_errc(1, 0,
"Cannot use both -p and -%c", cpio->mode);
cpio->mode = opt;
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
@@ -277,7 +277,7 @@ main(int argc, char *argv[])
* also; use that to set [ug]name_override. */
errmsg = owner_parse(cpio->optarg, &uid, &gid);
if (errmsg) {
- warnc(-1, "%s", errmsg);
+ lafe_warnc(-1, "%s", errmsg);
usage();
}
if (uid != -1) {
@@ -335,16 +335,16 @@ main(int argc, char *argv[])
cpio->mode = 'i';
/* -t requires -i */
if (cpio->option_list && cpio->mode != 'i')
- errc(1, 0, "Option -t requires -i");
+ lafe_errc(1, 0, "Option -t requires -i");
/* -n requires -it */
if (cpio->option_numeric_uid_gid && !cpio->option_list)
- errc(1, 0, "Option -n requires -it");
+ lafe_errc(1, 0, "Option -n requires -it");
/* Can only specify format when writing */
if (cpio->format != NULL && cpio->mode != 'o')
- errc(1, 0, "Option --format requires -o");
+ lafe_errc(1, 0, "Option --format requires -o");
/* -l requires -p */
if (cpio->option_link && cpio->mode != 'p')
- errc(1, 0, "Option -l requires -p");
+ lafe_errc(1, 0, "Option -l requires -p");
/* TODO: Flag other nonsensical combinations. */
switch (cpio->mode) {
@@ -358,7 +358,7 @@ main(int argc, char *argv[])
break;
case 'i':
while (*cpio->argv != NULL) {
- include(&cpio->matching, *cpio->argv);
+ lafe_include(&cpio->matching, *cpio->argv);
--cpio->argc;
++cpio->argv;
}
@@ -369,12 +369,12 @@ main(int argc, char *argv[])
break;
case 'p':
if (*cpio->argv == NULL || **cpio->argv == '\0')
- errc(1, 0,
+ lafe_errc(1, 0,
"-p mode requires a target directory");
mode_pass(cpio, *cpio->argv);
break;
default:
- errc(1, 0,
+ lafe_errc(1, 0,
"Must specify at least one of -i, -o, or -p");
}
@@ -388,7 +388,7 @@ usage(void)
{
const char *p;
- p = progname;
+ p = lafe_progname;
fprintf(stderr, "Brief Usage:\n");
fprintf(stderr, " List: %s -it < archive\n", p);
@@ -426,7 +426,7 @@ long_help(void)
const char *prog;
const char *p;
- prog = progname;
+ prog = lafe_progname;
fflush(stderr);
@@ -459,16 +459,16 @@ static void
mode_out(struct cpio *cpio)
{
struct archive_entry *entry, *spare;
- struct line_reader *lr;
+ struct lafe_line_reader *lr;
const char *p;
int r;
if (cpio->option_append)
- errc(1, 0, "Append mode not yet supported.");
+ lafe_errc(1, 0, "Append mode not yet supported.");
cpio->archive_read_disk = archive_read_disk_new();
if (cpio->archive_read_disk == NULL)
- errc(1, 0, "Failed to allocate archive object");
+ lafe_errc(1, 0, "Failed to allocate archive object");
if (cpio->option_follow_links)
archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
else
@@ -477,7 +477,7 @@ mode_out(struct cpio *cpio)
cpio->archive = archive_write_new();
if (cpio->archive == NULL)
- errc(1, 0, "Failed to allocate archive object");
+ lafe_errc(1, 0, "Failed to allocate archive object");
switch (cpio->compress) {
case 'J':
r = archive_write_set_compression_xz(cpio->archive);
@@ -499,10 +499,10 @@ mode_out(struct cpio *cpio)
break;
}
if (r < ARCHIVE_WARN)
- errc(1, 0, "Requested compression not available");
+ lafe_errc(1, 0, "Requested compression not available");
r = archive_write_set_format_by_name(cpio->archive, cpio->format);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(cpio->archive));
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block);
cpio->linkresolver = archive_entry_linkresolver_new();
archive_entry_linkresolver_set_strategy(cpio->linkresolver,
@@ -513,11 +513,11 @@ mode_out(struct cpio *cpio)
*/
r = archive_write_open_file(cpio->archive, cpio->filename);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(cpio->archive));
- lr = line_reader("-", cpio->option_null);
- while ((p = line_reader_next(lr)) != NULL)
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
+ lr = lafe_line_reader("-", cpio->option_null);
+ while ((p = lafe_line_reader_next(lr)) != NULL)
file_to_archive(cpio, p);
- line_reader_free(lr);
+ lafe_line_reader_free(lr);
/*
* The hardlink detection may have queued up a couple of entries
@@ -534,7 +534,7 @@ mode_out(struct cpio *cpio)
r = archive_write_close(cpio->archive);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(cpio->archive));
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
if (!cpio->quiet) {
int64_t blocks =
@@ -566,15 +566,15 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
*/
entry = archive_entry_new();
if (entry == NULL)
- errc(1, 0, "Couldn't allocate entry");
+ lafe_errc(1, 0, "Couldn't allocate entry");
archive_entry_copy_sourcepath(entry, srcpath);
r = archive_read_disk_entry_from_file(cpio->archive_read_disk,
entry, -1, NULL);
if (r < ARCHIVE_FAILED)
- errc(1, 0, "%s",
+ lafe_errc(1, 0, "%s",
archive_error_string(cpio->archive_read_disk));
if (r < ARCHIVE_OK)
- warnc(0, "%s",
+ lafe_warnc(0, "%s",
archive_error_string(cpio->archive_read_disk));
if (r <= ARCHIVE_FAILED) {
cpio->return_value = 1;
@@ -607,7 +607,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
free(cpio->pass_destpath);
cpio->pass_destpath = malloc(cpio->pass_destpath_alloc);
if (cpio->pass_destpath == NULL)
- errc(1, ENOMEM,
+ lafe_errc(1, ENOMEM,
"Can't allocate path buffer");
}
strcpy(cpio->pass_destpath, cpio->destdir);
@@ -673,7 +673,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
/* Save the original entry in case we need it later. */
t = archive_entry_clone(entry);
if (t == NULL)
- errc(1, ENOMEM, "Can't create link");
+ lafe_errc(1, ENOMEM, "Can't create link");
/* Note: link(2) doesn't create parent directories,
* so we use archive_write_header() instead as a
* convenience. */
@@ -683,7 +683,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
r = archive_write_header(cpio->archive, t);
archive_entry_free(t);
if (r != ARCHIVE_OK)
- warnc(archive_errno(cpio->archive),
+ lafe_warnc(archive_errno(cpio->archive),
"%s", archive_error_string(cpio->archive));
if (r == ARCHIVE_FATAL)
exit(1);
@@ -691,7 +691,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) {
/* Cross-device link: Just fall through and use
* the original entry to copy the file over. */
- warnc(0, "Copying file instead");
+ lafe_warnc(0, "Copying file instead");
} else
#endif
return (0);
@@ -705,7 +705,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
if (archive_entry_size(entry) > 0) {
fd = open(srcpath, O_RDONLY | O_BINARY);
if (fd < 0) {
- warnc(errno,
+ lafe_warnc(errno,
"%s: could not open file", srcpath);
goto cleanup;
}
@@ -717,7 +717,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
r = archive_write_header(cpio->archive, entry);
if (r != ARCHIVE_OK)
- warnc(archive_errno(cpio->archive),
+ lafe_warnc(archive_errno(cpio->archive),
"%s: %s",
srcpath,
archive_error_string(cpio->archive));
@@ -731,10 +731,10 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
r = archive_write_data(cpio->archive,
cpio->buff, bytes_read);
if (r < 0)
- errc(1, archive_errno(cpio->archive),
+ lafe_errc(1, archive_errno(cpio->archive),
"%s", archive_error_string(cpio->archive));
if (r < bytes_read) {
- warnc(0,
+ lafe_warnc(0,
"Truncated write; file may have grown while being archived.");
}
bytes_read = read(fd, cpio->buff, cpio->buff_size);
@@ -763,7 +763,7 @@ restore_time(struct cpio *cpio, struct archive_entry *entry,
(void)name; /* UNUSED */
if (!warned)
- warnc(0, "Can't restore access times on this platform");
+ lafe_warnc(0, "Can't restore access times on this platform");
warned = 1;
return (fd);
#else
@@ -801,7 +801,7 @@ restore_time(struct cpio *cpio, struct archive_entry *entry,
if ((AE_IFLNK != archive_entry_filetype(entry))
&& utimes(name, times) != 0)
#endif
- warnc(errno, "Can't update time for %s", name);
+ lafe_warnc(errno, "Can't update time for %s", name);
#endif
return (fd);
}
@@ -818,28 +818,28 @@ mode_in(struct cpio *cpio)
ext = archive_write_disk_new();
if (ext == NULL)
- errc(1, 0, "Couldn't allocate restore object");
+ lafe_errc(1, 0, "Couldn't allocate restore object");
r = archive_write_disk_set_options(ext, cpio->extract_flags);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(ext));
+ lafe_errc(1, 0, "%s", archive_error_string(ext));
a = archive_read_new();
if (a == NULL)
- errc(1, 0, "Couldn't allocate archive object");
+ lafe_errc(1, 0, "Couldn't allocate archive object");
archive_read_support_compression_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
- errc(1, archive_errno(a),
+ lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
- errc(1, archive_errno(a),
+ lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
}
- if (excluded(cpio->matching, archive_entry_pathname(entry)))
+ if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
continue;
if (cpio->option_rename) {
destpath = cpio_rename(archive_entry_pathname(entry));
@@ -867,10 +867,10 @@ mode_in(struct cpio *cpio)
}
r = archive_read_close(a);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(a));
+ lafe_errc(1, 0, "%s", archive_error_string(a));
r = archive_write_close(ext);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(ext));
+ lafe_errc(1, 0, "%s", archive_error_string(ext));
if (!cpio->quiet) {
int64_t blocks = (archive_position_uncompressed(a) + 511)
/ 512;
@@ -899,13 +899,13 @@ extract_data(struct archive *ar, struct archive *aw)
if (r == ARCHIVE_EOF)
return (ARCHIVE_OK);
if (r != ARCHIVE_OK) {
- warnc(archive_errno(ar),
+ lafe_warnc(archive_errno(ar),
"%s", archive_error_string(ar));
exit(1);
}
r = archive_write_data_block(aw, block, size, offset);
if (r != ARCHIVE_OK) {
- warnc(archive_errno(aw),
+ lafe_warnc(archive_errno(aw),
"%s", archive_error_string(aw));
return (r);
}
@@ -921,22 +921,22 @@ mode_list(struct cpio *cpio)
a = archive_read_new();
if (a == NULL)
- errc(1, 0, "Couldn't allocate archive object");
+ lafe_errc(1, 0, "Couldn't allocate archive object");
archive_read_support_compression_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
- errc(1, archive_errno(a),
+ lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
- errc(1, archive_errno(a),
+ lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
}
- if (excluded(cpio->matching, archive_entry_pathname(entry)))
+ if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
continue;
if (cpio->verbose)
list_item_verbose(cpio, entry);
@@ -945,7 +945,7 @@ mode_list(struct cpio *cpio)
}
r = archive_read_close(a);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(a));
+ lafe_errc(1, 0, "%s", archive_error_string(a));
if (!cpio->quiet) {
int64_t blocks = (archive_position_uncompressed(a) + 511)
/ 512;
@@ -1040,7 +1040,7 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
static void
mode_pass(struct cpio *cpio, const char *destdir)
{
- struct line_reader *lr;
+ struct lafe_line_reader *lr;
const char *p;
int r;
@@ -1052,31 +1052,31 @@ mode_pass(struct cpio *cpio, const char *destdir)
cpio->archive = archive_write_disk_new();
if (cpio->archive == NULL)
- errc(1, 0, "Failed to allocate archive object");
+ lafe_errc(1, 0, "Failed to allocate archive object");
r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(cpio->archive));
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
cpio->linkresolver = archive_entry_linkresolver_new();
archive_write_disk_set_standard_lookup(cpio->archive);
cpio->archive_read_disk = archive_read_disk_new();
if (cpio->archive_read_disk == NULL)
- errc(1, 0, "Failed to allocate archive object");
+ lafe_errc(1, 0, "Failed to allocate archive object");
if (cpio->option_follow_links)
archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
else
archive_read_disk_set_symlink_physical(cpio->archive_read_disk);
archive_read_disk_set_standard_lookup(cpio->archive_read_disk);
- lr = line_reader("-", cpio->option_null);
- while ((p = line_reader_next(lr)) != NULL)
+ lr = lafe_line_reader("-", cpio->option_null);
+ while ((p = lafe_line_reader_next(lr)) != NULL)
file_to_archive(cpio, p);
- line_reader_free(lr);
+ lafe_line_reader_free(lr);
archive_entry_linkresolver_free(cpio->linkresolver);
r = archive_write_close(cpio->archive);
if (r != ARCHIVE_OK)
- errc(1, 0, "%s", archive_error_string(cpio->archive));
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
if (!cpio->quiet) {
int64_t blocks =
@@ -1160,7 +1160,7 @@ lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable,
if (*name_cache_variable == NULL) {
*name_cache_variable = malloc(sizeof(struct name_cache));
if (*name_cache_variable == NULL)
- errc(1, ENOMEM, "No more memory");
+ lafe_errc(1, ENOMEM, "No more memory");
memset(*name_cache_variable, 0, sizeof(struct name_cache));
(*name_cache_variable)->size = name_cache_size;
}
@@ -1217,7 +1217,7 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
if (pwent == NULL) {
*name = NULL;
if (errno != 0 && errno != ENOENT)
- warnc(errno, "getpwuid(%d) failed", id);
+ lafe_warnc(errno, "getpwuid(%d) failed", id);
return (errno);
}
@@ -1244,7 +1244,7 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
if (grent == NULL) {
*name = NULL;
if (errno != 0)
- warnc(errno, "getgrgid(%d) failed", id);
+ lafe_warnc(errno, "getgrgid(%d) failed", id);
return (errno);
}
diff --git a/usr.bin/cpio/cpio.h b/usr.bin/cpio/cpio.h
index 2afa8f2..2d5b548 100644
--- a/usr.bin/cpio/cpio.h
+++ b/usr.bin/cpio/cpio.h
@@ -88,7 +88,7 @@ struct cpio {
struct name_cache *gname_cache;
/* Work data. */
- struct matching *matching;
+ struct lafe_matching *matching;
char *buff;
size_t buff_size;
};
diff --git a/usr.bin/cpio/line_reader.c b/usr.bin/cpio/line_reader.c
deleted file mode 100644
index 8461941..0000000
--- a/usr.bin/cpio/line_reader.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*-
- * Copyright (c) 2008 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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.
- */
-
-#include "cpio_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "err.h"
-#include "line_reader.h"
-
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
-#define strdup _strdup
-#endif
-
-/*
- * Read lines from file and do something with each one. If option_null
- * is set, lines are terminated with zero bytes; otherwise, they're
- * terminated with newlines.
- *
- * This uses a self-sizing buffer to handle arbitrarily-long lines.
- */
-struct line_reader {
- FILE *f;
- char *buff, *buff_end, *line_start, *line_end, *p;
- char *pathname;
- size_t buff_length;
- int nullSeparator; /* Lines separated by null, not CR/CRLF/etc. */
- int ret;
-};
-
-struct line_reader *
-line_reader(const char *pathname, int nullSeparator)
-{
- struct line_reader *lr;
-
- lr = calloc(1, sizeof(*lr));
- if (lr == NULL)
- errc(1, ENOMEM, "Can't open %s", pathname);
-
- lr->nullSeparator = nullSeparator;
- lr->pathname = strdup(pathname);
-
- if (strcmp(pathname, "-") == 0)
- lr->f = stdin;
- else
- lr->f = fopen(pathname, "r");
- if (lr->f == NULL)
- errc(1, errno, "Couldn't open %s", pathname);
- lr->buff_length = 8192;
- lr->buff = malloc(lr->buff_length);
- if (lr->buff == NULL)
- errc(1, ENOMEM, "Can't read %s", pathname);
- lr->line_start = lr->line_end = lr->buff_end = lr->buff;
-
- return (lr);
-}
-
-const char *
-line_reader_next(struct line_reader *lr)
-{
- size_t bytes_wanted, bytes_read, new_buff_size;
- char *line_start, *p;
-
- for (;;) {
- /* If there's a line in the buffer, return it immediately. */
- while (lr->line_end < lr->buff_end) {
- if (lr->nullSeparator) {
- if (*lr->line_end == '\0') {
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- return (line_start);
- }
- } else if (*lr->line_end == '\x0a' || *lr->line_end == '\x0d') {
- *lr->line_end = '\0';
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- if (line_start[0] != '\0')
- return (line_start);
- }
- lr->line_end++;
- }
-
- /* If we're at end-of-file, process the final data. */
- if (lr->f == NULL) {
- /* If there's more text, return one last line. */
- if (lr->line_end > lr->line_start) {
- *lr->line_end = '\0';
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- return (line_start);
- }
- /* Otherwise, we're done. */
- return (NULL);
- }
-
- /* Buffer only has part of a line. */
- if (lr->line_start > lr->buff) {
- /* Move a leftover fractional line to the beginning. */
- memmove(lr->buff, lr->line_start,
- lr->buff_end - lr->line_start);
- lr->buff_end -= lr->line_start - lr->buff;
- lr->line_end -= lr->line_start - lr->buff;
- lr->line_start = lr->buff;
- } else {
- /* Line is too big; enlarge the buffer. */
- new_buff_size = lr->buff_length * 2;
- if (new_buff_size <= lr->buff_length)
- errc(1, ENOMEM,
- "Line too long in %s", lr->pathname);
- lr->buff_length = new_buff_size;
- p = realloc(lr->buff, new_buff_size);
- if (p == NULL)
- errc(1, ENOMEM,
- "Line too long in %s", lr->pathname);
- lr->buff_end = p + (lr->buff_end - lr->buff);
- lr->line_end = p + (lr->line_end - lr->buff);
- lr->line_start = lr->buff = p;
- }
-
- /* Get some more data into the buffer. */
- bytes_wanted = lr->buff + lr->buff_length - lr->buff_end;
- bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f);
- lr->buff_end += bytes_read;
-
- if (ferror(lr->f))
- errc(1, errno, "Can't read %s", lr->pathname);
- if (feof(lr->f)) {
- if (lr->f != stdin)
- fclose(lr->f);
- lr->f = NULL;
- }
- }
-}
-
-void
-line_reader_free(struct line_reader *lr)
-{
- free(lr->buff);
- free(lr->pathname);
- free(lr);
-}
diff --git a/usr.bin/cpio/matching.c b/usr.bin/cpio/matching.c
deleted file mode 100644
index 0fd2b6a..0000000
--- a/usr.bin/cpio/matching.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- */
-
-#include "cpio_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "err.h"
-#include "line_reader.h"
-#include "matching.h"
-#include "pathmatch.h"
-
-struct match {
- struct match *next;
- int matches;
- char pattern[1];
-};
-
-struct matching {
- struct match *exclusions;
- int exclusions_count;
- struct match *inclusions;
- int inclusions_count;
- int inclusions_unmatched_count;
-};
-
-static void add_pattern(struct match **list, const char *pattern);
-static void initialize_matching(struct matching **);
-static int match_exclusion(struct match *, const char *pathname);
-static int match_inclusion(struct match *, const char *pathname);
-
-/*
- * The matching logic here needs to be re-thought. I started out to
- * try to mimic gtar's matching logic, but it's not entirely
- * consistent. In particular 'tar -t' and 'tar -x' interpret patterns
- * on the command line as anchored, but --exclude doesn't.
- */
-
-/*
- * Utility functions to manage exclusion/inclusion patterns
- */
-
-int
-exclude(struct matching **matching, const char *pattern)
-{
-
- if (*matching == NULL)
- initialize_matching(matching);
- add_pattern(&((*matching)->exclusions), pattern);
- (*matching)->exclusions_count++;
- return (0);
-}
-
-int
-exclude_from_file(struct matching **matching, const char *pathname)
-{
- struct line_reader *lr;
- const char *p;
- int ret = 0;
-
- lr = line_reader(pathname, 0);
- while ((p = line_reader_next(lr)) != NULL) {
- if (exclude(matching, p) != 0)
- ret = -1;
- }
- line_reader_free(lr);
- return (ret);
-}
-
-int
-include(struct matching **matching, const char *pattern)
-{
-
- if (*matching == NULL)
- initialize_matching(matching);
- add_pattern(&((*matching)->inclusions), pattern);
- (*matching)->inclusions_count++;
- (*matching)->inclusions_unmatched_count++;
- return (0);
-}
-
-int
-include_from_file(struct matching **matching, const char *pathname,
- int nullSeparator)
-{
- struct line_reader *lr;
- const char *p;
- int ret = 0;
-
- lr = line_reader(pathname, nullSeparator);
- while ((p = line_reader_next(lr)) != NULL) {
- if (include(matching, p) != 0)
- ret = -1;
- }
- line_reader_free(lr);
- return (ret);
-}
-
-static void
-add_pattern(struct match **list, const char *pattern)
-{
- struct match *match;
- size_t len;
-
- len = strlen(pattern);
- match = malloc(sizeof(*match) + len + 1);
- if (match == NULL)
- errc(1, errno, "Out of memory");
- strcpy(match->pattern, pattern);
- /* Both "foo/" and "foo" should match "foo/bar". */
- if (len && match->pattern[len - 1] == '/')
- match->pattern[strlen(match->pattern)-1] = '\0';
- match->next = *list;
- *list = match;
- match->matches = 0;
-}
-
-
-int
-excluded(struct matching *matching, const char *pathname)
-{
- struct match *match;
- struct match *matched;
-
- if (matching == NULL)
- return (0);
-
- /* Exclusions take priority */
- for (match = matching->exclusions; match != NULL; match = match->next){
- if (match_exclusion(match, pathname))
- return (1);
- }
-
- /* Then check for inclusions */
- matched = NULL;
- for (match = matching->inclusions; match != NULL; match = match->next){
- if (match_inclusion(match, pathname)) {
- /*
- * If this pattern has never been matched,
- * then we're done.
- */
- if (match->matches == 0) {
- match->matches++;
- matching->inclusions_unmatched_count--;
- return (0);
- }
- /*
- * Otherwise, remember the match but keep checking
- * in case we can tick off an unmatched pattern.
- */
- matched = match;
- }
- }
- /*
- * We didn't find a pattern that had never been matched, but
- * we did find a match, so count it and exit.
- */
- if (matched != NULL) {
- matched->matches++;
- return (0);
- }
-
- /* If there were inclusions, default is to exclude. */
- if (matching->inclusions != NULL)
- return (1);
-
- /* No explicit inclusions, default is to match. */
- return (0);
-}
-
-/*
- * This is a little odd, but it matches the default behavior of
- * gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar'
- *
- */
-static int
-match_exclusion(struct match *match, const char *pathname)
-{
- return (pathmatch(match->pattern,
- pathname,
- PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
-}
-
-/*
- * Again, mimic gtar: inclusions are always anchored (have to match
- * the beginning of the path) even though exclusions are not anchored.
- */
-static int
-match_inclusion(struct match *match, const char *pathname)
-{
-#if 0
- return (pathmatch(match->pattern, pathname, 0));
-#else
- return (pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END));
-#endif
-}
-
-void
-cleanup_exclusions(struct matching **matching)
-{
- struct match *p, *q;
-
- if (*matching == NULL)
- return;
-
- for (p = (*matching)->inclusions; p != NULL; ) {
- q = p;
- p = p->next;
- free(q);
- }
-
- for (p = (*matching)->exclusions; p != NULL; ) {
- q = p;
- p = p->next;
- free(q);
- }
-
- free(*matching);
- *matching = NULL;
-}
-
-static void
-initialize_matching(struct matching **matching)
-{
- *matching = calloc(sizeof(**matching), 1);
- if (*matching == NULL)
- errc(1, errno, "No memory");
-}
-
-int
-unmatched_inclusions(struct matching *matching)
-{
-
- if (matching == NULL)
- return (0);
- return (matching->inclusions_unmatched_count);
-}
-
-int
-unmatched_inclusions_warn(struct matching *matching, const char *msg)
-{
- struct match *p;
-
- if (matching == NULL)
- return (0);
-
- for (p = matching->inclusions; p != NULL; p = p->next) {
- if (p->matches == 0)
- warnc(0, "%s: %s", p->pattern, msg);
- }
-
- return (matching->inclusions_unmatched_count);
-}
diff --git a/usr.bin/cpio/matching.h b/usr.bin/cpio/matching.h
deleted file mode 100644
index e98e82e..0000000
--- a/usr.bin/cpio/matching.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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$
- */
-
-#ifndef MATCHING_H
-#define MATCHING_H
-
-struct matching;
-
-int exclude(struct matching **matching, const char *pattern);
-int exclude_from_file(struct matching **matching,
- const char *pathname);
-int include(struct matching **matching, const char *pattern);
-int include_from_file(struct matching **matching,
- const char *pathname, int nullSeparator);
-
-int excluded(struct matching *, const char *pathname);
-void cleanup_exclusions(struct matching **);
-int unmatched_inclusions(struct matching *);
-int unmatched_inclusions_warn(struct matching *, const char *msg);
-
-#endif
diff --git a/usr.bin/cpio/pathmatch.c b/usr.bin/cpio/pathmatch.c
deleted file mode 100644
index 75f9095..0000000
--- a/usr.bin/cpio/pathmatch.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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.
- */
-
-#include "cpio_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "pathmatch.h"
-
-/*
- * Check whether a character 'c' is matched by a list specification [...]:
- * * Leading '!' negates the class.
- * * <char>-<char> is a range of characters
- * * \<char> removes any special meaning for <char>
- *
- * Some interesting boundary cases:
- * a-d-e is one range (a-d) followed by two single characters - and e.
- * \a-\d is same as a-d
- * a\-d is three single characters: a, d, -
- * Trailing - is not special (so [a-] is two characters a and -).
- * Initial - is not special ([a-] is same as [-a] is same as [\\-a])
- * This function never sees a trailing \.
- * [] always fails
- * [!] always succeeds
- */
-static int
-pm_list(const char *start, const char *end, const char c, int flags)
-{
- const char *p = start;
- char rangeStart = '\0', nextRangeStart;
- int match = 1, nomatch = 0;
-
- /* This will be used soon... */
- (void)flags; /* UNUSED */
-
- /* If this is a negated class, return success for nomatch. */
- if (*p == '!' && p < end) {
- match = 0;
- nomatch = 1;
- ++p;
- }
-
- while (p < end) {
- nextRangeStart = '\0';
- switch (*p) {
- case '-':
- /* Trailing or initial '-' is not special. */
- if ((rangeStart == '\0') || (p == end - 1)) {
- if (*p == c)
- return (match);
- } else {
- char rangeEnd = *++p;
- if (rangeEnd == '\\')
- rangeEnd = *++p;
- if ((rangeStart <= c) && (c <= rangeEnd))
- return (match);
- }
- break;
- case '\\':
- ++p;
- /* Fall through */
- default:
- if (*p == c)
- return (match);
- nextRangeStart = *p; /* Possible start of range. */
- }
- rangeStart = nextRangeStart;
- ++p;
- }
- return (nomatch);
-}
-
-/*
- * If s is pointing to "./", ".//", "./././" or the like, skip it.
- */
-static const char *
-pm_slashskip(const char *s) {
- while ((*s == '/')
- || (s[0] == '.' && s[1] == '/')
- || (s[0] == '.' && s[1] == '\0'))
- ++s;
- return (s);
-}
-
-static int
-pm(const char *p, const char *s, int flags)
-{
- const char *end;
-
- /*
- * Ignore leading './', './/', '././', etc.
- */
- if (s[0] == '.' && s[1] == '/')
- s = pm_slashskip(s + 1);
- if (p[0] == '.' && p[1] == '/')
- p = pm_slashskip(p + 1);
-
- for (;;) {
- switch (*p) {
- case '\0':
- if (s[0] == '/') {
- if (flags & PATHMATCH_NO_ANCHOR_END)
- return (1);
- /* "dir" == "dir/" == "dir/." */
- s = pm_slashskip(s);
- }
- return (*s == '\0');
- case '?':
- /* ? always succeds, unless we hit end of 's' */
- if (*s == '\0')
- return (0);
- break;
- case '*':
- /* "*" == "**" == "***" ... */
- while (*p == '*')
- ++p;
- /* Trailing '*' always succeeds. */
- if (*p == '\0')
- return (1);
- while (*s) {
- if (pathmatch(p, s, flags))
- return (1);
- ++s;
- }
- return (0);
- case '[':
- /*
- * Find the end of the [...] character class,
- * ignoring \] that might occur within the class.
- */
- end = p + 1;
- while (*end != '\0' && *end != ']') {
- if (*end == '\\' && end[1] != '\0')
- ++end;
- ++end;
- }
- if (*end == ']') {
- /* We found [...], try to match it. */
- if (!pm_list(p + 1, end, *s, flags))
- return (0);
- p = end; /* Jump to trailing ']' char. */
- break;
- } else
- /* No final ']', so just match '['. */
- if (*p != *s)
- return (0);
- break;
- case '\\':
- /* Trailing '\\' matches itself. */
- if (p[1] == '\0') {
- if (*s != '\\')
- return (0);
- } else {
- ++p;
- if (*p != *s)
- return (0);
- }
- break;
- case '/':
- if (*s != '/' && *s != '\0')
- return (0);
- /* Note: pattern "/\./" won't match "/";
- * pm_slashskip() correctly stops at backslash. */
- p = pm_slashskip(p);
- s = pm_slashskip(s);
- if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
- return (1);
- --p; /* Counteract the increment below. */
- --s;
- break;
- case '$':
- /* '$' is special only at end of pattern and only
- * if PATHMATCH_NO_ANCHOR_END is specified. */
- if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
- /* "dir" == "dir/" == "dir/." */
- return (*pm_slashskip(s) == '\0');
- }
- /* Otherwise, '$' is not special. */
- /* FALL THROUGH */
- default:
- if (*p != *s)
- return (0);
- break;
- }
- ++p;
- ++s;
- }
-}
-
-/* Main entry point. */
-int
-pathmatch(const char *p, const char *s, int flags)
-{
- /* Empty pattern only matches the empty string. */
- if (p == NULL || *p == '\0')
- return (s == NULL || *s == '\0');
-
- /* Leading '^' anchors the start of the pattern. */
- if (*p == '^') {
- ++p;
- flags &= ~PATHMATCH_NO_ANCHOR_START;
- }
-
- if (*p == '/' && *s != '/')
- return (0);
-
- /* Certain patterns and file names anchor implicitly. */
- if (*p == '*' || *p == '/' || *p == '/') {
- while (*p == '/')
- ++p;
- while (*s == '/')
- ++s;
- return (pm(p, s, flags));
- }
-
- /* If start is unanchored, try to match start of each path element. */
- if (flags & PATHMATCH_NO_ANCHOR_START) {
- for ( ; s != NULL; s = strchr(s, '/')) {
- if (*s == '/')
- s++;
- if (pm(p, s, flags))
- return (1);
- }
- return (0);
- }
-
- /* Default: Match from beginning. */
- return (pm(p, s, flags));
-}
diff --git a/usr.bin/cpio/test/Makefile b/usr.bin/cpio/test/Makefile
index 111864e..9bdf613 100644
--- a/usr.bin/cpio/test/Makefile
+++ b/usr.bin/cpio/test/Makefile
@@ -2,24 +2,30 @@
# Where to find the cpio sources (for the internal unit tests)
CPIO_SRCDIR=${.CURDIR}/..
-.PATH: ${CPIO_SRCDIR}
-# Some cpio sources are pulled in for white-box tests
-CPIO_SRCS= cmdline.c err.c pathmatch.c
+.PATH: ${CPIO_SRCDIR}
+CPIO_SRCS= cmdline.c
+
+.PATH: ${.CURDIR}/../../../lib/libarchive/libarchive_fe
+TAR_SRCS= err.c pathmatch.c
TESTS= \
test_0.c \
test_basic.c \
test_format_newc.c \
test_gcpio_compat.c \
+ test_option_B_upper.c \
+ test_option_C_upper.c \
+ test_option_J_upper.c \
+ test_option_L_upper.c \
+ test_option_Z_upper.c \
test_option_a.c \
- test_option_B.c \
test_option_c.c \
test_option_d.c \
test_option_f.c \
test_option_help.c \
- test_option_L.c \
- test_option_ell.c \
+ test_option_l.c \
+ test_option_lzma.c \
test_option_m.c \
test_option_t.c \
test_option_u.c \
@@ -34,6 +40,7 @@ TESTS= \
# Build the test program
SRCS= list.h \
${CPIO_SRCS} \
+ ${TAR_SRCS} \
${TESTS} \
main.c
@@ -46,9 +53,11 @@ DPADD=${LIBARCHIVE} ${LIBBZ2} ${LIBZ} ${LIBLZMA}
CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
CFLAGS+= -I..
LDADD= -larchive -lz -lbz2 -llzma
-CFLAGS+= -static -g -O2 -Wall
+#CFLAGS+= -static -g -O2 -Wall
+CFLAGS+= -g -O2 -Wall
CFLAGS+= -I${.OBJDIR}
CFLAGS+= -I${CPIO_SRCDIR}
+CFLAGS+= -I${.CURDIR}/../../../lib/libarchive/libarchive_fe
# Uncomment to link against dmalloc
#LDADD+= -L/usr/local/lib -ldmalloc
diff --git a/usr.bin/cpio/test/main.c b/usr.bin/cpio/test/main.c
index 5a51752..bca4c96 100644
--- a/usr.bin/cpio/test/main.c
+++ b/usr.bin/cpio/test/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2009 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,12 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * Various utility routines useful for test programs.
- * Each test program is linked against this file.
- */
#include "test.h"
-
#include <errno.h>
#include <locale.h>
#include <stdarg.h>
@@ -38,149 +33,318 @@
* This same file is used pretty much verbatim for all test harnesses.
*
* The next few lines are the only differences.
+ * TODO: Move this into a separate configuration header, have all test
+ * suites share one copy of this file.
*/
-#define PROGRAM "bsdcpio" /* Name of program being tested. */
+__FBSDID("$FreeBSD$");
+#define KNOWNREF "test_option_f.cpio.uu"
#define ENVBASE "BSDCPIO" /* Prefix for environment variables. */
+#define PROGRAM "bsdcpio" /* Name of program being tested. */
+#undef LIBRARY /* Not testing a library. */
#undef EXTRA_DUMP /* How to dump extra data */
/* How to generate extra version info. */
#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
-#define KNOWNREF "test_option_f.cpio.uu"
-__FBSDID("$FreeBSD$");
/*
- * "list.h" is simply created by "grep DEFINE_TEST"; it has
- * a line like
- * DEFINE_TEST(test_function)
- * for each test.
- * Include it here with a suitable DEFINE_TEST to declare all of the
- * test functions.
+ *
+ * Windows support routines
+ *
+ * Note: Configuration is a tricky issue. Using HAVE_* feature macros
+ * in the test harness is dangerous because they cover up
+ * configuration errors. The classic example of this is omitting a
+ * configure check. If libarchive and libarchive_test both look for
+ * the same feature macro, such errors are hard to detect. Platform
+ * macros (e.g., _WIN32 or __GNUC__) are a little better, but can
+ * easily lead to very messy code. It's best to limit yourself
+ * to only the most generic programming techniques in the test harness
+ * and thus avoid conditionals altogether. Where that's not possible,
+ * try to minimize conditionals by grouping platform-specific tests in
+ * one place (e.g., test_acl_freebsd) or by adding new assert()
+ * functions (e.g., assertMakeHardlink()) to cover up platform
+ * differences. Platform-specific coding in libarchive_test is often
+ * a symptom that some capability is missing from libarchive itself.
*/
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void);
-#include "list.h"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <io.h>
+#include <windows.h>
+#ifndef F_OK
+#define F_OK (0)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(m) ((m) & _S_IFDIR)
+#endif
+#ifndef S_ISREG
+#define S_ISREG(m) ((m) & _S_IFREG)
+#endif
+#if !defined(__BORLANDC__)
+#define access _access
+#define chdir _chdir
+#endif
+#ifndef fileno
+#define fileno _fileno
+#endif
+/*#define fstat _fstat64*/
+#if !defined(__BORLANDC__)
+#define getcwd _getcwd
+#endif
+#define lstat stat
+/*#define lstat _stat64*/
+/*#define stat _stat64*/
+#define rmdir _rmdir
+#if !defined(__BORLANDC__)
+#define strdup _strdup
+#define umask _umask
+#endif
+#define int64_t __int64
+#endif
+
+#if defined(HAVE__CrtSetReportMode)
+# include <crtdbg.h>
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+void *GetFunctionKernel32(const char *name)
+{
+ static HINSTANCE lib;
+ static int set;
+ if (!set) {
+ set = 1;
+ lib = LoadLibrary("kernel32.dll");
+ }
+ if (lib == NULL) {
+ fprintf(stderr, "Can't load kernel32.dll?!\n");
+ exit(1);
+ }
+ return (void *)GetProcAddress(lib, name);
+}
+
+static int
+my_CreateSymbolicLinkA(const char *linkname, const char *target, int flags)
+{
+ static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, DWORD);
+ static int set;
+ if (!set) {
+ set = 1;
+ f = GetFunctionKernel32("CreateSymbolicLinkA");
+ }
+ return f == NULL ? 0 : (*f)(linkname, target, flags);
+}
+
+static int
+my_CreateHardLinkA(const char *linkname, const char *target)
+{
+ static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES);
+ static int set;
+ if (!set) {
+ set = 1;
+ f = GetFunctionKernel32("CreateHardLinkA");
+ }
+ return f == NULL ? 0 : (*f)(linkname, target, NULL);
+}
+
+int
+my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ HANDLE h;
+ int r;
+
+ memset(bhfi, 0, sizeof(*bhfi));
+ h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return (0);
+ r = GetFileInformationByHandle(h, bhfi);
+ CloseHandle(h);
+ return (r);
+}
+#endif
-/* Interix doesn't define these in a standard header. */
-#if __INTERIX__
-extern char *optarg;
-extern int optind;
+#if defined(HAVE__CrtSetReportMode)
+static void
+invalid_parameter_handler(const wchar_t * expression,
+ const wchar_t * function, const wchar_t * file,
+ unsigned int line, uintptr_t pReserved)
+{
+ /* nop */
+}
#endif
+/*
+ *
+ * OPTIONS FLAGS
+ *
+ */
+
/* Enable core dump on failure. */
static int dump_on_failure = 0;
-/* Default is to remove temp dirs for successful tests. */
+/* Default is to remove temp dirs and log data for successful tests. */
static int keep_temp_files = 0;
-/* Default is to print some basic information about each test. */
-static int quiet_flag = 0;
-/* Default is to summarize repeated failures. */
-static int verbose = 0;
-/* Cumulative count of component failures. */
+/* Default is to just report pass/fail for each test. */
+static int verbosity = 0;
+#define VERBOSITY_SUMMARY_ONLY -1 /* -q */
+#define VERBOSITY_PASSFAIL 0 /* Default */
+#define VERBOSITY_LIGHT_REPORT 1 /* -v */
+#define VERBOSITY_FULL 2 /* -vv */
+/* A few places generate even more output for verbosity > VERBOSITY_FULL,
+ * mostly for debugging the test harness itself. */
+/* Cumulative count of assertion failures. */
static int failures = 0;
-/* Cumulative count of skipped component tests. */
+/* Cumulative count of reported skips. */
static int skips = 0;
-/* Cumulative count of assertions. */
+/* Cumulative count of assertions checked. */
static int assertions = 0;
/* Directory where uuencoded reference files can be found. */
static const char *refdir;
/*
- * My own implementation of the standard assert() macro emits the
- * message in the same format as GCC (file:line: message).
- * It also includes some additional useful information.
- * This makes it a lot easier to skim through test failures in
- * Emacs. ;-)
- *
- * It also supports a few special features specifically to simplify
- * test harnesses:
- * failure(fmt, args) -- Stores a text string that gets
- * printed if the following assertion fails, good for
- * explaining subtle tests.
- */
-static char msg[4096];
-
-/*
- * For each test source file, we remember how many times each
- * failure was reported.
- */
-static const char *failed_filename = NULL;
-static struct line {
- int line;
- int count;
-} failed_lines[1000];
-
-/*
- * Count this failure; return the number of previous failures.
+ * Report log information selectively to console and/or disk log.
*/
-static int
-previous_failures(const char *filename, int line)
+static int log_console = 0;
+static FILE *logfile;
+static void
+vlogprintf(const char *fmt, va_list ap)
{
- unsigned int i;
- int count;
+#ifdef va_copy
+ va_list lfap;
+ va_copy(lfap, ap);
+#endif
+ if (log_console)
+ vfprintf(stdout, fmt, ap);
+ if (logfile != NULL)
+#ifdef va_copy
+ vfprintf(logfile, fmt, lfap);
+ va_end(lfap);
+#else
+ vfprintf(logfile, fmt, ap);
+#endif
+}
- if (failed_filename == NULL || strcmp(failed_filename, filename) != 0)
- memset(failed_lines, 0, sizeof(failed_lines));
- failed_filename = filename;
+static void
+logprintf(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vlogprintf(fmt, ap);
+ va_end(ap);
+}
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == line) {
- count = failed_lines[i].count;
- failed_lines[i].count++;
- return (count);
- }
- if (failed_lines[i].line == 0) {
- failed_lines[i].line = line;
- failed_lines[i].count = 1;
- return (0);
- }
- }
- return (0);
+/* Set up a message to display only if next assertion fails. */
+static char msgbuff[4096];
+static const char *msg, *nextmsg;
+void
+failure(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(msgbuff, fmt, ap);
+ va_end(ap);
+ nextmsg = msgbuff;
}
/*
* Copy arguments into file-local variables.
+ * This was added to permit vararg assert() functions without needing
+ * variadic wrapper macros. Turns out that the vararg capability is almost
+ * never used, so almost all of the vararg assertions can be simplified
+ * by removing the vararg capability and reworking the wrapper macro to
+ * pass __FILE__, __LINE__ directly into the function instead of using
+ * this hook. I suspect this machinery is used so rarely that we
+ * would be better off just removing it entirely. That would simplify
+ * the code here noticably.
*/
static const char *test_filename;
static int test_line;
static void *test_extra;
-void test_setup(const char *filename, int line)
+void assertion_setup(const char *filename, int line)
{
test_filename = filename;
test_line = line;
}
+/* Called at the beginning of each assert() function. */
+static void
+assertion_count(const char *file, int line)
+{
+ (void)file; /* UNUSED */
+ (void)line; /* UNUSED */
+ ++assertions;
+ /* Proper handling of "failure()" message. */
+ msg = nextmsg;
+ nextmsg = NULL;
+ /* Uncomment to print file:line after every assertion.
+ * Verbose, but occasionally useful in tracking down crashes. */
+ /* printf("Checked %s:%d\n", file, line); */
+}
+
/*
- * Inform user that we're skipping a test.
+ * For each test source file, we remember how many times each
+ * assertion was reported. Cleared before each new test,
+ * used by test_summarize().
*/
-void
-test_skipping(const char *fmt, ...)
+static struct line {
+ int count;
+ int skip;
+} failed_lines[10000];
+
+/* Count this failure, setup up log destination and handle initial report. */
+static void
+failure_start(const char *filename, int line, const char *fmt, ...)
{
va_list ap;
- if (previous_failures(test_filename, test_line))
- return;
+ /* Record another failure for this line. */
+ ++failures;
+ /* test_filename = filename; */
+ failed_lines[line].count++;
+ /* Determine whether to log header to console. */
+ switch (verbosity) {
+ case VERBOSITY_FULL:
+ log_console = 1;
+ break;
+ case VERBOSITY_LIGHT_REPORT:
+ log_console = (failed_lines[line].count < 2);
+ break;
+ default:
+ log_console = 0;
+ }
+
+ /* Log file:line header for this failure */
va_start(ap, fmt);
- fprintf(stderr, " *** SKIPPING: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
+#if _MSC_VER
+ logprintf("%s(%d): ", filename, line);
+#else
+ logprintf("%s:%d: ", filename, line);
+#endif
+ vlogprintf(fmt, ap);
va_end(ap);
- ++skips;
+ logprintf("\n");
+
+ if (msg != NULL && msg[0] != '\0') {
+ logprintf(" Description: %s\n", msg);
+ msg = NULL;
+ }
+
+ /* Determine whether to log details to console. */
+ if (verbosity == VERBOSITY_LIGHT_REPORT)
+ log_console = 0;
}
-/* Common handling of failed tests. */
+/* Complete reporting of failed tests. */
+/*
+ * The 'extra' hook here is used by libarchive to include libarchive
+ * error messages with assertion failures. It could also be used
+ * to add strerror() output, for example. Just define the EXTRA_DUMP()
+ * macro appropriately.
+ */
static void
-report_failure(void *extra)
+failure_finish(void *extra)
{
- if (msg[0] != '\0') {
- fprintf(stderr, " Description: %s\n", msg);
- msg[0] = '\0';
- }
-
+ (void)extra; /* UNUSED (maybe) */
#ifdef EXTRA_DUMP
if (extra != NULL)
- fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
-#else
- (void)extra; /* UNUSED */
+ logprintf(" detail: %s\n", EXTRA_DUMP(extra));
#endif
if (dump_on_failure) {
@@ -191,203 +355,170 @@ report_failure(void *extra)
}
}
-/*
- * Summarize repeated failures in the just-completed test file.
- * The reports above suppress multiple failures from the same source
- * line; this reports on any tests that did fail multiple times.
- */
-static int
-summarize_comparator(const void *a0, const void *b0)
-{
- const struct line *a = a0, *b = b0;
- if (a->line == 0 && b->line == 0)
- return (0);
- if (a->line == 0)
- return (1);
- if (b->line == 0)
- return (-1);
- return (a->line - b->line);
-}
-
-static void
-summarize(void)
-{
- unsigned int i;
-
- qsort(failed_lines, sizeof(failed_lines)/sizeof(failed_lines[0]),
- sizeof(failed_lines[0]), summarize_comparator);
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == 0)
- break;
- if (failed_lines[i].count > 1)
- fprintf(stderr, "%s:%d: Failed %d times\n",
- failed_filename, failed_lines[i].line,
- failed_lines[i].count);
- }
- /* Clear the failure history for the next file. */
- memset(failed_lines, 0, sizeof(failed_lines));
-}
-
-/* Set up a message to display only after a test fails. */
+/* Inform user that we're skipping some checks. */
void
-failure(const char *fmt, ...)
+test_skipping(const char *fmt, ...)
{
+ char buff[1024];
va_list ap;
+
va_start(ap, fmt);
- vsprintf(msg, fmt, ap);
+ vsprintf(buff, fmt, ap);
va_end(ap);
+ /* failure_start() isn't quite right, but is awfully convenient. */
+ failure_start(test_filename, test_line, "SKIPPING: %s", buff);
+ --failures; /* Undo failures++ in failure_start() */
+ /* Don't failure_finish() here. */
+ /* Mark as skip, so doesn't count as failed test. */
+ failed_lines[test_line].skip = 1;
+ ++skips;
}
+/*
+ *
+ * ASSERTIONS
+ *
+ */
+
/* Generic assert() just displays the failed condition. */
int
-test_assert(const char *file, int line, int value, const char *condition, void *extra)
+assertion_assert(const char *file, int line, int value,
+ const char *condition, void *extra)
{
- ++assertions;
- if (value) {
- msg[0] = '\0';
- return (value);
+ assertion_count(file, line);
+ if (!value) {
+ failure_start(file, line, "Assertion failed: %s", condition);
+ failure_finish(extra);
}
- failures ++;
- if (!verbose && previous_failures(file, line))
- return (value);
- fprintf(stderr, "%s:%d: Assertion failed\n", file, line);
- fprintf(stderr, " Condition: %s\n", condition);
- report_failure(extra);
return (value);
}
-/* assertEqualInt() displays the values of the two integers. */
+/* chdir() and report any errors */
int
-test_assert_equal_int(const char *file, int line,
- int v1, const char *e1, int v2, const char *e2, void *extra)
+assertion_chdir(const char *file, int line, const char *pathname)
{
- ++assertions;
- if (v1 == v2) {
- msg[0] = '\0';
+ assertion_count(file, line);
+ if (chdir(pathname) == 0)
return (1);
- }
- failures ++;
- if (!verbose && previous_failures(file, line))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n",
- file, line);
- fprintf(stderr, " %s=%d\n", e1, v1);
- fprintf(stderr, " %s=%d\n", e2, v2);
- report_failure(extra);
+ failure_start(file, line, "chdir(\"%s\")", pathname);
+ failure_finish(NULL);
return (0);
+
}
-static void strdump(const char *p)
+/* Verify two integers are equal. */
+int
+assertion_equal_int(const char *file, int line,
+ long long v1, const char *e1, long long v2, const char *e2, void *extra)
+{
+ assertion_count(file, line);
+ if (v1 == v2)
+ return (1);
+ failure_start(file, line, "%s != %s", e1, e2);
+ logprintf(" %s=%lld (0x%llx, 0%llo)\n", e1, v1, v1, v1);
+ logprintf(" %s=%lld (0x%llx, 0%llo)\n", e2, v2, v2, v2);
+ failure_finish(extra);
+ return (0);
+}
+
+static void strdump(const char *e, const char *p)
{
+ const char *q = p;
+
+ logprintf(" %s = ", e);
if (p == NULL) {
- fprintf(stderr, "(null)");
+ logprintf("NULL");
return;
}
- fprintf(stderr, "\"");
+ logprintf("\"");
while (*p != '\0') {
unsigned int c = 0xff & *p++;
switch (c) {
- case '\a': fprintf(stderr, "\a"); break;
- case '\b': fprintf(stderr, "\b"); break;
- case '\n': fprintf(stderr, "\n"); break;
- case '\r': fprintf(stderr, "\r"); break;
+ case '\a': printf("\a"); break;
+ case '\b': printf("\b"); break;
+ case '\n': printf("\n"); break;
+ case '\r': printf("\r"); break;
default:
if (c >= 32 && c < 127)
- fprintf(stderr, "%c", c);
+ logprintf("%c", c);
else
- fprintf(stderr, "\\x%02X", c);
+ logprintf("\\x%02X", c);
}
}
- fprintf(stderr, "\"");
+ logprintf("\"");
+ logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q));
}
-/* assertEqualString() displays the values of the two strings. */
+/* Verify two strings are equal, dump them if not. */
int
-test_assert_equal_string(const char *file, int line,
+assertion_equal_string(const char *file, int line,
const char *v1, const char *e1,
const char *v2, const char *e2,
void *extra)
{
- ++assertions;
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (strcmp(v1, v2) == 0) {
- msg[0] = '\0';
+ assertion_count(file, line);
+ if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
return (1);
- }
- failures ++;
- if (!verbose && previous_failures(file, line))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- strdump(v1);
- fprintf(stderr, " (length %d)\n", v1 == NULL ? 0 : (int)strlen(v1));
- fprintf(stderr, " %s = ", e2);
- strdump(v2);
- fprintf(stderr, " (length %d)\n", v2 == NULL ? 0 : (int)strlen(v2));
- report_failure(extra);
+ failure_start(file, line, "%s != %s", e1, e2);
+ strdump(e1, v1);
+ strdump(e2, v2);
+ failure_finish(extra);
return (0);
}
-static void wcsdump(const wchar_t *w)
+static void
+wcsdump(const char *e, const wchar_t *w)
{
+ logprintf(" %s = ", e);
if (w == NULL) {
- fprintf(stderr, "(null)");
+ logprintf("(null)");
return;
}
- fprintf(stderr, "\"");
+ logprintf("\"");
while (*w != L'\0') {
unsigned int c = *w++;
if (c >= 32 && c < 127)
- fprintf(stderr, "%c", c);
+ logprintf("%c", c);
else if (c < 256)
- fprintf(stderr, "\\x%02X", c);
+ logprintf("\\x%02X", c);
else if (c < 0x10000)
- fprintf(stderr, "\\u%04X", c);
+ logprintf("\\u%04X", c);
else
- fprintf(stderr, "\\U%08X", c);
+ logprintf("\\U%08X", c);
}
- fprintf(stderr, "\"");
+ logprintf("\"\n");
}
-/* assertEqualWString() displays the values of the two strings. */
+#ifndef HAVE_WCSCMP
+static int
+wcscmp(const wchar_t *s1, const wchar_t *s2)
+{
+
+ while (*s1 == *s2++) {
+ if (*s1++ == L'\0')
+ return 0;
+ }
+ if (*s1 > *--s2)
+ return 1;
+ else
+ return -1;
+}
+#endif
+
+/* Verify that two wide strings are equal, dump them if not. */
int
-test_assert_equal_wstring(const char *file, int line,
+assertion_equal_wstring(const char *file, int line,
const wchar_t *v1, const char *e1,
const wchar_t *v2, const char *e2,
void *extra)
{
- ++assertions;
- if (v1 == NULL) {
- if (v2 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (v2 == NULL) {
- if (v1 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (wcscmp(v1, v2) == 0) {
- msg[0] = '\0';
+ assertion_count(file, line);
+ if (v1 == v2 || wcscmp(v1, v2) == 0)
return (1);
- }
- failures ++;
- if (!verbose && previous_failures(file, line))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- wcsdump(v1);
- fprintf(stderr, "\n");
- fprintf(stderr, " %s = ", e2);
- wcsdump(v2);
- fprintf(stderr, "\n");
- report_failure(extra);
+ failure_start(file, line, "%s != %s", e1, e2);
+ wcsdump(e1, v1);
+ wcsdump(e2, v2);
+ failure_finish(extra);
return (0);
}
@@ -402,249 +533,294 @@ hexdump(const char *p, const char *ref, size_t l, size_t offset)
size_t i, j;
char sep;
+ if (p == NULL) {
+ logprintf("(null)\n");
+ return;
+ }
for(i=0; i < l; i+=16) {
- fprintf(stderr, "%04x", (unsigned)(i + offset));
+ logprintf("%04x", (unsigned)(i + offset));
sep = ' ';
for (j = 0; j < 16 && i + j < l; j++) {
if (ref != NULL && p[i + j] != ref[i + j])
sep = '_';
- fprintf(stderr, "%c%02x", sep, 0xff & (int)p[i+j]);
+ logprintf("%c%02x", sep, 0xff & (int)p[i+j]);
if (ref != NULL && p[i + j] == ref[i + j])
sep = ' ';
}
for (; j < 16; j++) {
- fprintf(stderr, "%c ", sep);
+ logprintf("%c ", sep);
sep = ' ';
}
- fprintf(stderr, "%c", sep);
+ logprintf("%c", sep);
for (j=0; j < 16 && i + j < l; j++) {
int c = p[i + j];
if (c >= ' ' && c <= 126)
- fprintf(stderr, "%c", c);
+ logprintf("%c", c);
else
- fprintf(stderr, ".");
+ logprintf(".");
}
- fprintf(stderr, "\n");
+ logprintf("\n");
}
}
-/* assertEqualMem() displays the values of the two memory blocks. */
-/* TODO: For long blocks, hexdump the first bytes that actually differ. */
+/* Verify that two blocks of memory are the same, display the first
+ * block of differences if they're not. */
int
-test_assert_equal_mem(const char *file, int line,
- const char *v1, const char *e1,
- const char *v2, const char *e2,
+assertion_equal_mem(const char *file, int line,
+ const void *_v1, const char *e1,
+ const void *_v2, const char *e2,
size_t l, const char *ld, void *extra)
{
- ++assertions;
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (memcmp(v1, v2, l) == 0) {
- msg[0] = '\0';
+ const char *v1 = (const char *)_v1;
+ const char *v2 = (const char *)_v2;
+ size_t offset;
+
+ assertion_count(file, line);
+ if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0))
return (1);
+
+ failure_start(file, line, "%s != %s", e1, e2);
+ logprintf(" size %s = %d\n", ld, (int)l);
+ /* Dump 48 bytes (3 lines) so that the first difference is
+ * in the second line. */
+ offset = 0;
+ while (l > 64 && memcmp(v1, v2, 32) == 0) {
+ /* Two lines agree, so step forward one line. */
+ v1 += 16;
+ v2 += 16;
+ l -= 16;
+ offset += 16;
}
- failures ++;
- if (!verbose && previous_failures(file, line))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n",
- file, line);
- fprintf(stderr, " size %s = %d\n", ld, (int)l);
- fprintf(stderr, " Dump of %s\n", e1);
- hexdump(v1, v2, l < 32 ? l : 32, 0);
- fprintf(stderr, " Dump of %s\n", e2);
- hexdump(v2, v1, l < 32 ? l : 32, 0);
- fprintf(stderr, "\n");
- report_failure(extra);
+ logprintf(" Dump of %s\n", e1);
+ hexdump(v1, v2, l < 64 ? l : 64, offset);
+ logprintf(" Dump of %s\n", e2);
+ hexdump(v2, v1, l < 64 ? l : 64, offset);
+ logprintf("\n");
+ failure_finish(extra);
return (0);
}
+/* Verify that the named file exists and is empty. */
int
-test_assert_empty_file(const char *f1fmt, ...)
+assertion_empty_file(const char *f1fmt, ...)
{
char buff[1024];
char f1[1024];
struct stat st;
va_list ap;
ssize_t s;
- int fd;
-
+ FILE *f;
+ assertion_count(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n", test_filename, test_line, f1);
- report_failure(NULL);
+ failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_finish(NULL);
return (0);
}
if (st.st_size == 0)
return (1);
- failures ++;
- if (!verbose && previous_failures(test_filename, test_line))
- return (0);
-
- fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1);
- fprintf(stderr, " File size: %d\n", (int)st.st_size);
- fprintf(stderr, " Contents:\n");
- fd = open(f1, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, " Unable to open %s\n", f1);
+ failure_start(test_filename, test_line, "File should be empty: %s", f1);
+ logprintf(" File size: %d\n", (int)st.st_size);
+ logprintf(" Contents:\n");
+ f = fopen(f1, "rb");
+ if (f == NULL) {
+ logprintf(" Unable to open %s\n", f1);
} else {
- s = sizeof(buff) < st.st_size ? sizeof(buff) : st.st_size;
- s = read(fd, buff, s);
+ s = ((off_t)sizeof(buff) < st.st_size) ?
+ (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
+ s = fread(buff, 1, s, f);
hexdump(buff, NULL, s, 0);
- close(fd);
+ fclose(f);
}
- report_failure(NULL);
+ failure_finish(NULL);
return (0);
}
-/* assertEqualFile() asserts that two files have the same contents. */
+/* Verify that the named file exists and is not empty. */
+int
+assertion_non_empty_file(const char *f1fmt, ...)
+{
+ char f1[1024];
+ struct stat st;
+ va_list ap;
+
+ assertion_count(test_filename, test_line);
+ va_start(ap, f1fmt);
+ vsprintf(f1, f1fmt, ap);
+ va_end(ap);
+
+ if (stat(f1, &st) != 0) {
+ failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (st.st_size == 0) {
+ failure_start(test_filename, test_line, "File empty: %s", f1);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+}
+
+/* Verify that two files have the same contents. */
/* TODO: hexdump the first bytes that actually differ. */
int
-test_assert_equal_file(const char *f1, const char *f2pattern, ...)
+assertion_equal_file(const char *fn1, const char *f2pattern, ...)
{
- char f2[1024];
+ char fn2[1024];
va_list ap;
char buff1[1024];
char buff2[1024];
- int fd1, fd2;
+ FILE *f1, *f2;
int n1, n2;
+ assertion_count(test_filename, test_line);
va_start(ap, f2pattern);
- vsprintf(f2, f2pattern, ap);
+ vsprintf(fn2, f2pattern, ap);
va_end(ap);
- fd1 = open(f1, O_RDONLY);
- fd2 = open(f2, O_RDONLY);
+ f1 = fopen(fn1, "rb");
+ f2 = fopen(fn2, "rb");
for (;;) {
- n1 = read(fd1, buff1, sizeof(buff1));
- n2 = read(fd2, buff2, sizeof(buff2));
+ n1 = fread(buff1, 1, sizeof(buff1), f1);
+ n2 = fread(buff2, 1, sizeof(buff2), f2);
if (n1 != n2)
break;
if (n1 == 0 && n2 == 0) {
- close(fd1);
- close(fd2);
+ fclose(f1);
+ fclose(f2);
return (1);
}
if (memcmp(buff1, buff2, n1) != 0)
break;
}
- close(fd1);
- close(fd2);
- failures ++;
- if (!verbose && previous_failures(test_filename, test_line))
- return (0);
- fprintf(stderr, "%s:%d: Files are not identical\n",
- test_filename, test_line);
- fprintf(stderr, " file1=\"%s\"\n", f1);
- fprintf(stderr, " file2=\"%s\"\n", f2);
- report_failure(test_extra);
+ fclose(f1);
+ fclose(f2);
+ failure_start(test_filename, test_line, "Files not identical");
+ logprintf(" file1=\"%s\"\n", fn1);
+ logprintf(" file2=\"%s\"\n", fn2);
+ failure_finish(test_extra);
return (0);
}
+/* Verify that the named file does exist. */
int
-test_assert_file_exists(const char *fpattern, ...)
+assertion_file_exists(const char *fpattern, ...)
{
char f[1024];
va_list ap;
+ assertion_count(test_filename, test_line);
va_start(ap, fpattern);
vsprintf(f, fpattern, ap);
va_end(ap);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (!_access(f, 0))
+ return (1);
+#else
if (!access(f, F_OK))
return (1);
- if (!previous_failures(test_filename, test_line)) {
- fprintf(stderr, "%s:%d: File doesn't exist\n",
- test_filename, test_line);
- fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
- }
+#endif
+ failure_start(test_filename, test_line, "File should exist: %s", f);
+ failure_finish(test_extra);
return (0);
}
+/* Verify that the named file doesn't exist. */
int
-test_assert_file_not_exists(const char *fpattern, ...)
+assertion_file_not_exists(const char *fpattern, ...)
{
char f[1024];
va_list ap;
+ assertion_count(test_filename, test_line);
va_start(ap, fpattern);
vsprintf(f, fpattern, ap);
va_end(ap);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (_access(f, 0))
+ return (1);
+#else
if (access(f, F_OK))
return (1);
- if (!previous_failures(test_filename, test_line)) {
- fprintf(stderr, "%s:%d: File exists and shouldn't\n",
- test_filename, test_line);
- fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
- }
+#endif
+ failure_start(test_filename, test_line, "File should not exist: %s", f);
+ failure_finish(test_extra);
return (0);
}
-/* assertFileContents() asserts the contents of a file. */
+/* Compare the contents of a file to a block of memory. */
int
-test_assert_file_contents(const void *buff, int s, const char *fpattern, ...)
+assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
{
- char f[1024];
+ char fn[1024];
va_list ap;
char *contents;
- int fd;
+ FILE *f;
int n;
+ assertion_count(test_filename, test_line);
va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
+ vsprintf(fn, fpattern, ap);
va_end(ap);
- fd = open(f, O_RDONLY);
- contents = malloc(s * 2 + 128);
- n = read(fd, contents, s * 2 + 128);
- close(fd);
+ f = fopen(fn, "rb");
+ if (f == NULL) {
+ failure_start(test_filename, test_line,
+ "File should exist: %s", fn);
+ failure_finish(test_extra);
+ return (0);
+ }
+ contents = malloc(s * 2);
+ n = fread(contents, 1, s * 2, f);
+ fclose(f);
if (n == s && memcmp(buff, contents, s) == 0) {
free(contents);
return (1);
}
- failures ++;
- if (!previous_failures(test_filename, test_line)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
- fprintf(stderr, " file=\"%s\"\n", f);
- if (n > 0)
- hexdump(contents, buff, n, 0);
- else {
- fprintf(stderr, " File empty, contents should be:\n");
- hexdump(buff, NULL, s, 0);
- }
- report_failure(test_extra);
+ failure_start(test_filename, test_line, "File contents don't match");
+ logprintf(" file=\"%s\"\n", fn);
+ if (n > 0)
+ hexdump(contents, buff, n > 512 ? 512 : n, 0);
+ else {
+ logprintf(" File empty, contents should be:\n");
+ hexdump(buff, NULL, s > 512 ? 512 : n, 0);
}
+ failure_finish(test_extra);
free(contents);
return (0);
}
-/* assertTextFileContents() asserts the contents of a text file. */
+/* Check the contents of a text file, being tolerant of line endings. */
int
-test_assert_text_file_contents(const char *buff, const char *f)
+assertion_text_file_contents(const char *buff, const char *fn)
{
char *contents;
const char *btxt, *ftxt;
- int fd;
+ FILE *f;
int n, s;
- fd = open(f, O_RDONLY);
+ assertion_count(test_filename, test_line);
+ f = fopen(fn, "r");
+ if (f == NULL) {
+ failure_start(test_filename, test_line,
+ "File doesn't exist: %s", fn);
+ failure_finish(test_extra);
+ return (0);
+ }
s = strlen(buff);
contents = malloc(s * 2 + 128);
- n = read(fd, contents, s * 2 + 128 -1);
+ n = fread(contents, 1, s * 2 + 128 - 1, f);
if (n >= 0)
contents[n] = '\0';
- close(fd);
+ fclose(f);
/* Compare texts. */
btxt = buff;
ftxt = (const char *)contents;
@@ -666,23 +842,647 @@ test_assert_text_file_contents(const char *buff, const char *f)
free(contents);
return (1);
}
- failures ++;
- if (!previous_failures(test_filename, test_line)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
- fprintf(stderr, " file=\"%s\"\n", f);
- if (n > 0)
- hexdump(contents, buff, n, 0);
- else {
- fprintf(stderr, " File empty, contents should be:\n");
- hexdump(buff, NULL, s, 0);
- }
- report_failure(test_extra);
+ failure_start(test_filename, test_line, "Contents don't match");
+ logprintf(" file=\"%s\"\n", fn);
+ if (n > 0)
+ hexdump(contents, buff, n, 0);
+ else {
+ logprintf(" File empty, contents should be:\n");
+ hexdump(buff, NULL, s, 0);
}
+ failure_finish(test_extra);
free(contents);
return (0);
}
+/* Test that two paths point to the same file. */
+/* As a side-effect, asserts that both files exist. */
+static int
+is_hardlink(const char *file, int line,
+ const char *path1, const char *path2)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi1, bhfi2;
+ int r;
+
+ assertion_count(file, line);
+ r = my_GetFileInformationByName(path1, &bhfi1);
+ if (r == 0) {
+ failure_start(file, line, "File %s can't be inspected?", path1);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = my_GetFileInformationByName(path2, &bhfi2);
+ if (r == 0) {
+ failure_start(file, line, "File %s can't be inspected?", path2);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (bhfi1.dwVolumeSerialNumber == bhfi2.dwVolumeSerialNumber
+ && bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh
+ && bhfi1.nFileIndexLow == bhfi2.nFileIndexLow);
+#else
+ struct stat st1, st2;
+ int r;
+
+ assertion_count(file, line);
+ r = lstat(path1, &st1);
+ if (r != 0) {
+ failure_start(file, line, "File should exist: %s", path1);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = lstat(path2, &st2);
+ if (r != 0) {
+ failure_start(file, line, "File should exist: %s", path2);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev);
+#endif
+}
+
+int
+assertion_is_hardlink(const char *file, int line,
+ const char *path1, const char *path2)
+{
+ if (is_hardlink(file, line, path1, path2))
+ return (1);
+ failure_start(file, line,
+ "Files %s and %s are not hardlinked", path1, path2);
+ failure_finish(NULL);
+ return (0);
+}
+
+int
+assertion_is_not_hardlink(const char *file, int line,
+ const char *path1, const char *path2)
+{
+ if (!is_hardlink(file, line, path1, path2))
+ return (1);
+ failure_start(file, line,
+ "Files %s and %s should not be hardlinked", path1, path2);
+ failure_finish(NULL);
+ return (0);
+}
+
+/* Verify a/b/mtime of 'pathname'. */
+/* If 'recent', verify that it's within last 10 seconds. */
+static int
+assertion_file_time(const char *file, int line,
+ const char *pathname, long t, long nsec, char type, int recent)
+{
+ long long filet, filet_nsec;
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define EPOC_TIME (116444736000000000ULL)
+ FILETIME ftime, fbirthtime, fatime, fmtime;
+ ULARGE_INTEGER wintm;
+ HANDLE h;
+ ftime.dwLowDateTime = 0;
+ ftime.dwHighDateTime = 0;
+
+ assertion_count(file, line);
+ h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ failure_start(file, line, "Can't access %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = GetFileTime(h, &fbirthtime, &fatime, &fmtime);
+ switch (type) {
+ case 'a': ftime = fatime; break;
+ case 'b': ftime = fbirthtime; break;
+ case 'm': ftime = fmtime; break;
+ }
+ CloseHandle(h);
+ if (r == 0) {
+ failure_start(file, line, "Can't GetFileTime %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ wintm.LowPart = ftime.dwLowDateTime;
+ wintm.HighPart = ftime.dwHighDateTime;
+ filet = (wintm.QuadPart - EPOC_TIME) / 10000000;
+ filet_nsec = ((wintm.QuadPart - EPOC_TIME) % 10000000) * 100;
+ nsec = (nsec / 100) * 100; /* Round the request */
+#else
+ struct stat st;
+
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0) {
+ failure_start(file, line, "Can't stat %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ switch (type) {
+ case 'a': filet = st.st_atime; break;
+ case 'm': filet = st.st_mtime; break;
+ case 'b': filet = 0; break;
+ default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
+ exit(1);
+ }
+#if defined(__FreeBSD__)
+ switch (type) {
+ case 'a': filet_nsec = st.st_atimespec.tv_nsec; break;
+ case 'b': filet = st.st_birthtime;
+ filet_nsec = st.st_birthtimespec.tv_nsec; break;
+ case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break;
+ default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
+ exit(1);
+ }
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ filet_nsec = (filet_nsec / 1000) * 1000;
+ nsec = (nsec / 1000) * 1000;
+#else
+ filet_nsec = nsec = 0; /* Generic POSIX only has whole seconds. */
+ if (type == 'b') return (1); /* Generic POSIX doesn't have birthtime */
+#if defined(__HAIKU__)
+ if (type == 'a') return (1); /* Haiku doesn't have atime. */
+#endif
+#endif
+#endif
+ if (recent) {
+ /* Check that requested time is up-to-date. */
+ time_t now = time(NULL);
+ if (filet < now - 10 || filet > now + 1) {
+ failure_start(file, line,
+ "File %s has %ctime %ld, %ld seconds ago\n",
+ pathname, type, filet, now - filet);
+ failure_finish(NULL);
+ return (0);
+ }
+ } else if (filet != t || filet_nsec != nsec) {
+ failure_start(file, line,
+ "File %s has %ctime %ld.%09ld, expected %ld.%09ld",
+ pathname, type, filet, filet_nsec, t, nsec);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+}
+
+/* Verify atime of 'pathname'. */
+int
+assertion_file_atime(const char *file, int line,
+ const char *pathname, long t, long nsec)
+{
+ return assertion_file_time(file, line, pathname, t, nsec, 'a', 0);
+}
+
+/* Verify atime of 'pathname' is up-to-date. */
+int
+assertion_file_atime_recent(const char *file, int line, const char *pathname)
+{
+ return assertion_file_time(file, line, pathname, 0, 0, 'a', 1);
+}
+
+/* Verify birthtime of 'pathname'. */
+int
+assertion_file_birthtime(const char *file, int line,
+ const char *pathname, long t, long nsec)
+{
+ return assertion_file_time(file, line, pathname, t, nsec, 'b', 0);
+}
+
+/* Verify birthtime of 'pathname' is up-to-date. */
+int
+assertion_file_birthtime_recent(const char *file, int line,
+ const char *pathname)
+{
+ return assertion_file_time(file, line, pathname, 0, 0, 'b', 1);
+}
+
+/* Verify mtime of 'pathname'. */
+int
+assertion_file_mtime(const char *file, int line,
+ const char *pathname, long t, long nsec)
+{
+ return assertion_file_time(file, line, pathname, t, nsec, 'm', 0);
+}
+
+/* Verify mtime of 'pathname' is up-to-date. */
+int
+assertion_file_mtime_recent(const char *file, int line, const char *pathname)
+{
+ return assertion_file_time(file, line, pathname, 0, 0, 'm', 1);
+}
+
+/* Verify number of links to 'pathname'. */
+int
+assertion_file_nlinks(const char *file, int line,
+ const char *pathname, int nlinks)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ int r;
+
+ assertion_count(file, line);
+ r = my_GetFileInformationByName(pathname, &bhfi);
+ if (r != 0 && bhfi.nNumberOfLinks == (DWORD)nlinks)
+ return (1);
+ failure_start(file, line, "File %s has %d links, expected %d",
+ pathname, bhfi.nNumberOfLinks, nlinks);
+ failure_finish(NULL);
+ return (0);
+#else
+ struct stat st;
+ int r;
+
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r == 0 && st.st_nlink == nlinks)
+ return (1);
+ failure_start(file, line, "File %s has %d links, expected %d",
+ pathname, st.st_nlink, nlinks);
+ failure_finish(NULL);
+ return (0);
+#endif
+}
+
+/* Verify size of 'pathname'. */
+int
+assertion_file_size(const char *file, int line, const char *pathname, long size)
+{
+ int64_t filesize;
+ int r;
+
+ assertion_count(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ {
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ r = !my_GetFileInformationByName(pathname, &bhfi);
+ filesize = ((int64_t)bhfi.nFileSizeHigh << 32) + bhfi.nFileSizeLow;
+ }
+#else
+ {
+ struct stat st;
+ r = lstat(pathname, &st);
+ filesize = st.st_size;
+ }
+#endif
+ if (r == 0 && filesize == size)
+ return (1);
+ failure_start(file, line, "File %s has size %ld, expected %ld",
+ pathname, (long)filesize, (long)size);
+ failure_finish(NULL);
+ return (0);
+}
+
+/* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */
+int
+assertion_is_dir(const char *file, int line, const char *pathname, int mode)
+{
+ struct stat st;
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)mode; /* UNUSED */
+#endif
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0) {
+ failure_start(file, line, "Dir should exist: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ failure_start(file, line, "%s is not a dir", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ /* Windows doesn't handle permissions the same way as POSIX,
+ * so just ignore the mode tests. */
+ /* TODO: Can we do better here? */
+ if (mode >= 0 && mode != (st.st_mode & 07777)) {
+ failure_start(file, line, "Dir %s has wrong mode", pathname);
+ logprintf(" Expected: 0%3o\n", mode);
+ logprintf(" Found: 0%3o\n", st.st_mode & 07777);
+ failure_finish(NULL);
+ return (0);
+ }
+#endif
+ return (1);
+}
+
+/* Verify that 'pathname' is a regular file. If 'mode' is >= 0,
+ * verify that too. */
+int
+assertion_is_reg(const char *file, int line, const char *pathname, int mode)
+{
+ struct stat st;
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)mode; /* UNUSED */
+#endif
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0 || !S_ISREG(st.st_mode)) {
+ failure_start(file, line, "File should exist: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ /* Windows doesn't handle permissions the same way as POSIX,
+ * so just ignore the mode tests. */
+ /* TODO: Can we do better here? */
+ if (mode >= 0 && mode != (st.st_mode & 07777)) {
+ failure_start(file, line, "File %s has wrong mode", pathname);
+ logprintf(" Expected: 0%3o\n", mode);
+ logprintf(" Found: 0%3o\n", st.st_mode & 07777);
+ failure_finish(NULL);
+ return (0);
+ }
+#endif
+ return (1);
+}
+
+/* Check whether 'pathname' is a symbolic link. If 'contents' is
+ * non-NULL, verify that the symlink has those contents. */
+static int
+is_symlink(const char *file, int line,
+ const char *pathname, const char *contents)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)pathname; /* UNUSED */
+ (void)contents; /* UNUSED */
+ assertion_count(file, line);
+ /* Windows sort-of has real symlinks, but they're only usable
+ * by privileged users and are crippled even then, so there's
+ * really not much point in bothering with this. */
+ return (0);
+#else
+ char buff[300];
+ struct stat st;
+ ssize_t linklen;
+ int r;
+
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0) {
+ failure_start(file, line,
+ "Symlink should exist: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (!S_ISLNK(st.st_mode))
+ return (0);
+ if (contents == NULL)
+ return (1);
+ linklen = readlink(pathname, buff, sizeof(buff));
+ if (linklen < 0) {
+ failure_start(file, line, "Can't read symlink %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ buff[linklen] = '\0';
+ if (strcmp(buff, contents) != 0)
+ return (0);
+ return (1);
+#endif
+}
+
+/* Assert that path is a symlink that (optionally) contains contents. */
+int
+assertion_is_symlink(const char *file, int line,
+ const char *path, const char *contents)
+{
+ if (is_symlink(file, line, path, contents))
+ return (1);
+ if (contents)
+ failure_start(file, line, "File %s is not a symlink to %s",
+ path, contents);
+ else
+ failure_start(file, line, "File %s is not a symlink", path);
+ failure_finish(NULL);
+ return (0);
+}
+
+
+/* Create a directory and report any errors. */
+int
+assertion_make_dir(const char *file, int line, const char *dirname, int mode)
+{
+ assertion_count(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)mode; /* UNUSED */
+ if (0 == _mkdir(dirname))
+ return (1);
+#else
+ if (0 == mkdir(dirname, mode))
+ return (1);
+#endif
+ failure_start(file, line, "Could not create directory %s", dirname);
+ failure_finish(NULL);
+ return(0);
+}
+
+/* Create a file with the specified contents and report any failures. */
+int
+assertion_make_file(const char *file, int line,
+ const char *path, int mode, const char *contents)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* TODO: Rework this to set file mode as well. */
+ FILE *f;
+ (void)mode; /* UNUSED */
+ assertion_count(file, line);
+ f = fopen(path, "wb");
+ if (f == NULL) {
+ failure_start(file, line, "Could not create file %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (contents != NULL) {
+ if (strlen(contents)
+ != fwrite(contents, 1, strlen(contents), f)) {
+ fclose(f);
+ failure_start(file, line,
+ "Could not write file %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ }
+ fclose(f);
+ return (1);
+#else
+ int fd;
+ assertion_count(file, line);
+ fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644);
+ if (fd < 0) {
+ failure_start(file, line, "Could not create %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (contents != NULL) {
+ if ((ssize_t)strlen(contents)
+ != write(fd, contents, strlen(contents))) {
+ close(fd);
+ failure_start(file, line, "Could not write to %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ }
+ close(fd);
+ return (1);
+#endif
+}
+
+/* Create a hardlink and report any failures. */
+int
+assertion_make_hardlink(const char *file, int line,
+ const char *newpath, const char *linkto)
+{
+ int succeeded;
+
+ assertion_count(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ succeeded = my_CreateHardLinkA(newpath, linkto);
+#elif HAVE_LINK
+ succeeded = !link(linkto, newpath);
+#else
+ succeeded = 0;
+#endif
+ if (succeeded)
+ return (1);
+ failure_start(file, line, "Could not create hardlink");
+ logprintf(" New link: %s\n", newpath);
+ logprintf(" Old name: %s\n", linkto);
+ failure_finish(NULL);
+ return(0);
+}
+
+/* Create a symlink and report any failures. */
+int
+assertion_make_symlink(const char *file, int line,
+ const char *newpath, const char *linkto)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ int targetIsDir = 0; /* TODO: Fix this */
+ assertion_count(file, line);
+ if (my_CreateSymbolicLinkA(newpath, linkto, targetIsDir))
+ return (1);
+#elif HAVE_SYMLINK
+ assertion_count(file, line);
+ if (0 == symlink(linkto, newpath))
+ return (1);
+#endif
+ failure_start(file, line, "Could not create symlink");
+ logprintf(" New link: %s\n", newpath);
+ logprintf(" Old name: %s\n", linkto);
+ failure_finish(NULL);
+ return(0);
+}
+
+/* Set umask, report failures. */
+int
+assertion_umask(const char *file, int line, int mask)
+{
+ assertion_count(file, line);
+ (void)file; /* UNUSED */
+ (void)line; /* UNUSED */
+ umask(mask);
+ return (1);
+}
+
+/*
+ *
+ * UTILITIES for use by tests.
+ *
+ */
+
+/*
+ * Check whether platform supports symlinks. This is intended
+ * for tests to use in deciding whether to bother testing symlink
+ * support; if the platform doesn't support symlinks, there's no point
+ * in checking whether the program being tested can create them.
+ *
+ * Note that the first time this test is called, we actually go out to
+ * disk to create and verify a symlink. This is necessary because
+ * symlink support is actually a property of a particular filesystem
+ * and can thus vary between directories on a single system. After
+ * the first call, this returns the cached result from memory, so it's
+ * safe to call it as often as you wish.
+ */
+int
+canSymlink(void)
+{
+ /* Remember the test result */
+ static int value = 0, tested = 0;
+ if (tested)
+ return (value);
+
+ ++tested;
+ assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+ /* Note: Cygwin has its own symlink() emulation that does not
+ * use the Win32 CreateSymbolicLink() function. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0)
+ && is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0");
+#elif HAVE_SYMLINK
+ value = (0 == symlink("canSymlink.0", "canSymlink.1"))
+ && is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0");
+#endif
+ return (value);
+}
+
+/*
+ * Can this platform run the gzip program?
+ */
+/* Platform-dependent options for hiding the output of a subcommand. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */
+#else
+static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */
+#endif
+int
+canGzip(void)
+{
+ static int tested = 0, value = 0;
+ if (!tested) {
+ tested = 1;
+ if (systemf("gzip -V %s", redirectArgs) == 0)
+ value = 1;
+ }
+ return (value);
+}
+
+/*
+ * Can this platform run the gunzip program?
+ */
+int
+canGunzip(void)
+{
+ static int tested = 0, value = 0;
+ if (!tested) {
+ tested = 1;
+ if (systemf("gunzip -V %s", redirectArgs) == 0)
+ value = 1;
+ }
+ return (value);
+}
+
+/*
+ * Sleep as needed; useful for verifying disk timestamp changes by
+ * ensuring that the wall-clock time has actually changed before we
+ * go back to re-read something from disk.
+ */
+void
+sleepUntilAfter(time_t t)
+{
+ while (t >= time(NULL))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ Sleep(500);
+#else
+ sleep(1);
+#endif
+}
+
/*
* Call standard system() call, but build up the command line using
* sprintf() conventions.
@@ -696,6 +1496,8 @@ systemf(const char *fmt, ...)
va_start(ap, fmt);
vsprintf(buff, fmt, ap);
+ if (verbosity > VERBOSITY_FULL)
+ logprintf("Cmd: %s\n", buff);
r = system(buff);
va_end(ap);
return (r);
@@ -714,143 +1516,48 @@ slurpfile(size_t * sizep, const char *fmt, ...)
va_list ap;
char *p;
ssize_t bytes_read;
- int fd;
+ FILE *f;
int r;
va_start(ap, fmt);
vsprintf(filename, fmt, ap);
va_end(ap);
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
+ f = fopen(filename, "rb");
+ if (f == NULL) {
/* Note: No error; non-existent file is okay here. */
return (NULL);
}
- r = fstat(fd, &st);
+ r = fstat(fileno(f), &st);
if (r != 0) {
- fprintf(stderr, "Can't stat file %s\n", filename);
- close(fd);
+ logprintf("Can't stat file %s\n", filename);
+ fclose(f);
return (NULL);
}
- p = malloc(st.st_size + 1);
+ p = malloc((size_t)st.st_size + 1);
if (p == NULL) {
- fprintf(stderr, "Can't allocate %ld bytes of memory to read file %s\n", (long int)st.st_size, filename);
- close(fd);
+ logprintf("Can't allocate %ld bytes of memory to read file %s\n",
+ (long int)st.st_size, filename);
+ fclose(f);
return (NULL);
}
- bytes_read = read(fd, p, st.st_size);
+ bytes_read = fread(p, 1, (size_t)st.st_size, f);
if (bytes_read < st.st_size) {
- fprintf(stderr, "Can't read file %s\n", filename);
- close(fd);
+ logprintf("Can't read file %s\n", filename);
+ fclose(f);
free(p);
return (NULL);
}
p[st.st_size] = '\0';
if (sizep != NULL)
*sizep = (size_t)st.st_size;
- close(fd);
+ fclose(f);
return (p);
}
-/*
- * "list.h" is automatically generated; it just has a lot of lines like:
- * DEFINE_TEST(function_name)
- * It's used above to declare all of the test functions.
- * We reuse it here to define a list of all tests (functions and names).
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(n) { n, #n },
-struct { void (*func)(void); const char *name; } tests[] = {
- #include "list.h"
-};
-
-/*
- * Each test is run in a private work dir. Those work dirs
- * do have consistent and predictable names, in case a group
- * of tests need to collaborate. However, there is no provision
- * for requiring that tests run in a certain order.
- */
-static int test_run(int i, const char *tmpdir)
-{
- int failures_before = failures;
-
- if (!quiet_flag) {
- printf("%d: %s\n", i, tests[i].name);
- fflush(stdout);
- }
-
- /*
- * Always explicitly chdir() in case the last test moved us to
- * a strange place.
- */
- if (chdir(tmpdir)) {
- fprintf(stderr,
- "ERROR: Couldn't chdir to temp dir %s\n",
- tmpdir);
- exit(1);
- }
- /* Create a temp directory for this specific test. */
- if (mkdir(tests[i].name, 0755)) {
- fprintf(stderr,
- "ERROR: Couldn't create temp dir ``%s''\n",
- tests[i].name);
- exit(1);
- }
- /* Chdir() to that work directory. */
- if (chdir(tests[i].name)) {
- fprintf(stderr,
- "ERROR: Couldn't chdir to temp dir ``%s''\n",
- tests[i].name);
- exit(1);
- }
- /* Explicitly reset the locale before each test. */
- setlocale(LC_ALL, "C");
- /* Run the actual test. */
- (*tests[i].func)();
- /* Summarize the results of this test. */
- summarize();
- /* If there were no failures, we can remove the work dir. */
- if (failures == failures_before) {
- if (!keep_temp_files && chdir(tmpdir) == 0) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- systemf("rmdir /S /Q %s", tests[i].name);
-#else
- systemf("rm -rf %s", tests[i].name);
-#endif
- }
- }
- /* Return appropriate status. */
- return (failures == failures_before ? 0 : 1);
-}
-
-static void usage(const char *program)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i;
-
- printf("Usage: %s [options] <test> <test> ...\n", program);
- printf("Default is to run all tests.\n");
- printf("Otherwise, specify the numbers of the tests you wish to run.\n");
- printf("Options:\n");
- printf(" -d Dump core after any failure, for debugging.\n");
- printf(" -k Keep all temp files.\n");
- printf(" Default: temp files for successful tests deleted.\n");
-#ifdef PROGRAM
- printf(" -p <path> Path to executable to be tested.\n");
- printf(" Default: path taken from " ENVBASE " environment variable.\n");
-#endif
- printf(" -q Quiet.\n");
- printf(" -r <dir> Path to dir containing reference files.\n");
- printf(" Default: Current directory.\n");
- printf(" -v Verbose.\n");
- printf("Available tests:\n");
- for (i = 0; i < limit; i++)
- printf(" %d: %s\n", i, tests[i].name);
- exit(1);
-}
-
+/* Read a uuencoded file from the reference directory, decode, and
+ * write the result into the current directory. */
#define UUDECODE(c) (((c) - 0x20) & 0x3f)
-
void
extract_reference_file(const char *name)
{
@@ -874,7 +1581,7 @@ extract_reference_file(const char *name)
}
/* Now, decode the rest and write it. */
/* Not a lot of error checking here; the input better be right. */
- out = fopen(name, "w");
+ out = fopen(name, "wb");
while (fgets(buff, sizeof(buff), in) != NULL) {
char *p = buff;
int bytes;
@@ -908,19 +1615,211 @@ extract_reference_file(const char *name)
fclose(in);
}
+/*
+ *
+ * TEST management
+ *
+ */
+
+/*
+ * "list.h" is simply created by "grep DEFINE_TEST test_*.c"; it has
+ * a line like
+ * DEFINE_TEST(test_function)
+ * for each test.
+ */
+
+/* Use "list.h" to declare all of the test functions. */
+#undef DEFINE_TEST
+#define DEFINE_TEST(name) void name(void);
+#include "list.h"
+
+/* Use "list.h" to create a list of all tests (functions and names). */
+#undef DEFINE_TEST
+#define DEFINE_TEST(n) { n, #n, 0 },
+struct { void (*func)(void); const char *name; int failures; } tests[] = {
+ #include "list.h"
+};
+
+/*
+ * Summarize repeated failures in the just-completed test.
+ */
+static void
+test_summarize(const char *filename, int failed)
+{
+ unsigned int i;
+
+ switch (verbosity) {
+ case VERBOSITY_SUMMARY_ONLY:
+ printf(failed ? "E" : ".");
+ fflush(stdout);
+ break;
+ case VERBOSITY_PASSFAIL:
+ printf(failed ? "FAIL\n" : "ok\n");
+ break;
+ }
+
+ log_console = (verbosity == VERBOSITY_LIGHT_REPORT);
+
+ for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
+ if (failed_lines[i].count > 1 && !failed_lines[i].skip)
+ logprintf("%s:%d: Summary: Failed %d times\n",
+ filename, i, failed_lines[i].count);
+ }
+ /* Clear the failure history for the next file. */
+ memset(failed_lines, 0, sizeof(failed_lines));
+}
+
+/*
+ * Actually run a single test, with appropriate setup and cleanup.
+ */
+static int
+test_run(int i, const char *tmpdir)
+{
+ char logfilename[64];
+ int failures_before = failures;
+ int oldumask;
+
+ switch (verbosity) {
+ case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */
+ break;
+ case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */
+ printf("%3d: %-50s", i, tests[i].name);
+ fflush(stdout);
+ break;
+ default: /* Title of test, details will follow */
+ printf("%3d: %s\n", i, tests[i].name);
+ }
+
+ /* Chdir to the top-level work directory. */
+ if (!assertChdir(tmpdir)) {
+ fprintf(stderr,
+ "ERROR: Can't chdir to top work dir %s\n", tmpdir);
+ exit(1);
+ }
+ /* Create a log file for this test. */
+ sprintf(logfilename, "%s.log", tests[i].name);
+ logfile = fopen(logfilename, "w");
+ fprintf(logfile, "%s\n\n", tests[i].name);
+ /* Chdir() to a work dir for this specific test. */
+ if (!assertMakeDir(tests[i].name, 0755)
+ || !assertChdir(tests[i].name)) {
+ fprintf(stderr,
+ "ERROR: Can't chdir to work dir %s/%s\n",
+ tmpdir, tests[i].name);
+ exit(1);
+ }
+ /* Explicitly reset the locale before each test. */
+ setlocale(LC_ALL, "C");
+ /* Record the umask before we run the test. */
+ umask(oldumask = umask(0));
+ /*
+ * Run the actual test.
+ */
+ (*tests[i].func)();
+ /*
+ * Clean up and report afterwards.
+ */
+ /* Restore umask */
+ umask(oldumask);
+ /* Reset locale. */
+ setlocale(LC_ALL, "C");
+ /* Reset directory. */
+ if (!assertChdir(tmpdir)) {
+ fprintf(stderr, "ERROR: Couldn't chdir to temp dir %s\n",
+ tmpdir);
+ exit(1);
+ }
+ /* Report per-test summaries. */
+ tests[i].failures = failures - failures_before;
+ test_summarize(test_filename, tests[i].failures);
+ /* Close the per-test log file. */
+ fclose(logfile);
+ logfile = NULL;
+ /* If there were no failures, we can remove the work dir and logfile. */
+ if (tests[i].failures == 0) {
+ if (!keep_temp_files && assertChdir(tmpdir)) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Make sure not to leave empty directories.
+ * Sometimes a processing of closing files used by tests
+ * is not done, then rmdir will be failed and it will
+ * leave a empty test directory. So we should wait a few
+ * seconds and retry rmdir. */
+ int r, t;
+ for (t = 0; t < 10; t++) {
+ if (t > 0)
+ Sleep(1000);
+ r = systemf("rmdir /S /Q %s", tests[i].name);
+ if (r == 0)
+ break;
+ }
+ systemf("del %s", logfilename);
+#else
+ systemf("rm -rf %s", tests[i].name);
+ systemf("rm %s", logfilename);
+#endif
+ }
+ }
+ /* Return appropriate status. */
+ return (tests[i].failures);
+}
+
+/*
+ *
+ *
+ * MAIN and support routines.
+ *
+ *
+ */
+
+static void
+usage(const char *program)
+{
+ static const int limit = sizeof(tests) / sizeof(tests[0]);
+ int i;
+
+ printf("Usage: %s [options] <test> <test> ...\n", program);
+ printf("Default is to run all tests.\n");
+ printf("Otherwise, specify the numbers of the tests you wish to run.\n");
+ printf("Options:\n");
+ printf(" -d Dump core after any failure, for debugging.\n");
+ printf(" -k Keep all temp files.\n");
+ printf(" Default: temp files for successful tests deleted.\n");
+#ifdef PROGRAM
+ printf(" -p <path> Path to executable to be tested.\n");
+ printf(" Default: path taken from " ENVBASE " environment variable.\n");
+#endif
+ printf(" -q Quiet.\n");
+ printf(" -r <dir> Path to dir containing reference files.\n");
+ printf(" Default: Current directory.\n");
+ printf(" -v Verbose.\n");
+ printf("Available tests:\n");
+ for (i = 0; i < limit; i++)
+ printf(" %d: %s\n", i, tests[i].name);
+ exit(1);
+}
static char *
-get_refdir(void)
+get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
+ /* If a dir was specified, try that */
+ if (d != NULL) {
+ pwd = NULL;
+ snprintf(buff, sizeof(buff), "%s", d);
+ p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
+ if (p != NULL) goto success;
+ strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
+ strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+ goto failure;
+ }
+
/* Get the current dir. */
pwd = getcwd(NULL, 0);
while (pwd[strlen(pwd) - 1] == '\n')
pwd[strlen(pwd) - 1] = '\0';
- printf("PWD: %s\n", pwd);
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
@@ -935,7 +1834,11 @@ get_refdir(void)
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#if defined(LIBRARY)
+ snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
+#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
+#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
@@ -955,11 +1858,12 @@ get_refdir(void)
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
}
+failure:
+ printf("Unable to locate known reference file %s\n", KNOWNREF);
+ printf(" Checked following directories:\n%s\n", tried);
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
DebugBreak();
#endif
- printf("Unable to locate known reference file %s\n", KNOWNREF);
- printf(" Checked following directories:\n%s\n", tried);
exit(1);
success:
@@ -968,27 +1872,27 @@ success:
return strdup(buff);
}
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i, tests_run = 0, tests_failed = 0, opt;
+ int i, tests_run = 0, tests_failed = 0, option;
time_t now;
char *refdir_alloc = NULL;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- char *testprg;
-#endif
- const char *opt_arg, *progname, *p;
+ const char *progname;
+ const char *tmp, *option_arg, *p;
char tmpdir[256];
char tmpdir_timestamp[256];
(void)argc; /* UNUSED */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure open() function will be used with a binary mode. */
- /* on cygwin, we need something similar, but instead link against */
- /* a special startup object, binmode.o */
- _set_fmode(_O_BINARY);
+#if defined(HAVE__CrtSetReportMode)
+ /* To stop to run the default invalid parameter handler. */
+ _set_invalid_parameter_handler(invalid_parameter_handler);
+ /* Disable annoying assertion message box. */
+ _CrtSetReportMode(_CRT_ASSERT, 0);
#endif
+
/*
* Name of this program, used to build root of our temp directory
* tree.
@@ -1003,9 +1907,20 @@ int main(int argc, char **argv)
#ifdef PROGRAM
/* Get the target program from environment, if available. */
- testprog = getenv(ENVBASE);
+ testprogfile = getenv(ENVBASE);
#endif
+ if (getenv("TMPDIR") != NULL)
+ tmp = getenv("TMPDIR");
+ else if (getenv("TMP") != NULL)
+ tmp = getenv("TMP");
+ else if (getenv("TEMP") != NULL)
+ tmp = getenv("TEMP");
+ else if (getenv("TEMPDIR") != NULL)
+ tmp = getenv("TEMPDIR");
+ else
+ tmp = "/tmp";
+
/* Allow -d to be controlled through the environment. */
if (getenv(ENVBASE "_DEBUG") != NULL)
dump_on_failure = 1;
@@ -1024,23 +1939,24 @@ int main(int argc, char **argv)
p = *argv++;
++p; /* Skip '-' */
while (*p != '\0') {
- opt = *p++;
- opt_arg = NULL;
+ option = *p++;
+ option_arg = NULL;
/* If 'opt' takes an argument, parse that. */
- if (opt == 'p' || opt == 'r') {
+ if (option == 'p' || option == 'r') {
if (*p != '\0')
- opt_arg = p;
+ option_arg = p;
else if (*argv == NULL) {
fprintf(stderr,
"Option -%c requires argument.\n",
- opt);
+ option);
usage(progname);
} else
- opt_arg = *argv++;
+ option_arg = *argv++;
p = ""; /* End of this option word. */
}
- switch (opt) {
+ /* Now, handle the option. */
+ switch (option) {
case 'd':
dump_on_failure = 1;
break;
@@ -1049,21 +1965,20 @@ int main(int argc, char **argv)
break;
case 'p':
#ifdef PROGRAM
- testprog = opt_arg;
+ testprogfile = option_arg;
#else
usage(progname);
#endif
break;
case 'q':
- quiet_flag++;
+ verbosity--;
break;
case 'r':
- refdir = opt_arg;
+ refdir = option_arg;
break;
case 'v':
- verbose = 1;
+ verbosity++;
break;
- case '?':
default:
usage(progname);
}
@@ -1074,20 +1989,26 @@ int main(int argc, char **argv)
* Sanity-check that our options make sense.
*/
#ifdef PROGRAM
- if (testprog == NULL)
+ if (testprogfile == NULL)
usage(progname);
-#endif
+ {
+ char *testprg;
#if defined(_WIN32) && !defined(__CYGWIN__)
- /*
- * Command.exe cannot accept the command used '/' with drive
- * name such as c:/xxx/command.exe when use '|' pipe handling.
- */
- testprg = strdup(testprog);
- for (i = 0; testprg[i] != '\0'; i++) {
- if (testprg[i] == '/')
- testprg[i] = '\\';
+ /* Command.com sometimes rejects '/' separators. */
+ testprg = strdup(testprogfile);
+ for (i = 0; testprg[i] != '\0'; i++) {
+ if (testprg[i] == '/')
+ testprg[i] = '\\';
+ }
+ testprogfile = testprg;
+#endif
+ /* Quote the name that gets put into shell command lines. */
+ testprg = malloc(strlen(testprogfile) + 3);
+ strcpy(testprg, "\"");
+ strcat(testprg, testprogfile);
+ strcat(testprg, "\"");
+ testprog = testprg;
}
- testprog = testprg;
#endif
/*
@@ -1096,32 +2017,37 @@ int main(int argc, char **argv)
* to make it easier to track the results of multiple tests.
*/
now = time(NULL);
- for (i = 0; i < 1000; i++) {
+ for (i = 0; ; i++) {
strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp),
"%Y-%m-%dT%H.%M.%S",
localtime(&now));
- sprintf(tmpdir, "/tmp/%s.%s-%03d", progname, tmpdir_timestamp, i);
- if (mkdir(tmpdir,0755) == 0)
+ sprintf(tmpdir, "%s/%s.%s-%03d", tmp, progname,
+ tmpdir_timestamp, i);
+ if (assertMakeDir(tmpdir,0755))
break;
- if (errno == EEXIST)
- continue;
- fprintf(stderr, "ERROR: Unable to create temp directory %s\n",
- tmpdir);
- exit(1);
+ if (i >= 999) {
+ fprintf(stderr,
+ "ERROR: Unable to create temp directory %s\n",
+ tmpdir);
+ exit(1);
+ }
}
/*
* If the user didn't specify a directory for locating
- * reference files, use the current directory for that.
+ * reference files, try to find the reference files in
+ * the "usual places."
*/
- if (refdir == NULL)
- refdir = refdir_alloc = get_refdir();
+ refdir = refdir_alloc = get_refdir(refdir);
/*
* Banner with basic information.
*/
- if (!quiet_flag) {
- printf("Running tests in: %s\n", tmpdir);
+ printf("\n");
+ printf("If tests fail or crash, details will be in:\n");
+ printf(" %s\n", tmpdir);
+ printf("\n");
+ if (verbosity > VERBOSITY_SUMMARY_ONLY) {
printf("Reference files will be read from: %s\n", refdir);
#ifdef PROGRAM
printf("Running tests on: %s\n", testprog);
@@ -1129,6 +2055,9 @@ int main(int argc, char **argv)
printf("Exercising: ");
fflush(stdout);
printf("%s\n", EXTRA_VERSION);
+ } else {
+ printf("Running ");
+ fflush(stdout);
}
/*
@@ -1143,15 +2072,30 @@ int main(int argc, char **argv)
}
} else {
while (*(argv) != NULL) {
- i = atoi(*argv);
- if (**argv < '0' || **argv > '9' || i < 0 || i >= limit) {
- printf("*** INVALID Test %s\n", *argv);
- usage(progname);
+ if (**argv >= '0' && **argv <= '9') {
+ i = atoi(*argv);
+ if (i < 0 || i >= limit) {
+ printf("*** INVALID Test %s\n", *argv);
+ free(refdir_alloc);
+ usage(progname);
+ /* usage() never returns */
+ }
} else {
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
+ for (i = 0; i < limit; ++i) {
+ if (strcmp(*argv, tests[i].name) == 0)
+ break;
+ }
+ if (i >= limit) {
+ printf("*** INVALID Test ``%s''\n",
+ *argv);
+ free(refdir_alloc);
+ usage(progname);
+ /* usage() never returns */
+ }
}
+ if (test_run(i, tmpdir))
+ tests_failed++;
+ tests_run++;
argv++;
}
}
@@ -1159,20 +2103,38 @@ int main(int argc, char **argv)
/*
* Report summary statistics.
*/
- if (!quiet_flag) {
+ if (verbosity > VERBOSITY_SUMMARY_ONLY) {
printf("\n");
- printf("%d of %d tests reported failures\n",
- tests_failed, tests_run);
- printf(" Total of %d assertions checked.\n", assertions);
- printf(" Total of %d assertions failed.\n", failures);
- printf(" Total of %d assertions skipped.\n", skips);
+ printf("Totals:\n");
+ printf(" Tests run: %8d\n", tests_run);
+ printf(" Tests failed: %8d\n", tests_failed);
+ printf(" Assertions checked:%8d\n", assertions);
+ printf(" Assertions failed: %8d\n", failures);
+ printf(" Skips reported: %8d\n", skips);
+ }
+ if (failures) {
+ printf("\n");
+ printf("Failing tests:\n");
+ for (i = 0; i < limit; ++i) {
+ if (tests[i].failures)
+ printf(" %d: %s (%d failures)\n", i,
+ tests[i].name, tests[i].failures);
+ }
+ printf("\n");
+ printf("Details for failing tests: %s\n", tmpdir);
+ printf("\n");
+ } else {
+ if (verbosity == VERBOSITY_SUMMARY_ONLY)
+ printf("\n");
+ printf("%d tests passed, no failures\n", tests_run);
}
free(refdir_alloc);
/* If the final tmpdir is empty, we can remove it. */
/* This should be the usual case when all tests succeed. */
+ assertChdir("..");
rmdir(tmpdir);
- return (tests_failed);
+ return (tests_failed ? 1 : 0);
}
diff --git a/usr.bin/cpio/test/test.h b/usr.bin/cpio/test/test.h
index be28dd4..8b1352a 100644
--- a/usr.bin/cpio/test/test.h
+++ b/usr.bin/cpio/test/test.h
@@ -45,47 +45,84 @@
#error Oops: No config.h and no pre-built configuration in test.h.
#endif
-#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <sys/types.h> /* Windows requires this before sys/stat.h */
+#include <sys/stat.h>
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+#if HAVE_DIRENT_H
#include <dirent.h>
-#else
-#include "../cpio_windows.h"
#endif
-#if defined(__CYGWIN__)
-/* In cygwin-1.7.x, the .nlinks field of directories is
- * deliberately inaccurate, because to populate it requires
- * stat'ing every file in the directory, which is slow.
- * So, as an optimization cygwin doesn't do that in newer
- * releases; all correct applications on any platform should
- * never rely on it being > 1, so this optimization doesn't
- * impact the operation of correctly coded applications.
- * Therefore, the cpio test should not check its accuracy
- */
-# define NLINKS_INACCURATE_FOR_DIRS
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
-#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <time.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include <time.h>
#include <wchar.h>
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
#endif
-/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
-#ifdef __FreeBSD__
-#include <sys/cdefs.h> /* For __FBSDID */
+/*
+ * System-specific tweaks. We really want to minimize these
+ * as much as possible, since they make it harder to understand
+ * the mainline code.
+ */
+
+/* Windows (including Visual Studio and MinGW but not Cygwin) */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include "../cpio_windows.h"
+#if !defined(__BORLANDC__)
+#define strdup _strdup
+#endif
+#define LOCALE_DE "deu"
#else
-#undef __FBSDID
+#define LOCALE_DE "de_DE.UTF-8"
+#endif
+
+/* Visual Studio */
+#ifdef _MSC_VER
+#define snprintf sprintf_s
+#endif
+
+/* Cygwin */
+#if defined(__CYGWIN__)
+/* Cygwin-1.7.x is lazy about populating nlinks, so don't
+ * expect it to be accurate. */
+# define NLINKS_INACCURATE_FOR_DIRS
+#endif
+
+#if defined(__HAIKU__) || defined(__QNXNTO__)
+/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
+#include <stdint.h>
+#endif
+
+/* Get a real definition for __FBSDID if we can */
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+
+/* If not, define it so as to avoid dangling semicolons. */
+#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
@@ -93,40 +130,81 @@
#define DEFINE_TEST(name) void name(void); void name(void)
/* An implementation of the standard assert() macro */
-#define assert(e) test_assert(__FILE__, __LINE__, (e), #e, NULL)
-
+#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
+/* chdir() and error if it fails */
+#define assertChdir(path) \
+ assertion_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
-#define assertEqualInt(v1,v2) \
- test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-
+#define assertEqualInt(v1,v2) \
+ assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
- test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
- test_assert_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+ assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
- test_assert_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
+ assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert two files are the same; allow printf-style expansion of second name.
* See below for comments about variable arguments here...
*/
#define assertEqualFile \
- test_setup(__FILE__, __LINE__);test_assert_equal_file
+ assertion_setup(__FILE__, __LINE__);assertion_equal_file
/* Assert that a file is empty; supports printf-style arguments. */
#define assertEmptyFile \
- test_setup(__FILE__, __LINE__);test_assert_empty_file
+ assertion_setup(__FILE__, __LINE__);assertion_empty_file
+/* Assert that a file is not empty; supports printf-style arguments. */
+#define assertNonEmptyFile \
+ assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
+#define assertFileAtime(pathname, sec, nsec) \
+ assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
+#define assertFileAtimeRecent(pathname) \
+ assertion_file_atime_recent(__FILE__, __LINE__, pathname)
+#define assertFileBirthtime(pathname, sec, nsec) \
+ assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
+#define assertFileBirthtimeRecent(pathname) \
+ assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists \
- test_setup(__FILE__, __LINE__);test_assert_file_exists
+ assertion_setup(__FILE__, __LINE__);assertion_file_exists
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileNotExists \
- test_setup(__FILE__, __LINE__);test_assert_file_not_exists
+ assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
/* Assert that file contents match a string; supports printf-style arguments. */
#define assertFileContents \
- test_setup(__FILE__, __LINE__);test_assert_file_contents
+ assertion_setup(__FILE__, __LINE__);assertion_file_contents
+#define assertFileMtime(pathname, sec, nsec) \
+ assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
+#define assertFileMtimeRecent(pathname) \
+ assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
+#define assertFileNLinks(pathname, nlinks) \
+ assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
+#define assertFileSize(pathname, size) \
+ assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertTextFileContents \
- test_setup(__FILE__, __LINE__);test_assert_text_file_contents
+ assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
+#define assertIsDir(pathname, mode) \
+ assertion_is_dir(__FILE__, __LINE__, pathname, mode)
+#define assertIsHardlink(path1, path2) \
+ assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
+#define assertIsNotHardlink(path1, path2) \
+ assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
+#define assertIsReg(pathname, mode) \
+ assertion_is_reg(__FILE__, __LINE__, pathname, mode)
+#define assertIsSymlink(pathname, contents) \
+ assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
+/* Create a directory, report error if it fails. */
+#define assertMakeDir(dirname, mode) \
+ assertion_make_dir(__FILE__, __LINE__, dirname, mode)
+#define assertMakeFile(path, mode, contents) \
+ assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+#define assertMakeHardlink(newfile, oldfile) \
+ assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
+#define assertMakeSymlink(newfile, linkto) \
+ assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
+#define assertUmask(mask) \
+ assertion_umask(__FILE__, __LINE__, mask)
/*
* This would be simple with C99 variadic macros, but I don't want to
@@ -135,27 +213,60 @@
* but effective.
*/
#define skipping \
- test_setup(__FILE__, __LINE__);test_skipping
+ assertion_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
-void test_setup(const char *, int);
+int assertion_assert(const char *, int, int, const char *, void *);
+int assertion_chdir(const char *, int, const char *);
+int assertion_empty_file(const char *, ...);
+int assertion_equal_file(const char *, const char *, ...);
+int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
+int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
+int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
+int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
+int assertion_file_atime(const char *, int, const char *, long, long);
+int assertion_file_atime_recent(const char *, int, const char *);
+int assertion_file_birthtime(const char *, int, const char *, long, long);
+int assertion_file_birthtime_recent(const char *, int, const char *);
+int assertion_file_contents(const void *, int, const char *, ...);
+int assertion_file_exists(const char *, ...);
+int assertion_file_mtime(const char *, int, const char *, long, long);
+int assertion_file_mtime_recent(const char *, int, const char *);
+int assertion_file_nlinks(const char *, int, const char *, int);
+int assertion_file_not_exists(const char *, ...);
+int assertion_file_size(const char *, int, const char *, long);
+int assertion_is_dir(const char *, int, const char *, int);
+int assertion_is_hardlink(const char *, int, const char *, const char *);
+int assertion_is_not_hardlink(const char *, int, const char *, const char *);
+int assertion_is_reg(const char *, int, const char *, int);
+int assertion_is_symlink(const char *, int, const char *, const char *);
+int assertion_make_dir(const char *, int, const char *, int);
+int assertion_make_file(const char *, int, const char *, int, const char *);
+int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
+int assertion_make_symlink(const char *, int, const char *newpath, const char *);
+int assertion_non_empty_file(const char *, ...);
+int assertion_text_file_contents(const char *buff, const char *f);
+int assertion_umask(const char *, int, int);
+void assertion_setup(const char *, int);
+
void test_skipping(const char *fmt, ...);
-int test_assert(const char *, int, int, const char *, void *);
-int test_assert_empty_file(const char *, ...);
-int test_assert_equal_file(const char *, const char *, ...);
-int test_assert_equal_int(const char *, int, int, const char *, int, const char *, void *);
-int test_assert_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
-int test_assert_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
-int test_assert_equal_mem(const char *, int, const char *, const char *, const char *, const char *, size_t, const char *, void *);
-int test_assert_file_contents(const void *, int, const char *, ...);
-int test_assert_text_file_contents(const char *buff, const char *f);
-int test_assert_file_exists(const char *, ...);
-int test_assert_file_not_exists(const char *, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
+/* Delay until time() returns a value after this. */
+void sleepUntilAfter(time_t);
+
+/* Return true if this platform can create symlinks. */
+int canSymlink(void);
+
+/* Return true if this platform can run the "gzip" program. */
+int canGzip(void);
+
+/* Return true if this platform can run the "gunzip" program. */
+int canGunzip(void);
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
@@ -168,4 +279,7 @@ void extract_reference_file(const char *);
*/
/* Pathname of exe to be tested. */
+const char *testprogfile;
+/* Name of exe to use in printf-formatted command strings. */
+/* On Windows, this includes leading/trailing quotes. */
const char *testprog;
diff --git a/usr.bin/cpio/test/test_0.c b/usr.bin/cpio/test/test_0.c
index d224daa..75a1437 100644
--- a/usr.bin/cpio/test/test_0.c
+++ b/usr.bin/cpio/test/test_0.c
@@ -39,11 +39,11 @@ DEFINE_TEST(test_0)
{
struct stat st;
- failure("File %s does not exist?!", testprog);
- if (!assertEqualInt(0, stat(testprog, &st)))
+ failure("File %s does not exist?!", testprogfile);
+ if (!assertEqualInt(0, stat(testprogfile, &st)))
exit(1);
- failure("%s is not executable?!", testprog);
+ failure("%s is not executable?!", testprogfile);
if (!assert((st.st_mode & 0111) != 0))
exit(1);
diff --git a/usr.bin/cpio/test/test_basic.c b/usr.bin/cpio/test/test_basic.c
index a4eb60f..3a3fae8 100644
--- a/usr.bin/cpio/test/test_basic.c
+++ b/usr.bin/cpio/test/test_basic.c
@@ -26,106 +26,32 @@
__FBSDID("$FreeBSD$");
static void
-verify_files(const char *target)
+verify_files(const char *msg)
{
- struct stat st, st2;
-#if !defined(_WIN32) || defined(__CYGWIN__)
- char buff[128];
-#endif
- int r;
-
/*
* Verify unpacked files.
*/
/* Regular file with 2 links. */
- r = lstat("file", &st);
- failure("Failed to stat file %s/file, errno=%d", target, errno);
- assertEqualInt(r, 0);
- if (r == 0) {
- assert(S_ISREG(st.st_mode));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
- assertEqualInt(0600, st.st_mode & 0700);
-#else
- assertEqualInt(0644, st.st_mode & 0777);
-#endif
- assertEqualInt(10, st.st_size);
- failure("file %s/file should have 2 links", target);
- assertEqualInt(2, st.st_nlink);
- }
+ assertIsReg("file", 0644);
+ failure(msg);
+ assertFileSize("file", 10);
+ assertFileNLinks("file", 2);
/* Another name for the same file. */
- r = lstat("linkfile", &st2);
- failure("Failed to stat file %s/linkfile, errno=%d", target, errno);
- assertEqualInt(r, 0);
- if (r == 0) {
- assert(S_ISREG(st2.st_mode));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
- assertEqualInt(0600, st2.st_mode & 0700);
-#else
- assertEqualInt(0644, st2.st_mode & 0777);
-#endif
- assertEqualInt(10, st2.st_size);
- failure("file %s/linkfile should have 2 links", target);
- assertEqualInt(2, st2.st_nlink);
- /* Verify that the two are really hardlinked. */
- assertEqualInt(st.st_dev, st2.st_dev);
- failure("%s/linkfile and %s/file should be hardlinked",
- target, target);
- assertEqualInt(st.st_ino, st2.st_ino);
- }
+ assertIsHardlink("linkfile", "file");
/* Symlink */
- r = lstat("symlink", &st);
- failure("Failed to stat file %s/symlink, errno=%d", target, errno);
- assertEqualInt(r, 0);
-#if !defined(_WIN32) || defined(__CYGWIN__)
- if (r == 0) {
- failure("symlink should be a symlink; actual mode is %o",
- st.st_mode);
- assert(S_ISLNK(st.st_mode));
- if (S_ISLNK(st.st_mode)) {
- r = readlink("symlink", buff, sizeof(buff));
- assertEqualInt(r, 4);
- buff[r] = '\0';
- assertEqualString(buff, "file");
- }
- }
-#endif
+ if (canSymlink())
+ assertIsSymlink("symlink", "file");
/* Another file with 1 link and different permissions. */
- r = lstat("file2", &st);
- failure("Failed to stat file %s/file2, errno=%d", target, errno);
- assertEqualInt(r, 0);
- if (r == 0) {
- assert(S_ISREG(st.st_mode));
- failure("%s/file2: st.st_mode = %o", target, st.st_mode);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Execution bit and group members bits and others
- * bits do not work. */
- assertEqualInt(0600, st.st_mode & 0700);
-#else
- assertEqualInt(0777, st.st_mode & 0777);
-#endif
- assertEqualInt(10, st.st_size);
- failure("file %s/file2 should have 1 link", target);
- assertEqualInt(1, st.st_nlink);
- }
+ assertIsReg("file2", 0777);
+ assertFileSize("file2", 10);
+ assertFileNLinks("file2", 1);
/* dir */
- r = lstat("dir", &st);
- if (r == 0) {
- assertEqualInt(r, 0);
- assert(S_ISDIR(st.st_mode));
- failure("%s/dir: st.st_mode = %o", target, st.st_mode);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualInt(0700, st.st_mode & 0700);
-#else
- assertEqualInt(0775, st.st_mode & 0777);
-#endif
- }
+ assertIsDir("dir", 0775);
}
static void
@@ -136,7 +62,7 @@ basic_cpio(const char *target,
{
int r;
- if (!assertEqualInt(0, mkdir(target, 0775)))
+ if (!assertMakeDir(target, 0775))
return;
/* Use the cpio program to create an archive. */
@@ -145,7 +71,7 @@ basic_cpio(const char *target,
failure("Error invoking %s -o %s", testprog, pack_options);
assertEqualInt(r, 0);
- chdir(target);
+ assertChdir(target);
/* Verify stderr. */
failure("Expected: %s, options=%s", se, pack_options);
@@ -163,9 +89,9 @@ basic_cpio(const char *target,
failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
assertTextFileContents(se, "unpack.err");
- verify_files(target);
+ verify_files(pack_options);
- chdir("..");
+ assertChdir("..");
}
static void
@@ -173,7 +99,7 @@ passthrough(const char *target)
{
int r;
- if (!assertEqualInt(0, mkdir(target, 0775)))
+ if (!assertMakeDir(target, 0775))
return;
/*
@@ -184,77 +110,64 @@ passthrough(const char *target)
failure("Error invoking %s -p", testprog);
assertEqualInt(r, 0);
- chdir(target);
+ assertChdir(target);
/* Verify stderr. */
failure("Error invoking %s -p in dir %s",
testprog, target);
assertTextFileContents("1 block\n", "stderr");
- verify_files(target);
- chdir("..");
+ verify_files("passthrough");
+ assertChdir("..");
}
DEFINE_TEST(test_basic)
{
- int fd;
- int filelist;
- int oldumask;
+ FILE *filelist;
+ const char *msg;
- oldumask = umask(0);
+ assertUmask(0);
/*
* Create an assortment of files on disk.
*/
- filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
+ filelist = fopen("filelist", "w");
/* File with 10 bytes content. */
- fd = open("file", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(10, write(fd, "123456789", 10));
- close(fd);
- write(filelist, "file\n", 5);
+ assertMakeFile("file", 0644, "1234567890");
+ fprintf(filelist, "file\n");
/* hardlink to above file. */
- assertEqualInt(0, link("file", "linkfile"));
- write(filelist, "linkfile\n", 9);
+ assertMakeHardlink("linkfile", "file");
+ fprintf(filelist, "linkfile\n");
/* Symlink to above file. */
- assertEqualInt(0, symlink("file", "symlink"));
- write(filelist, "symlink\n", 8);
+ if (canSymlink()) {
+ assertMakeSymlink("symlink", "file");
+ fprintf(filelist, "symlink\n");
+ }
/* Another file with different permissions. */
- fd = open("file2", O_CREAT | O_WRONLY, 0777);
- assert(fd >= 0);
- assertEqualInt(10, write(fd, "123456789", 10));
- close(fd);
- write(filelist, "file2\n", 6);
+ assertMakeFile("file2", 0777, "1234567890");
+ fprintf(filelist, "file2\n");
/* Directory. */
- assertEqualInt(0, mkdir("dir", 0775));
- write(filelist, "dir\n", 4);
+ assertMakeDir("dir", 0775);
+ fprintf(filelist, "dir\n");
/* All done. */
- close(filelist);
+ fclose(filelist);
- umask(022);
+ assertUmask(022);
/* Archive/dearchive with a variety of options. */
- basic_cpio("copy", "", "", "2 blocks\n");
- basic_cpio("copy_odc", "--format=odc", "", "2 blocks\n");
+ msg = canSymlink() ? "2 blocks\n" : "1 block\n";
+ basic_cpio("copy", "", "", msg);
+ basic_cpio("copy_odc", "--format=odc", "", msg);
basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
- basic_cpio("copy_cpio", "-H odc", "", "2 blocks\n");
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /*
- * On Windows, symbolic link does not work.
- * Currentry copying file instead. therefore block size is
- * different.
- */
- basic_cpio("copy_ustar", "-H ustar", "", "10 blocks\n");
-#else
- basic_cpio("copy_ustar", "-H ustar", "", "9 blocks\n");
-#endif
+ basic_cpio("copy_cpio", "-H odc", "", msg);
+ msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
+ basic_cpio("copy_ustar", "-H ustar", "", msg);
+
/* Copy in one step using -p */
passthrough("passthrough");
-
- umask(oldumask);
}
diff --git a/usr.bin/cpio/test/test_cmdline.c b/usr.bin/cpio/test/test_cmdline.c
new file mode 100644
index 0000000..2dd7d65
--- /dev/null
+++ b/usr.bin/cpio/test/test_cmdline.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * 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(S) ``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(S) 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.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Test the command-line parsing.
+ */
+
+DEFINE_TEST(test_cmdline)
+{
+ FILE *f;
+
+ /* Create an empty file. */
+ f = fopen("empty", "wb");
+ assert(f != NULL);
+ fclose(f);
+
+ failure("-Q is an invalid option on every cpio program I know of");
+ assert(0 != systemf("%s -i -Q <empty >1.out 2>1.err", testprog));
+ assertEmptyFile("1.out");
+
+ failure("-f requires an argument");
+ assert(0 != systemf("%s -if <empty >2.out 2>2.err", testprog));
+ assertEmptyFile("2.out");
+
+ failure("-f requires an argument");
+ assert(0 != systemf("%s -i -f <empty >3.out 2>3.err", testprog));
+ assertEmptyFile("3.out");
+
+ failure("--format requires an argument");
+ assert(0 != systemf("%s -i --format <empty >4.out 2>4.err", testprog));
+ assertEmptyFile("4.out");
+
+ failure("--badopt is an invalid option");
+ assert(0 != systemf("%s -i --badop <empty >5.out 2>5.err", testprog));
+ assertEmptyFile("5.out");
+
+ failure("--badopt is an invalid option");
+ assert(0 != systemf("%s -i --badopt <empty >6.out 2>6.err", testprog));
+ assertEmptyFile("6.out");
+
+ failure("--n is ambiguous");
+ assert(0 != systemf("%s -i --n <empty >7.out 2>7.err", testprog));
+ assertEmptyFile("7.out");
+
+ failure("--create forbids an argument");
+ assert(0 != systemf("%s --create=arg <empty >8.out 2>8.err", testprog));
+ assertEmptyFile("8.out");
+
+ failure("-i with empty input should succeed");
+ assert(0 == systemf("%s -i <empty >9.out 2>9.err", testprog));
+ assertEmptyFile("9.out");
+
+ failure("-o with empty input should succeed");
+ assert(0 == systemf("%s -o <empty >10.out 2>10.err", testprog));
+
+ failure("-i -p is nonsense");
+ assert(0 != systemf("%s -i -p <empty >11.out 2>11.err", testprog));
+ assertEmptyFile("11.out");
+
+ failure("-p -i is nonsense");
+ assert(0 != systemf("%s -p -i <empty >12.out 2>12.err", testprog));
+ assertEmptyFile("12.out");
+
+ failure("-i -o is nonsense");
+ assert(0 != systemf("%s -i -o <empty >13.out 2>13.err", testprog));
+ assertEmptyFile("13.out");
+
+ failure("-o -i is nonsense");
+ assert(0 != systemf("%s -o -i <empty >14.out 2>14.err", testprog));
+ assertEmptyFile("14.out");
+
+ failure("-o -p is nonsense");
+ assert(0 != systemf("%s -o -p <empty >15.out 2>15.err", testprog));
+ assertEmptyFile("15.out");
+
+ failure("-p -o is nonsense");
+ assert(0 != systemf("%s -p -o <empty >16.out 2>16.err", testprog));
+ assertEmptyFile("16.out");
+
+ failure("-p with empty input should fail");
+ assert(0 != systemf("%s -p <empty >17.out 2>17.err", testprog));
+ assertEmptyFile("17.out");
+}
diff --git a/usr.bin/cpio/test/test_format_newc.c b/usr.bin/cpio/test/test_format_newc.c
index 816f074..eb87c31 100644
--- a/usr.bin/cpio/test/test_format_newc.c
+++ b/usr.bin/cpio/test/test_format_newc.c
@@ -25,6 +25,13 @@
#include "test.h"
__FBSDID("$FreeBSD$");
+/* Number of bytes needed to pad 'n' to multiple of 'block', assuming
+ * that 'block' is a power of two. This trick can be more easily
+ * remembered as -n & (block - 1), but many compilers quite reasonably
+ * warn about "-n" when n is an unsigned value. (~(n) + 1) is the
+ * same thing, but written in a way that won't offend anyone. */
+#define PAD(n, block) ((~(n) + 1) & ((block) - 1))
+
static int
is_hex(const char *p, size_t l)
{
@@ -63,60 +70,67 @@ from_hex(const char *p, size_t l)
DEFINE_TEST(test_format_newc)
{
- int fd, list;
+ FILE *list;
int r;
int devmajor, devminor, ino, gid;
+ int uid = -1;
time_t t, t2, now;
char *p, *e;
size_t s, fs, ns;
- mode_t oldmask;
- oldmask = umask(0);
+ assertUmask(0);
+
+#if !defined(_WIN32)
+ uid = getuid();
+#endif
/*
* Create an assortment of files.
* TODO: Extend this to cover more filetypes.
*/
- list = open("list", O_CREAT | O_WRONLY, 0644);
+ list = fopen("list", "w");
/* "file1" */
- fd = open("file1", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(10, write(fd, "123456789", 10));
- close(fd);
- assertEqualInt(6, write(list, "file1\n", 6));
+ assertMakeFile("file1", 0644, "1234567890");
+ fprintf(list, "file1\n");
/* "hardlink" */
- assertEqualInt(0, link("file1", "hardlink"));
- assertEqualInt(9, write(list, "hardlink\n", 9));
+ assertMakeHardlink("hardlink", "file1");
+ fprintf(list, "hardlink\n");
/* Another hardlink, but this one won't be archived. */
- assertEqualInt(0, link("file1", "hardlink2"));
+ assertMakeHardlink("hardlink2", "file1");
/* "symlink" */
- assertEqualInt(0, symlink("file1", "symlink"));
- assertEqualInt(8, write(list, "symlink\n", 8));
+ if (canSymlink()) {
+ assertMakeSymlink("symlink", "file1");
+ fprintf(list, "symlink\n");
+ }
/* "dir" */
- assertEqualInt(0, mkdir("dir", 0775));
- assertEqualInt(4, write(list, "dir\n", 4));
+ assertMakeDir("dir", 0775);
+ fprintf(list, "dir\n");
/* Record some facts about what we just created: */
now = time(NULL); /* They were all created w/in last two seconds. */
/* Use the cpio program to create an archive. */
- close(list);
+ fclose(list);
r = systemf("%s -o --format=newc <list >newc.out 2>newc.err",
testprog);
if (!assertEqualInt(r, 0))
return;
/* Verify that nothing went to stderr. */
- assertTextFileContents("2 blocks\n", "newc.err");
+ if (canSymlink()) {
+ assertTextFileContents("2 blocks\n", "newc.err");
+ } else {
+ assertTextFileContents("1 block\n", "newc.err");
+ }
/* Verify that stdout is a well-formed cpio file in "newc" format. */
p = slurpfile(&s, "newc.out");
- assertEqualInt(s, 1024);
+ assertEqualInt(s, canSymlink() ? 1024 : 512);
e = p;
/*
@@ -133,8 +147,10 @@ DEFINE_TEST(test_format_newc)
assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */
#else
assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
-#endif
- assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
+#endif
+ if (uid < 0)
+ uid = from_hex(e + 22, 8);
+ assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
gid = from_hex(e + 30, 8); /* gid */
assertEqualMem(e + 38, "00000003", 8); /* nlink */
t = from_hex(e + 46, 8); /* mtime */
@@ -147,68 +163,60 @@ DEFINE_TEST(test_format_newc)
" field should be zero");
assertEqualInt(0, from_hex(e + 54, 8)); /* File size */
fs = from_hex(e + 54, 8);
- fs += 3 & -fs;
+ fs += PAD(fs, 4);
devmajor = from_hex(e + 62, 8); /* devmajor */
devminor = from_hex(e + 70, 8); /* devminor */
assert(is_hex(e + 78, 8)); /* rdevmajor */
assert(is_hex(e + 86, 8)); /* rdevminor */
assertEqualMem(e + 94, "00000006", 8); /* Name size */
ns = from_hex(e + 94, 8);
- ns += 3 & (-ns - 2);
+ ns += PAD(ns + 2, 4);
assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
assertEqualMem(e + 110, "file1\0", 6); /* Name contents */
/* Since there's another link, no file contents here. */
/* But add in file size so that an error here doesn't cascade. */
e += 110 + fs + ns;
- /* "symlink" pointing to "file1" */
- assert(is_hex(e, 110));
- assertEqualMem(e + 0, "070701", 6); /* Magic */
- assert(is_hex(e + 6, 8)); /* ino */
-#if !defined(_WIN32) || defined(__CYGWIN__)
- /* On Windows, symbolic link and group members bits and
- * others bits do not work. */
- assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
-#endif
- assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
- assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
- assertEqualMem(e + 38, "00000001", 8); /* nlink */
- t2 = from_hex(e + 46, 8); /* mtime */
- failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
- assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Symbolic link does not work. */
- assertEqualMem(e + 54, "0000000a", 8); /* File size */
-#else
- assertEqualMem(e + 54, "00000005", 8); /* File size */
-#endif
- fs = from_hex(e + 54, 8);
- fs += 3 & -fs;
- assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
- assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
- assert(is_hex(e + 78, 8)); /* rdevmajor */
- assert(is_hex(e + 86, 8)); /* rdevminor */
- assertEqualMem(e + 94, "00000008", 8); /* Name size */
- ns = from_hex(e + 94, 8);
- ns += 3 & (-ns - 2);
- assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
- assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */
-#if !defined(_WIN32) || defined(__CYGWIN__)
- assertEqualMem(e + 110 + ns, "file1\0\0\0", 8); /* symlink target */
-#endif
- e += 110 + fs + ns;
+ if (canSymlink()) {
+ /* "symlink" pointing to "file1" */
+ assert(is_hex(e, 110));
+ assertEqualMem(e + 0, "070701", 6); /* Magic */
+ assert(is_hex(e + 6, 8)); /* ino */
+ assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
+ assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
+ assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
+ assertEqualMem(e + 38, "00000001", 8); /* nlink */
+ t2 = from_hex(e + 46, 8); /* mtime */
+ failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
+ assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
+ assertEqualMem(e + 54, "00000005", 8); /* File size */
+ fs = from_hex(e + 54, 8);
+ fs += PAD(fs, 4);
+ assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
+ assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
+ assert(is_hex(e + 78, 8)); /* rdevmajor */
+ assert(is_hex(e + 86, 8)); /* rdevminor */
+ assertEqualMem(e + 94, "00000008", 8); /* Name size */
+ ns = from_hex(e + 94, 8);
+ ns += PAD(ns + 2, 4);
+ assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
+ assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */
+ assertEqualMem(e + 110 + ns, "file1\0\0\0", 8); /* symlink target */
+ e += 110 + fs + ns;
+ }
/* "dir" */
assert(is_hex(e, 110));
assertEqualMem(e + 0, "070701", 6); /* Magic */
assert(is_hex(e + 6, 8)); /* ino */
#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
+ /* Group members bits and others bits do not work. */
assertEqualInt(0x41c0, from_hex(e + 14, 8) & 0xffc0); /* Mode */
#else
- assertEqualInt(0x41fd, from_hex(e + 14, 8)); /* Mode */
+ /* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */
+ assertEqualInt(040775, from_hex(e + 14, 8) & ~02000);
#endif
- assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
+ assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
#ifndef NLINKS_INACCURATE_FOR_DIRS
assertEqualMem(e + 38, "00000002", 8); /* nlink */
@@ -218,14 +226,14 @@ DEFINE_TEST(test_format_newc)
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
assertEqualMem(e + 54, "00000000", 8); /* File size */
fs = from_hex(e + 54, 8);
- fs += 3 & -fs;
+ fs += PAD(fs, 4);
assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
assert(is_hex(e + 78, 8)); /* rdevmajor */
assert(is_hex(e + 86, 8)); /* rdevminor */
assertEqualMem(e + 94, "00000004", 8); /* Name size */
ns = from_hex(e + 94, 8);
- ns += 3 & (-ns - 2);
+ ns += PAD(ns + 2, 4);
assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */
e += 110 + fs + ns;
@@ -243,7 +251,7 @@ DEFINE_TEST(test_format_newc)
#else
assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
#endif
- assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
+ assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
assertEqualMem(e + 38, "00000003", 8); /* nlink */
t2 = from_hex(e + 46, 8); /* mtime */
@@ -251,17 +259,17 @@ DEFINE_TEST(test_format_newc)
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
assertEqualInt(10, from_hex(e + 54, 8)); /* File size */
fs = from_hex(e + 54, 8);
- fs += 3 & -fs;
+ fs += PAD(fs, 4);
assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
assert(is_hex(e + 78, 8)); /* rdevmajor */
assert(is_hex(e + 86, 8)); /* rdevminor */
assertEqualMem(e + 94, "00000009", 8); /* Name size */
ns = from_hex(e + 94, 8);
- ns += 3 & (-ns - 2);
+ ns += PAD(ns + 2, 4);
assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */
- assertEqualMem(e + 110 + ns, "123456789\0\0\0", 12); /* File contents */
+ assertEqualMem(e + 110 + ns, "1234567890\0\0", 12); /* File contents */
e += 110 + ns + fs;
/* Last entry is end-of-archive marker. */
@@ -283,6 +291,4 @@ DEFINE_TEST(test_format_newc)
assertEqualMem(e + 110, "TRAILER!!!\0\0", 12); /* Name */
free(p);
-
- umask(oldmask);
}
diff --git a/usr.bin/cpio/test/test_gcpio_compat.c b/usr.bin/cpio/test/test_gcpio_compat.c
index 767719b..3d992c4 100644
--- a/usr.bin/cpio/test/test_gcpio_compat.c
+++ b/usr.bin/cpio/test/test_gcpio_compat.c
@@ -28,15 +28,11 @@ __FBSDID("$FreeBSD$");
static void
unpack_test(const char *from, const char *options, const char *se)
{
- struct stat st, st2;
-#if !defined(_WIN32) || defined(__CYGWIN__)
- char buff[128];
-#endif
int r;
/* Create a work dir named after the file we're unpacking. */
- assertEqualInt(0, mkdir(from, 0775));
- chdir(from);
+ assertMakeDir(from, 0775);
+ assertChdir(from);
/*
* Use cpio to unpack the sample archive
@@ -49,96 +45,64 @@ unpack_test(const char *from, const char *options, const char *se)
assertEqualInt(r, 0);
/* Verify that nothing went to stderr. */
- failure("Error invoking %s -i %s < %s", testprog, options, from);
- assertTextFileContents(se, "unpack.err");
+ if (canSymlink()) {
+ failure("Error invoking %s -i %s < %s",
+ testprog, options, from);
+ assertTextFileContents(se, "unpack.err");
+ }
/*
* Verify unpacked files.
*/
/* Regular file with 2 links. */
- r = lstat("file", &st);
- failure("Failed to stat file %s/file, errno=%d", from, errno);
- assertEqualInt(r, 0);
- if (r == 0) {
- assert(S_ISREG(st.st_mode));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualInt(0600, st.st_mode & 0700);
-#else
- assertEqualInt(0644, st.st_mode & 0777);
-#endif
- failure("file %s/file", from);
- assertEqualInt(10, st.st_size);
- failure("file %s/file", from);
- assertEqualInt(2, st.st_nlink);
- }
+ assertIsReg("file", 0644);
+ failure("%s", from);
+ assertFileSize("file", 10);
+ assertFileSize("linkfile", 10);
+ failure("%s", from);
+ assertFileNLinks("file", 2);
/* Another name for the same file. */
- r = lstat("linkfile", &st2);
- failure("Failed to stat file %s/linkfile, errno=%d", from, errno);
- assertEqualInt(r, 0);
- if (r == 0) {
- assert(S_ISREG(st2.st_mode));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualInt(0600, st2.st_mode & 0700);
-#else
- assertEqualInt(0644, st2.st_mode & 0777);
-#endif
- failure("file %s/file", from);
- assertEqualInt(10, st2.st_size);
- failure("file %s/file", from);
- assertEqualInt(2, st2.st_nlink);
- failure("file and linkfile should be hardlinked");
- assertEqualInt(st.st_dev, st2.st_dev);
- failure("file %s/file", from);
- assertEqualInt(st.st_ino, st2.st_ino);
- }
+ failure("%s", from);
+ assertIsHardlink("linkfile", "file");
+ assertFileSize("file", 10);
+ assertFileSize("linkfile", 10);
/* Symlink */
- r = lstat("symlink", &st);
- failure("Failed to stat file %s/symlink, errno=%d", from, errno);
- assertEqualInt(r, 0);
-#if !defined(_WIN32) || defined(__CYGWIN__)
- if (r == 0) {
- failure("symlink should be a symlink; actual mode is %o",
- st.st_mode);
- assert(S_ISLNK(st.st_mode));
- if (S_ISLNK(st.st_mode)) {
- r = readlink("symlink", buff, sizeof(buff));
- assertEqualInt(r, 4);
- buff[r] = '\0';
- assertEqualString(buff, "file");
- }
- }
-#endif
+ if (canSymlink())
+ assertIsSymlink("symlink", "file");
/* dir */
- r = lstat("dir", &st);
- if (r == 0) {
- assertEqualInt(r, 0);
- assert(S_ISDIR(st.st_mode));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualInt(0700, st.st_mode & 0700);
-#else
- assertEqualInt(0775, st.st_mode & 0777);
-#endif
- }
+ assertIsDir("dir", 0775);
- chdir("..");
+ assertChdir("..");
}
DEFINE_TEST(test_gcpio_compat)
{
- int oldumask;
-
- oldumask = umask(0);
+ assertUmask(0);
/* Dearchive sample files with a variety of options. */
- unpack_test("test_gcpio_compat_ref.bin", "", "1 block\n");
- unpack_test("test_gcpio_compat_ref.crc", "", "2 blocks\n");
- unpack_test("test_gcpio_compat_ref.newc", "", "2 blocks\n");
- /* gcpio-2.9 only reads 6 blocks here */
- unpack_test("test_gcpio_compat_ref.ustar", "", "7 blocks\n");
-
- umask(oldumask);
+ if (canSymlink()) {
+ unpack_test("test_gcpio_compat_ref.bin",
+ "--no-preserve-owner", "1 block\n");
+ unpack_test("test_gcpio_compat_ref.crc",
+ "--no-preserve-owner", "2 blocks\n");
+ unpack_test("test_gcpio_compat_ref.newc",
+ "--no-preserve-owner", "2 blocks\n");
+ /* gcpio-2.9 only reads 6 blocks here */
+ unpack_test("test_gcpio_compat_ref.ustar",
+ "--no-preserve-owner", "7 blocks\n");
+ } else {
+ unpack_test("test_gcpio_compat_ref_nosym.bin",
+ "--no-preserve-owner", "1 block\n");
+ unpack_test("test_gcpio_compat_ref_nosym.crc",
+ "--no-preserve-owner", "2 blocks\n");
+ unpack_test("test_gcpio_compat_ref_nosym.newc",
+ "--no-preserve-owner", "2 blocks\n");
+ /* gcpio-2.9 only reads 6 blocks here */
+ unpack_test("test_gcpio_compat_ref_nosym.ustar",
+ "--no-preserve-owner", "7 blocks\n");
+ }
}
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu
new file mode 100644
index 0000000..7a2a272
--- /dev/null
+++ b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu
@@ -0,0 +1,17 @@
+$FreeBSD$
+
+begin 644 test_gcpio_compat_ref_nosym.bin
+MQW%4`-[Z_4'H`^@#`@`VNZU*NQX$``````!D:7(`QW%4`-SZI('H`^@#`@`G
+MNZU*NQX%````"@!F:6QE```Q,C,T-38W.#D*QW%4`-SZI('H`^@#`@`GNZU*
+MNQX)````"@!L:6YK9FEL90``,3(S-#4V-S@Y"L=Q``````````````$`````
+M````"P``````5%)!24Q%4B$A(0``````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+1````````````````````````
+`
+end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu
new file mode 100644
index 0000000..0147df7
--- /dev/null
+++ b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu
@@ -0,0 +1,17 @@
+$FreeBSD$
+
+begin 644 test_gcpio_compat_ref_nosym.crc
+M,#<P-S`R,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13@P,#`P,#`P
+M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
+M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#(P,#4V1D%$0S`P,#`X
+M,4$T,#`P,#`S13@P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
+M,&9I;&4``#`W,#<P,C`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
+M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
+M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,44W;&EN:V9I;&4``#$R,S0U-C<X
+M.0H``#`W,#<P,C`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
+M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
+1````````````````````````
+`
+end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu
new file mode 100644
index 0000000..e2a4900
--- /dev/null
+++ b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu
@@ -0,0 +1,17 @@
+$FreeBSD$
+
+begin 644 test_gcpio_compat_ref_nosym.newc
+M,#<P-S`Q,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13@P,#`P,#`P
+M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
+M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#$P,#4V1D%$0S`P,#`X
+M,4$T,#`P,#`S13@P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
+M,&9I;&4``#`W,#<P,3`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
+M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
+M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,#`P;&EN:V9I;&4``#$R,S0U-C<X
+M.0H``#`W,#<P,3`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
+M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
+1````````````````````````
+`
+end
diff --git a/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu
new file mode 100644
index 0000000..b5cbd66
--- /dev/null
+++ b/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu
@@ -0,0 +1,74 @@
+$FreeBSD$
+
+begin 644 test_gcpio_compat_ref_nosym.ustar
+M9&ER+P``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````#`P,#`W-S4`,#`P,3<U,``P,#`Q-S4P`#`P,#`P,#`P,#`P
+M`#$Q,C4S,C$W,C<S`#`P,3$S-3$`-0``````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
+M````````````````````````````````````=&EM````````````````````
+M```````````````````P,#`P,C<S`#8V,#`P-C8`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````!F:6QE````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````,#`P,#8T-``P,#`Q-S4P`#`P
+M,#$W-3``,#`P,#`P,#`P,3(`,3$R-3,R,3<R-S,`,#`Q,30R,P`P````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````'5S=&%R`#`P=&EM``````````````````````````````````````!T
+M:6T``````````````````````````````````````#`P,#`R-S,`-C8P,#`T
+M-P``````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````#$R,S0U-C<X.0H`
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````;&EN:V9I;&4`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````#`P,#`V-#0`,#`P,3<U,``P,#`Q-S4P`#`P,#`P
+M,#`P,#`P`#$Q,C4S,C$W,C<S`#`P,3,Q,S<`,69I;&4`````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````!U<W1A<@`P
+M,'1I;0``````````````````````````````````````=&EM````````````
+M```````````````````````````P,#`P,C<S`#8V,#`P-#<`````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/usr.bin/cpio/test/test_option_B.c b/usr.bin/cpio/test/test_option_B_upper.c
index 8083882..b040354 100644
--- a/usr.bin/cpio/test/test_option_B.c
+++ b/usr.bin/cpio/test/test_option_B_upper.c
@@ -26,29 +26,27 @@
__FBSDID("$FreeBSD$");
-DEFINE_TEST(test_option_B)
+DEFINE_TEST(test_option_B_upper)
{
struct stat st;
- int r, fd;
+ int r;
/*
* Create a file on disk.
*/
- fd = open("file", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- close(fd);
+ assertMakeFile("file", 0644, NULL);
/* Create an archive without -B; this should be 512 bytes. */
r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
assertEqualInt(r, 0);
- assertFileContents("1 block\n", 8, "small.err");
+ assertTextFileContents("1 block\n", "small.err");
assertEqualInt(0, stat("small.cpio", &st));
assertEqualInt(512, st.st_size);
/* Create an archive with -B; this should be 5120 bytes. */
r = systemf("echo file | %s -oB > large.cpio 2>large.err", testprog);
assertEqualInt(r, 0);
- assertFileContents("1 block\n", 8, "large.err");
+ assertTextFileContents("1 block\n", "large.err");
assertEqualInt(0, stat("large.cpio", &st));
assertEqualInt(5120, st.st_size);
}
diff --git a/usr.bin/cpio/pathmatch.h b/usr.bin/cpio/test/test_option_C_upper.c
index 3e82830..c8e63fd 100644
--- a/usr.bin/cpio/pathmatch.h
+++ b/usr.bin/cpio/test/test_option_C_upper.c
@@ -6,8 +6,7 @@
* 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
- * in this position and unchanged.
+ * 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.
@@ -22,21 +21,42 @@
* 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 "test.h"
+__FBSDID("$FreeBSD$");
+
+
+DEFINE_TEST(test_option_C_upper)
+{
+ int r;
-#ifndef LAFE_PATHMATCH_H
-#define LAFE_PATHMATCH_H
+ /*
+ * Create a file on disk.
+ */
+ assertMakeFile("file", 0644, NULL);
-/* Don't anchor at beginning unless the pattern starts with "^" */
-#define PATHMATCH_NO_ANCHOR_START 1
-/* Don't anchor at end unless the pattern ends with "$" */
-#define PATHMATCH_NO_ANCHOR_END 2
+ /* Create an archive without -C; this should be 512 bytes. */
+ r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
+ assertEqualInt(r, 0);
+ assertTextFileContents("1 block\n", "small.err");
+ assertFileSize("small.cpio", 512);
-/* Note that "^" and "$" are not special unless you set the corresponding
- * flag above. */
+ /* Create an archive with -C 513; this should be 513 bytes. */
+ r = systemf("echo file | %s -o -C 513 > 513.cpio 2>513.err",
+ testprog);
+ assertEqualInt(r, 0);
+ assertTextFileContents("1 block\n", "513.err");
+ assertFileSize("513.cpio", 513);
-int pathmatch(const char *p, const char *s, int flags);
+ /* Create an archive with -C 12345; this should be 12345 bytes. */
+ r = systemf("echo file | %s -o -C12345 > 12345.cpio 2>12345.err",
+ testprog);
+ assertEqualInt(r, 0);
+ assertTextFileContents("1 block\n", "12345.err");
+ assertFileSize("12345.cpio", 12345);
-#endif
+ /* Create an archive with invalid -C request */
+ assert(0 != systemf("echo file | %s -o -C > bad.cpio 2>bad.err",
+ testprog));
+ assertEmptyFile("bad.cpio");
+}
diff --git a/usr.bin/cpio/err.h b/usr.bin/cpio/test/test_option_J_upper.c
index fe96c70..532aacf 100644
--- a/usr.bin/cpio/err.h
+++ b/usr.bin/cpio/test/test_option_J_upper.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Joerg Sonnenberger
+ * Copyright (c) 2003-2009 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -21,23 +21,36 @@
* 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 "test.h"
+__FBSDID("$FreeBSD$");
-#ifndef LAFE_ERR_H
-#define LAFE_ERR_H
-
-#if defined(__GNUC__) && (__GNUC__ > 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
-#define __LA_DEAD __attribute__((__noreturn__))
-#else
-#define __LA_DEAD
-#endif
-
-extern const char *progname;
+DEFINE_TEST(test_option_J_upper)
+{
+ char *p;
+ int r;
+ size_t s;
-void warnc(int code, const char *fmt, ...);
-void errc(int eval, int code, const char *fmt, ...) __LA_DEAD;
+ /* Create a file. */
+ assertMakeFile("f", 0644, "a");
-#endif
+ /* Archive it with xz compression. */
+ r = systemf("echo f | %s -o -J >archive.out 2>archive.err",
+ testprog);
+ p = slurpfile(&s, "archive.err");
+ p[s] = '\0';
+ if (r != 0) {
+ if (strstr(p, "compression not available") != NULL) {
+ skipping("This version of bsdcpio was compiled "
+ "without xz support");
+ return;
+ }
+ failure("-J option is broken");
+ assertEqualInt(r, 0);
+ return;
+ }
+ /* Check that the archive file has an xz signature. */
+ p = slurpfile(&s, "archive.out");
+ assert(s > 2);
+ assertEqualMem(p, "\3757zXZ", 5);
+}
diff --git a/usr.bin/cpio/test/test_option_L.c b/usr.bin/cpio/test/test_option_L_upper.c
index 79e2adb..0acc100 100644
--- a/usr.bin/cpio/test/test_option_L.c
+++ b/usr.bin/cpio/test/test_option_L_upper.c
@@ -25,60 +25,77 @@
#include "test.h"
__FBSDID("$FreeBSD$");
-DEFINE_TEST(test_option_L)
+/* This is a little pointless, as Windows doesn't support symlinks
+ * (except for the seriously crippled CreateSymbolicLink API) so these
+ * tests won't run on Windows. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define CAT "type"
+#else
+#define CAT "cat"
+#endif
+
+DEFINE_TEST(test_option_L_upper)
{
- struct stat st;
- int fd, filelist;
+ FILE *filelist;
int r;
- filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
+ if (!canSymlink()) {
+ skipping("Symlink tests");
+ return;
+ }
+
+ filelist = fopen("filelist", "w");
/* Create a file and a symlink to the file. */
- fd = open("file", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(10, write(fd, "123456789", 10));
- close(fd);
- write(filelist, "file\n", 5);
+ assertMakeFile("file", 0644, "1234567890");
+ fprintf(filelist, "file\n");
/* Symlink to above file. */
- assertEqualInt(0, symlink("file", "symlink"));
- write(filelist, "symlink\n", 8);
+ assertMakeSymlink("symlink", "file");
+ fprintf(filelist, "symlink\n");
- close(filelist);
+ fclose(filelist);
- r = systemf("cat filelist | %s -pd copy >copy.out 2>copy.err", testprog);
+ r = systemf(CAT " filelist | %s -pd copy >copy.out 2>copy.err", testprog);
assertEqualInt(r, 0);
- assertEqualInt(0, lstat("copy/symlink", &st));
+ assertTextFileContents("1 block\n", "copy.err");
+
failure("Regular -p without -L should preserve symlinks.");
- assert(S_ISLNK(st.st_mode));
+ assertIsSymlink("copy/symlink", NULL);
- r = systemf("cat filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
+ r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
assertEqualInt(r, 0);
assertEmptyFile("copy-L.out");
- assertFileContents("1 block\n", 8, "copy-L.err");
- assertEqualInt(0, lstat("copy-L/symlink", &st));
+ assertTextFileContents("1 block\n", "copy-L.err");
failure("-pdL should dereference symlinks and turn them into files.");
- assert(!S_ISLNK(st.st_mode));
+ assertIsReg("copy-L/symlink", -1);
- r = systemf("cat filelist | %s -o >archive.out 2>archive.err", testprog);
+ r = systemf(CAT " filelist | %s -o >archive.out 2>archive.err", testprog);
failure("Error invoking %s -o ", testprog);
assertEqualInt(r, 0);
+ assertTextFileContents("1 block\n", "archive.err");
- assertEqualInt(0, mkdir("unpack", 0755));
- r = systemf("cat archive.out | (cd unpack ; %s -i >unpack.out 2>unpack.err)", testprog);
+ assertMakeDir("unpack", 0755);
+ assertChdir("unpack");
+ r = systemf(CAT " ../archive.out | %s -i >unpack.out 2>unpack.err", testprog);
failure("Error invoking %s -i", testprog);
assertEqualInt(r, 0);
- assertEqualInt(0, lstat("unpack/symlink", &st));
- assert(S_ISLNK(st.st_mode));
+ assertTextFileContents("1 block\n", "unpack.err");
+ assertChdir("..");
+
+ assertIsSymlink("unpack/symlink", NULL);
- r = systemf("cat filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
+ r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
failure("Error invoking %s -oL", testprog);
assertEqualInt(r, 0);
+ assertTextFileContents("1 block\n", "archive-L.err");
- assertEqualInt(0, mkdir("unpack-L", 0755));
- r = systemf("cat archive-L.out | (cd unpack-L ; %s -i >unpack-L.out 2>unpack-L.err)", testprog);
+ assertMakeDir("unpack-L", 0755);
+ assertChdir("unpack-L");
+ r = systemf(CAT " ../archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
failure("Error invoking %s -i < archive-L.out", testprog);
assertEqualInt(r, 0);
- assertEqualInt(0, lstat("unpack-L/symlink", &st));
- assert(!S_ISLNK(st.st_mode));
+ assertTextFileContents("1 block\n", "unpack-L.err");
+ assertChdir("..");
+ assertIsReg("unpack-L/symlink", -1);
}
diff --git a/usr.bin/cpio/line_reader.h b/usr.bin/cpio/test/test_option_Z_upper.c
index 4f5dd6a..936ce0c 100644
--- a/usr.bin/cpio/line_reader.h
+++ b/usr.bin/cpio/test/test_option_Z_upper.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Joerg Sonnenberger
+ * Copyright (c) 2003-2009 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -21,17 +21,36 @@
* 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 "test.h"
+__FBSDID("$FreeBSD$");
-#ifndef LAFE_LINE_READER_H
-#define LAFE_LINE_READER_H
-
-struct line_reader;
+DEFINE_TEST(test_option_Z_upper)
+{
+ char *p;
+ int r;
+ size_t s;
-struct line_reader *line_reader(const char *, int nullSeparator);
-const char *line_reader_next(struct line_reader *);
-void line_reader_free(struct line_reader *);
+ /* Create a file. */
+ assertMakeFile("f", 0644, "a");
-#endif
+ /* Archive it with compress compression. */
+ r = systemf("echo f | %s -oZ >archive.out 2>archive.err",
+ testprog);
+ p = slurpfile(&s, "archive.err");
+ p[s] = '\0';
+ if (r != 0) {
+ if (strstr(p, "compression not available") != NULL) {
+ skipping("This version of bsdcpio was compiled "
+ "without compress support");
+ return;
+ }
+ failure("-Z option is broken");
+ assertEqualInt(r, 0);
+ return;
+ }
+ /* Check that the archive file has a compress signature. */
+ p = slurpfile(&s, "archive.out");
+ assert(s > 2);
+ assertEqualMem(p, "\x1f\x9d", 2);
+}
diff --git a/usr.bin/cpio/test/test_option_a.c b/usr.bin/cpio/test/test_option_a.c
index e769836..af4b48e 100644
--- a/usr.bin/cpio/test/test_option_a.c
+++ b/usr.bin/cpio/test/test_option_a.c
@@ -23,10 +23,10 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <sys/utime.h>
-#else
+#if defined(HAVE_UTIME_H)
#include <utime.h>
+#elif defined(HAVE_SYS_UTIME_H)
+#include <sys/utime.h>
#endif
__FBSDID("$FreeBSD$");
@@ -57,19 +57,15 @@ test_create(void)
struct utimbuf times;
static const int numfiles = sizeof(files) / sizeof(files[0]);
int i;
- int fd;
for (i = 0; i < numfiles; ++i) {
- fd = open(files[i].name, O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
/*
* Note: Have to write at least one byte to the file.
* cpio doesn't bother reading the file if it's zero length,
* so the atime never gets changed in that case, which
* makes the tests below rather pointless.
*/
- assertEqualInt(1, write(fd, "a", 1));
- close(fd);
+ assertMakeFile(files[i].name, 0644, "a");
/* If utime() isn't supported on your platform, just
* #ifdef this section out. Most of the test below is
@@ -87,26 +83,21 @@ test_create(void)
}
/* Wait until the atime on the last file is actually in the past. */
- /* If utime() is supported above, there's no sleep here which
- * makes the test faster. */
- while (files[numfiles - 1].atime_sec >= time(NULL))
- sleep(1);
+ sleepUntilAfter(files[numfiles - 1].atime_sec);
}
DEFINE_TEST(test_option_a)
{
struct stat st;
int r;
- int f;
- char buff[64];
+ char *p;
/* Create all of the test files. */
test_create();
/* Sanity check; verify that atimes really do get modified. */
- f = open(files[0].name, O_RDONLY);
- assertEqualInt(1, read(f,buff, 1));
- assertEqualInt(0, close(f));
+ assert((p = slurpfile(NULL, "f0")) != NULL);
+ free(p);
assertEqualInt(0, stat("f0", &st));
if (st.st_atime == files[0].atime_sec) {
skipping("Cannot verify -a option\n"
diff --git a/usr.bin/cpio/test/test_option_c.c b/usr.bin/cpio/test/test_option_c.c
index 2f4e3bc..241bcf6 100644
--- a/usr.bin/cpio/test/test_option_c.c
+++ b/usr.bin/cpio/test/test_option_c.c
@@ -53,41 +53,44 @@ from_octal(const char *p, size_t l)
DEFINE_TEST(test_option_c)
{
- int fd, filelist;
+ FILE *filelist;
int r;
+ int uid = -1;
int dev, ino, gid;
time_t t, now;
char *p, *e;
size_t s;
- mode_t oldmask;
- oldmask = umask(0);
+ assertUmask(0);
+
+#if !defined(_WIN32)
+ uid = getuid();
+#endif
/*
* Create an assortment of files.
* TODO: Extend this to cover more filetypes.
*/
- filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
+ filelist = fopen("filelist", "w");
/* "file" */
- fd = open("file", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(10, write(fd, "123456789", 10));
- close(fd);
- assertEqualInt(5, write(filelist, "file\n", 5));
+ assertMakeFile("file", 0644, "1234567890");
+ fprintf(filelist, "file\n");
/* "symlink" */
- assertEqualInt(0, symlink("file", "symlink"));
- assertEqualInt(8, write(filelist, "symlink\n", 8));
+ if (canSymlink()) {
+ assertMakeSymlink("symlink", "file");
+ fprintf(filelist, "symlink\n");
+ }
/* "dir" */
- assertEqualInt(0, mkdir("dir", 0775));
+ assertMakeDir("dir", 0775);
/* Record some facts about what we just created: */
now = time(NULL); /* They were all created w/in last two seconds. */
- assertEqualInt(4, write(filelist, "dir\n", 4));
+ fprintf(filelist, "dir\n");
/* Use the cpio program to create an archive. */
- close(filelist);
+ fclose(filelist);
r = systemf("%s -oc <filelist >basic.out 2>basic.err", testprog);
/* Verify that nothing went to stderr. */
assertTextFileContents("1 block\n", "basic.err");
@@ -115,12 +118,14 @@ DEFINE_TEST(test_option_c)
assert(is_octal(e + 12, 6)); /* ino */
ino = from_octal(e + 12, 6);
#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
+ /* Group members bits and others bits do not work. */
assertEqualMem(e + 18, "100666", 6); /* Mode */
#else
assertEqualMem(e + 18, "100644", 6); /* Mode */
#endif
- assertEqualInt(from_octal(e + 24, 6), getuid()); /* uid */
+ if (uid < 0)
+ uid = from_octal(e + 24, 6);
+ assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
assert(is_octal(e + 30, 6)); /* gid */
gid = from_octal(e + 30, 6);
assertEqualMem(e + 36, "000001", 6); /* nlink */
@@ -133,46 +138,37 @@ DEFINE_TEST(test_option_c)
assertEqualMem(e + 59, "000005", 6); /* Name size */
assertEqualMem(e + 65, "00000000012", 11); /* File size */
assertEqualMem(e + 76, "file\0", 5); /* Name contents */
- assertEqualMem(e + 81, "123456789\0", 10); /* File contents */
+ assertEqualMem(e + 81, "1234567890", 10); /* File contents */
e += 91;
- /* Second entry is "symlink" pointing to "file" */
- assert(is_octal(e, 76)); /* Entire header is octal digits. */
- assertEqualMem(e + 0, "070707", 6); /* Magic */
- assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */
- assert(dev != from_octal(e + 12, 6)); /* ino */
+ /* "symlink" pointing to "file" */
+ if (canSymlink()) {
+ assert(is_octal(e, 76)); /* Entire header is octal digits. */
+ assertEqualMem(e + 0, "070707", 6); /* Magic */
+ assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */
+ assert(ino != from_octal(e + 12, 6)); /* ino */
#if !defined(_WIN32) || defined(__CYGWIN__)
- /* On Windows, symbolic link and group members bits and
- * others bits do not work. */
- assertEqualMem(e + 18, "120777", 6); /* Mode */
-#endif
- assertEqualInt(from_octal(e + 24, 6), getuid()); /* uid */
- assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
- assertEqualMem(e + 36, "000001", 6); /* nlink */
- failure("file entries should have rdev == 0 (dev was 0%o)",
- from_octal(e + 6, 6));
- assertEqualMem(e + 42, "000000", 6); /* rdev */
- t = from_octal(e + 48, 11); /* mtime */
- assert(t <= now); /* File wasn't created in future. */
- assert(t >= now - 2); /* File was created w/in last 2 secs. */
- assertEqualMem(e + 59, "000010", 6); /* Name size */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* On Windows, symbolic link does not work. */
- assertEqualMem(e + 65, "00000000012", 11); /* File size */
-#else
- assertEqualMem(e + 65, "00000000004", 11); /* File size */
-#endif
- assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* On Windows, symbolic link does not work. */
- assertEqualMem(e + 84, "123456789\0", 10); /* File contents. */
- e += 94;
-#else
- assertEqualMem(e + 84, "file", 4); /* Symlink target. */
- e += 88;
+ /* On Windows, symbolic link and group members bits and
+ * others bits do not work. */
+ assertEqualMem(e + 18, "120777", 6); /* Mode */
#endif
+ assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
+ assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
+ assertEqualMem(e + 36, "000001", 6); /* nlink */
+ failure("file entries should have rdev == 0 (dev was 0%o)",
+ from_octal(e + 6, 6));
+ assertEqualMem(e + 42, "000000", 6); /* rdev */
+ t = from_octal(e + 48, 11); /* mtime */
+ assert(t <= now); /* File wasn't created in future. */
+ assert(t >= now - 2); /* File was created w/in last 2 secs. */
+ assertEqualMem(e + 59, "000010", 6); /* Name size */
+ assertEqualMem(e + 65, "00000000004", 11); /* File size */
+ assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */
+ assertEqualMem(e + 84, "file", 4); /* Symlink target. */
+ e += 88;
+ }
- /* Second entry is "dir" */
+ /* "dir" */
assert(is_octal(e, 76));
assertEqualMem(e + 0, "070707", 6); /* Magic */
/* Dev should be same as first entry. */
@@ -182,12 +178,14 @@ DEFINE_TEST(test_option_c)
assert(is_octal(e + 12, 6)); /* ino */
assert(dev != from_octal(e + 12, 6));
#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Group members bits and others bits do not work. */
+ /* Group members bits and others bits do not work. */
assertEqualMem(e + 18, "040777", 6); /* Mode */
#else
- assertEqualMem(e + 18, "040775", 6); /* Mode */
+ /* Accept 042775 to accomodate systems where sgid bit propagates. */
+ if (memcmp(e + 18, "042775", 6) != 0)
+ assertEqualMem(e + 18, "040775", 6); /* Mode */
#endif
- assertEqualInt(from_octal(e + 24, 6), getuid()); /* uid */
+ assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
/* Gid should be same as first entry. */
assert(is_octal(e + 30, 6)); /* gid */
assertEqualInt(gid, from_octal(e + 30, 6));
@@ -220,6 +218,4 @@ DEFINE_TEST(test_option_c)
assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */
free(p);
-
- umask(oldmask);
}
diff --git a/usr.bin/cpio/test/test_option_d.c b/usr.bin/cpio/test/test_option_d.c
index cb422ae..9ff1453 100644
--- a/usr.bin/cpio/test/test_option_d.c
+++ b/usr.bin/cpio/test/test_option_d.c
@@ -28,41 +28,37 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_option_d)
{
- struct stat st;
- int r, fd;
+ int r;
/*
* Create a file in a directory.
*/
- assertEqualInt(0, mkdir("dir", 0755));
- fd = open("dir/file", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- close(fd);
+ assertMakeDir("dir", 0755);
+ assertMakeFile("dir/file", 0644, NULL);
/* Create an archive. */
r = systemf("echo dir/file | %s -o > archive.cpio 2>archive.err", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "archive.err");
- assertEqualInt(0, stat("archive.cpio", &st));
- assertEqualInt(512, st.st_size);
+ assertFileSize("archive.cpio", 512);
/* Dearchive without -d, this should fail. */
- assertEqualInt(0, mkdir("without-d", 0755));
- assertEqualInt(0, chdir("without-d"));
+ assertMakeDir("without-d", 0755);
+ assertChdir("without-d");
r = systemf("%s -i < ../archive.cpio >out 2>err", testprog);
assertEqualInt(r, 0);
assertEmptyFile("out");
/* And the file should not be restored. */
- assert(0 != stat("dir/file", &st));
+ assertFileNotExists("dir/file");
/* Dearchive with -d, this should succeed. */
- assertEqualInt(0, chdir(".."));
- assertEqualInt(0, mkdir("with-d", 0755));
- assertEqualInt(0, chdir("with-d"));
+ assertChdir("..");
+ assertMakeDir("with-d", 0755);
+ assertChdir("with-d");
r = systemf("%s -id < ../archive.cpio >out 2>err", testprog);
assertEqualInt(r, 0);
assertEmptyFile("out");
assertTextFileContents("1 block\n", "err");
/* And the file should be restored. */
- assertEqualInt(0, stat("dir/file", &st));
+ assertFileExists("dir/file");
}
diff --git a/usr.bin/cpio/test/test_option_f.c b/usr.bin/cpio/test/test_option_f.c
index 54e07ac..784e085 100644
--- a/usr.bin/cpio/test/test_option_f.c
+++ b/usr.bin/cpio/test/test_option_f.c
@@ -33,44 +33,44 @@ unpack(const char *dirname, const char *option)
{
int r;
- assertEqualInt(0, mkdir(dirname, 0755));
- assertEqualInt(0, chdir(dirname));
+ assertMakeDir(dirname, 0755);
+ assertChdir(dirname);
extract_reference_file("test_option_f.cpio");
r = systemf("%s -i %s < test_option_f.cpio > copy-no-a.out 2>copy-no-a.err", testprog, option);
assertEqualInt(0, r);
- assertEqualInt(0, chdir(".."));
+ assertChdir("..");
}
DEFINE_TEST(test_option_f)
{
/* Calibrate: No -f option, so everything should be extracted. */
- unpack("t0", "");
- assertEqualInt(0, access("t0/a123", F_OK));
- assertEqualInt(0, access("t0/a234", F_OK));
- assertEqualInt(0, access("t0/b123", F_OK));
- assertEqualInt(0, access("t0/b234", F_OK));
+ unpack("t0", "--no-preserve-owner");
+ assertFileExists("t0/a123");
+ assertFileExists("t0/a234");
+ assertFileExists("t0/b123");
+ assertFileExists("t0/b234");
/* Don't extract 'a*' files. */
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Single quotes isn't used by command.exe. */
- unpack("t1", "-f a*");
+ unpack("t1", "--no-preserve-owner -f a*");
#else
- unpack("t1", "-f 'a*'");
+ unpack("t1", "--no-preserve-owner -f 'a*'");
#endif
- assert(0 != access("t1/a123", F_OK));
- assert(0 != access("t1/a234", F_OK));
- assertEqualInt(0, access("t1/b123", F_OK));
- assertEqualInt(0, access("t1/b234", F_OK));
+ assertFileNotExists("t1/a123");
+ assertFileNotExists("t1/a234");
+ assertFileExists("t1/b123");
+ assertFileExists("t1/b234");
/* Don't extract 'b*' files. */
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Single quotes isn't used by command.exe. */
- unpack("t2", "-f b*");
+ unpack("t2", "--no-preserve-owner -f b*");
#else
- unpack("t2", "-f 'b*'");
+ unpack("t2", "--no-preserve-owner -f 'b*'");
#endif
- assertEqualInt(0, access("t2/a123", F_OK));
- assertEqualInt(0, access("t2/a234", F_OK));
- assert(0 != access("t2/b123", F_OK));
- assert(0 != access("t2/b234", F_OK));
+ assertFileExists("t2/a123");
+ assertFileExists("t2/a234");
+ assertFileNotExists("t2/b123");
+ assertFileNotExists("t2/b234");
}
diff --git a/usr.bin/cpio/test/test_option_help.c b/usr.bin/cpio/test/test_option_help.c
index b9433a4..5623430 100644
--- a/usr.bin/cpio/test/test_option_help.c
+++ b/usr.bin/cpio/test/test_option_help.c
@@ -51,6 +51,7 @@ DEFINE_TEST(test_option_help)
/* Exercise --help option. */
r = systemf("%s --help >help.stdout 2>help.stderr", testprog);
+ assertEqualInt(r, 0);
failure("--help should generate nothing to stderr.");
assertEmptyFile("help.stderr");
/* Help message should start with name of program. */
@@ -67,6 +68,7 @@ DEFINE_TEST(test_option_help)
/* -h option should generate the same output. */
r = systemf("%s -h >h.stdout 2>h.stderr", testprog);
+ assertEqualInt(r, 0);
failure("-h should generate nothing to stderr.");
assertEmptyFile("h.stderr");
failure("stdout should be same for -h and --help");
@@ -74,6 +76,7 @@ DEFINE_TEST(test_option_help)
/* -W help should be another synonym. */
r = systemf("%s -W help >Whelp.stdout 2>Whelp.stderr", testprog);
+ assertEqualInt(r, 0);
failure("-W help should generate nothing to stderr.");
assertEmptyFile("Whelp.stderr");
failure("stdout should be same for -W help and --help");
diff --git a/usr.bin/cpio/test/test_option_ell.c b/usr.bin/cpio/test/test_option_l.c
index 36bb0ac..5c76e68 100644
--- a/usr.bin/cpio/test/test_option_ell.c
+++ b/usr.bin/cpio/test/test_option_l.c
@@ -25,26 +25,12 @@
#include "test.h"
__FBSDID("$FreeBSD$");
-/*
- * This is called "test_option_ell" instead of "test_option_l" to
- * avoid any conflicts with "test_option_L" on case-insensitive
- * filesystems.
- */
-
-DEFINE_TEST(test_option_ell)
+DEFINE_TEST(test_option_l)
{
- struct stat st, st2;
- int fd;
int r;
/* Create a file. */
- fd = open("f", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(1, write(fd, "a", 1));
- close(fd);
-
- /* Stat it. */
- assertEqualInt(0, stat("f", &st));
+ assertMakeFile("f", 0644, "a");
/* Copy the file to the "copy" dir. */
r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
@@ -52,8 +38,7 @@ DEFINE_TEST(test_option_ell)
assertEqualInt(r, 0);
/* Check that the copy is a true copy and not a link. */
- assertEqualInt(0, stat("copy/f", &st2));
- assert(st2.st_ino != st.st_ino);
+ assertIsNotHardlink("f", "copy/f");
/* Copy the file to the "link" dir with the -l option. */
r = systemf("echo f | %s -pld link >link.out 2>link.err",
@@ -61,6 +46,5 @@ DEFINE_TEST(test_option_ell)
assertEqualInt(r, 0);
/* Check that this is a link and not a copy. */
- assertEqualInt(0, stat("link/f", &st2));
- assert(st2.st_ino == st.st_ino);
+ assertIsHardlink("f", "link/f");
}
diff --git a/usr.bin/cpio/err.c b/usr.bin/cpio/test/test_option_lzma.c
index c74e097..c6e3353 100644
--- a/usr.bin/cpio/err.c
+++ b/usr.bin/cpio/test/test_option_lzma.c
@@ -6,8 +6,7 @@
* 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
- * in this position and unchanged.
+ * 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.
@@ -23,52 +22,35 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-#include "cpio_platform.h"
+#include "test.h"
__FBSDID("$FreeBSD$");
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "err.h"
-
-const char *progname;
-
-static void
-vwarnc(int code, const char *fmt, va_list ap)
-{
- fprintf(stderr, "%s: ", progname);
- vfprintf(stderr, fmt, ap);
- if (code != 0)
- fprintf(stderr, ": %s", strerror(code));
- fprintf(stderr, "\n");
-}
-
-void
-warnc(int code, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vwarnc(code, fmt, ap);
- va_end(ap);
-}
-
-void
-errc(int eval, int code, const char *fmt, ...)
+DEFINE_TEST(test_option_lzma)
{
- va_list ap;
-
- va_start(ap, fmt);
- vwarnc(code, fmt, ap);
- va_end(ap);
- exit(eval);
+ char *p;
+ int r;
+ size_t s;
+
+ /* Create a file. */
+ assertMakeFile("f", 0644, "a");
+
+ /* Archive it with lzma compression. */
+ r = systemf("echo f | %s -o --lzma >archive.out 2>archive.err",
+ testprog);
+ p = slurpfile(&s, "archive.err");
+ p[s] = '\0';
+ if (r != 0) {
+ if (strstr(p, "compression not available") != NULL) {
+ skipping("This version of bsdcpio was compiled "
+ "without lzma support");
+ return;
+ }
+ failure("--lzma option is broken");
+ assertEqualInt(r, 0);
+ return;
+ }
+ /* Check that the archive file has an lzma signature. */
+ p = slurpfile(&s, "archive.out");
+ assert(s > 2);
+ assertEqualMem(p, "\x5d\00\00", 3);
}
diff --git a/usr.bin/cpio/test/test_option_m.c b/usr.bin/cpio/test/test_option_m.c
index 7f8e901..de880b2 100644
--- a/usr.bin/cpio/test/test_option_m.c
+++ b/usr.bin/cpio/test/test_option_m.c
@@ -28,9 +28,7 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_option_m)
{
- struct stat st;
int r;
- time_t now;
/*
* The reference archive has one file with an mtime in 1970, 1
@@ -38,33 +36,28 @@ DEFINE_TEST(test_option_m)
*/
/* Restored without -m, the result should have a current mtime. */
- assertEqualInt(0, mkdir("without-m", 0755));
- assertEqualInt(0, chdir("without-m"));
+ assertMakeDir("without-m", 0755);
+ assertChdir("without-m");
extract_reference_file("test_option_m.cpio");
- r = systemf("%s -i < test_option_m.cpio >out 2>err", testprog);
- now = time(NULL);
+ r = systemf("%s --no-preserve-owner -i < test_option_m.cpio >out 2>err", testprog);
assertEqualInt(r, 0);
assertEmptyFile("out");
assertTextFileContents("1 block\n", "err");
- assertEqualInt(0, stat("file", &st));
/* Should have been created within the last few seconds. */
- assert(st.st_mtime <= now);
- assert(st.st_mtime > now - 5);
+ assertFileMtimeRecent("file");
/* With -m, it should have an mtime in 1970. */
- assertEqualInt(0, chdir(".."));
- assertEqualInt(0, mkdir("with-m", 0755));
- assertEqualInt(0, chdir("with-m"));
+ assertChdir("..");
+ assertMakeDir("with-m", 0755);
+ assertChdir("with-m");
extract_reference_file("test_option_m.cpio");
- r = systemf("%s -im < test_option_m.cpio >out 2>err", testprog);
- now = time(NULL);
+ r = systemf("%s --no-preserve-owner -im < test_option_m.cpio >out 2>err", testprog);
assertEqualInt(r, 0);
assertEmptyFile("out");
assertTextFileContents("1 block\n", "err");
- assertEqualInt(0, stat("file", &st));
/*
* mtime in reference archive is '1' == 1 second after
* midnight Jan 1, 1970 UTC.
*/
- assertEqualInt(1, st.st_mtime);
+ assertFileMtime("file", 1, 0);
}
diff --git a/usr.bin/cpio/test/test_option_t.c b/usr.bin/cpio/test/test_option_t.c
index 1c9af19..4427bb3 100644
--- a/usr.bin/cpio/test/test_option_t.c
+++ b/usr.bin/cpio/test/test_option_t.c
@@ -71,12 +71,22 @@ DEFINE_TEST(test_option_t)
testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "itnv.err");
- extract_reference_file("test_option_tnv.stdout");
- /* This does work because numeric IDs come from archive. */
- /* Unfortunately, the timestamp still gets localized, so
- * we can't just compare against a fixed result. */
- /* TODO: Fix this. */
- /* assertEqualFile("itnv.out", "test_option_tnv.stdout"); */
+ p = slurpfile(NULL, "itnv.out");
+ /* Since -n uses numeric UID/GID, this part should be the
+ * same on every system. */
+ assertEqualMem(p, "-rw-r--r-- 1 1000 1000 0 ",42);
+ /* Date varies depending on local timezone. */
+ if (memcmp(p + 42, "Dec 31 1969", 12) == 0) {
+ /* East of Greenwich we get Dec 31, 1969. */
+ } else {
+ /* West of Greenwich get Jan 1, 1970 */
+ assertEqualMem(p + 42, "Jan ", 4);
+ /* Some systems format "Jan 01", some "Jan 1" */
+ assert(p[46] == ' ' || p[46] == '0');
+ assertEqualMem(p + 47, "1 1970 ", 8);
+ }
+ assertEqualMem(p + 54, " file", 5);
+ free(p);
/* But "-n" without "-t" is an error. */
assert(0 != systemf("%s -in < test_option_t.cpio >in.out 2>in.err",
diff --git a/usr.bin/cpio/test/test_option_u.c b/usr.bin/cpio/test/test_option_u.c
index 7d2edff..08058aa 100644
--- a/usr.bin/cpio/test/test_option_u.c
+++ b/usr.bin/cpio/test/test_option_u.c
@@ -23,10 +23,10 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <sys/utime.h>
-#else
+#if defined(HAVE_UTIME_H)
#include <utime.h>
+#elif defined(HAVE_SYS_UTIME_H)
+#include <sys/utime.h>
#endif
__FBSDID("$FreeBSD$");
@@ -35,14 +35,10 @@ DEFINE_TEST(test_option_u)
struct utimbuf times;
char *p;
size_t s;
- int fd;
int r;
/* Create a file. */
- fd = open("f", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(1, write(fd, "a", 1));
- close(fd);
+ assertMakeFile("f", 0644, "a");
/* Copy the file to the "copy" dir. */
r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
@@ -55,10 +51,7 @@ DEFINE_TEST(test_option_u)
assertEqualMem(p, "a", 1);
/* Recreate the file with a single "b" */
- fd = open("f", O_CREAT | O_TRUNC | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(1, write(fd, "b", 1));
- close(fd);
+ assertMakeFile("f", 0644, "b");
/* Set the mtime to the distant past. */
memset(&times, 0, sizeof(times));
diff --git a/usr.bin/cpio/test/test_option_version.c b/usr.bin/cpio/test/test_option_version.c
index 8a25248..7345da1 100644
--- a/usr.bin/cpio/test/test_option_version.c
+++ b/usr.bin/cpio/test/test_option_version.c
@@ -74,14 +74,14 @@ verify(const char *p, size_t s)
/* Skip a single trailing a,b,c, or d. */
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
++q;
- /* All terminated by a newline. */
+ /* All terminated by end-of-line: \r, \r\n, or \n */
assert(s >= 1);
failure("Version: %s", p);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualMem(q, "\r\n", 2);
-#else
- assertEqualMem(q, "\n", 1);
-#endif
+ if (*q == '\x0d') {
+ if (q[1] != '\0')
+ assertEqualMem(q, "\x0d\x0a", 2);
+ } else
+ assertEqualMem(q, "\x0a", 1);
}
diff --git a/usr.bin/cpio/test/test_option_y.c b/usr.bin/cpio/test/test_option_y.c
index 5cefaed..8e81ee7 100644
--- a/usr.bin/cpio/test/test_option_y.c
+++ b/usr.bin/cpio/test/test_option_y.c
@@ -28,32 +28,30 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_option_y)
{
char *p;
- int fd;
int r;
size_t s;
/* Create a file. */
- fd = open("f", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(1, write(fd, "a", 1));
- close(fd);
+ assertMakeFile("f", 0644, "a");
/* Archive it with bzip2 compression. */
r = systemf("echo f | %s -oy >archive.out 2>archive.err",
testprog);
- failure("-y (bzip) option seems to be broken");
- if (assertEqualInt(r, 0)) {
- p = slurpfile(&s, "archive.err");
- p[s] = '\0';
- if (strstr(p, "bzip2 compression not supported") != NULL) {
+ p = slurpfile(&s, "archive.err");
+ p[s] = '\0';
+ if (r != 0) {
+ if (strstr(p, "compression not available") != NULL) {
skipping("This version of bsdcpio was compiled "
"without bzip2 support");
- } else {
- assertTextFileContents("1 block\n", "archive.err");
- /* Check that the archive file has a bzip2 signature. */
- p = slurpfile(&s, "archive.out");
- assert(s > 2);
- assertEqualMem(p, "BZh9", 4);
+ return;
}
+ failure("-y option is broken");
+ assertEqualInt(r, 0);
+ return;
}
+ assertTextFileContents("1 block\n", "archive.err");
+ /* Check that the archive file has a bzip2 signature. */
+ p = slurpfile(&s, "archive.out");
+ assert(s > 2);
+ assertEqualMem(p, "BZh9", 4);
}
diff --git a/usr.bin/cpio/test/test_option_z.c b/usr.bin/cpio/test/test_option_z.c
index 2057912..91d37ac 100644
--- a/usr.bin/cpio/test/test_option_z.c
+++ b/usr.bin/cpio/test/test_option_z.c
@@ -28,32 +28,29 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_option_z)
{
char *p;
- int fd;
int r;
size_t s;
/* Create a file. */
- fd = open("f", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(1, write(fd, "a", 1));
- close(fd);
+ assertMakeFile("f", 0644, "a");
/* Archive it with gzip compression. */
r = systemf("echo f | %s -oz >archive.out 2>archive.err",
testprog);
- failure("-z option seems to be broken");
- assertEqualInt(r, 0);
- if (r == 0) {
- p = slurpfile(&s, "archive.err");
- p[s] = '\0';
- if (strstr(p, "gzip compression not supported") != NULL) {
+ p = slurpfile(&s, "archive.err");
+ p[s] = '\0';
+ if (r != 0) {
+ if (strstr(p, "compression not available") != NULL) {
skipping("This version of bsdcpio was compiled "
"without gzip support");
- } else {
- /* Check that the archive file has a gzip signature. */
- p = slurpfile(&s, "archive.out");
- assert(s > 2);
- assertEqualMem(p, "\x1f\x8b\x08\x00", 4);
+ return;
}
+ failure("-z option is broken");
+ assertEqualInt(r, 0);
+ return;
}
+ /* Check that the archive file has a gzip signature. */
+ p = slurpfile(&s, "archive.out");
+ assert(s > 4);
+ assertEqualMem(p, "\x1f\x8b\x08\x00", 4);
}
diff --git a/usr.bin/cpio/test/test_owner_parse.c b/usr.bin/cpio/test/test_owner_parse.c
index 06fabd9..d07724e 100644
--- a/usr.bin/cpio/test/test_owner_parse.c
+++ b/usr.bin/cpio/test/test_owner_parse.c
@@ -28,7 +28,12 @@ __FBSDID("$FreeBSD$");
#include "../cpio.h"
#include "err.h"
-#if defined(__CYGWIN__)
+#if !defined(_WIN32)
+#define ROOT "root"
+static int root_uids[] = { 0 };
+/* Solaris 9 root has gid 1 (other) */
+static int root_gids[] = { 0, 1 };
+#elif defined(__CYGWIN__)
/* On cygwin, the Administrator user most likely exists (unless
* it has been renamed or is in a non-English localization), but
* its primary group membership depends on how the user set up
@@ -40,12 +45,9 @@ __FBSDID("$FreeBSD$");
#define ROOT "Administrator"
static int root_uids[] = { 500 };
static int root_gids[] = { 513, 545, 544 };
-#else
-#define ROOT "root"
-static int root_uids[] = { 0 };
-static int root_gids[] = { 0 };
#endif
+#if defined(ROOT)
static int
int_in_list(int i, int *l, size_t n)
{
@@ -55,54 +57,54 @@ int_in_list(int i, int *l, size_t n)
failure("%d", i);
return (0);
}
+#endif
DEFINE_TEST(test_owner_parse)
{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* TODO: Does this need cygwin style handling of uid/gid ? */
- skipping("Windows cannot handle uid/gid as UNIX like system");
+#if !defined(ROOT)
+ skipping("No uid/gid configuration for this OS");
#else
int uid, gid;
- assertEqualInt(0, owner_parse(ROOT, &uid, &gid));
+ assert(NULL == owner_parse(ROOT, &uid, &gid));
assert(int_in_list(uid, root_uids,
sizeof(root_uids)/sizeof(root_uids[0])));
assertEqualInt(-1, gid);
- assertEqualInt(0, owner_parse(ROOT ":", &uid, &gid));
+ assert(NULL == owner_parse(ROOT ":", &uid, &gid));
assert(int_in_list(uid, root_uids,
sizeof(root_uids)/sizeof(root_uids[0])));
assert(int_in_list(gid, root_gids,
sizeof(root_gids)/sizeof(root_gids[0])));
- assertEqualInt(0, owner_parse(ROOT ".", &uid, &gid));
+ assert(NULL == owner_parse(ROOT ".", &uid, &gid));
assert(int_in_list(uid, root_uids,
sizeof(root_uids)/sizeof(root_uids[0])));
assert(int_in_list(gid, root_gids,
sizeof(root_gids)/sizeof(root_gids[0])));
- assertEqualInt(0, owner_parse("111", &uid, &gid));
+ assert(NULL == owner_parse("111", &uid, &gid));
assertEqualInt(111, uid);
assertEqualInt(-1, gid);
- assertEqualInt(0, owner_parse("112:", &uid, &gid));
+ assert(NULL == owner_parse("112:", &uid, &gid));
assertEqualInt(112, uid);
/* Can't assert gid, since we don't know gid for user #112. */
- assertEqualInt(0, owner_parse("113.", &uid, &gid));
+ assert(NULL == owner_parse("113.", &uid, &gid));
assertEqualInt(113, uid);
/* Can't assert gid, since we don't know gid for user #113. */
- assertEqualInt(0, owner_parse(":114", &uid, &gid));
+ assert(NULL == owner_parse(":114", &uid, &gid));
assertEqualInt(-1, uid);
assertEqualInt(114, gid);
- assertEqualInt(0, owner_parse(".115", &uid, &gid));
+ assert(NULL == owner_parse(".115", &uid, &gid));
assertEqualInt(-1, uid);
assertEqualInt(115, gid);
- assertEqualInt(0, owner_parse("116:117", &uid, &gid));
+ assert(NULL == owner_parse("116:117", &uid, &gid));
assertEqualInt(116, uid);
assertEqualInt(117, gid);
@@ -112,19 +114,9 @@ DEFINE_TEST(test_owner_parse)
* users.
*/
- /*
- * TODO: Rework owner_parse to either return a char * pointing
- * to an error message or accept a function pointer to an
- * error-reporting routine so that the following tests don't
- * generate any output.
- *
- * Alternatively, redirect stderr temporarily to suppress the output.
- */
-
- cpio_progname = "Ignore this message";
- assertEqualInt(1, owner_parse(":nonexistentgroup", &uid, &gid));
- assertEqualInt(1, owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
- assertEqualInt(1,
+ assert(NULL != owner_parse(":nonexistentgroup", &uid, &gid));
+ assert(NULL != owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
+ assert(NULL !=
owner_parse("nonexistentuser:nonexistentgroup", &uid, &gid));
#endif
}
diff --git a/usr.bin/cpio/test/test_passthrough_dotdot.c b/usr.bin/cpio/test/test_passthrough_dotdot.c
index bcb5a6a..58d8234 100644
--- a/usr.bin/cpio/test/test_passthrough_dotdot.c
+++ b/usr.bin/cpio/test/test_passthrough_dotdot.c
@@ -31,33 +31,28 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_passthrough_dotdot)
{
- struct stat st;
- int fd, r;
- int filelist;
- int oldumask;
+ int r;
+ FILE *filelist;
- oldumask = umask(0);
+ assertUmask(0);
/*
* Create an assortment of files on disk.
*/
- filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
+ filelist = fopen("filelist", "w");
/* Directory. */
- assertEqualInt(0, mkdir("dir", 0755));
- assertEqualInt(0, chdir("dir"));
+ assertMakeDir("dir", 0755);
+ assertChdir("dir");
- write(filelist, ".\n", 2);
+ fprintf(filelist, ".\n");
/* File with 10 bytes content. */
- fd = open("file", O_CREAT | O_WRONLY, 0642);
- assert(fd >= 0);
- assertEqualInt(10, write(fd, "123456789", 10));
- close(fd);
- write(filelist, "file\n", 5);
+ assertMakeFile("file", 0642, "1234567890");
+ fprintf(filelist, "file\n");
/* All done. */
- close(filelist);
+ fclose(filelist);
/*
@@ -68,26 +63,14 @@ DEFINE_TEST(test_passthrough_dotdot)
failure("Error invoking %s -pd ..", testprog);
assertEqualInt(r, 0);
- assertEqualInt(0, chdir(".."));
+ assertChdir("..");
/* Verify stderr and stdout. */
assertTextFileContents("../.\n../file\n1 block\n", "stderr");
assertEmptyFile("stdout");
/* Regular file. */
- r = lstat("file", &st);
- failure("Failed to stat file, errno=%d", errno);
- assertEqualInt(r, 0);
- if (r == 0) {
- assert(S_ISREG(st.st_mode));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualInt(0600, st.st_mode & 0700);
-#else
- assertEqualInt(0642, st.st_mode & 0777);
-#endif
- assertEqualInt(10, st.st_size);
- assertEqualInt(1, st.st_nlink);
- }
-
- umask(oldumask);
+ assertIsReg("file", 0642);
+ assertFileSize("file", 10);
+ assertFileNLinks("file", 1);
}
diff --git a/usr.bin/cpio/test/test_passthrough_reverse.c b/usr.bin/cpio/test/test_passthrough_reverse.c
index a7695ed..42df75a 100644
--- a/usr.bin/cpio/test/test_passthrough_reverse.c
+++ b/usr.bin/cpio/test/test_passthrough_reverse.c
@@ -36,33 +36,28 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_passthrough_reverse)
{
- struct stat st;
- int fd, r;
- int filelist;
- int oldumask;
+ int r;
+ FILE *filelist;
- oldumask = umask(0);
+ assertUmask(0);
/*
* Create an assortment of files on disk.
*/
- filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
+ filelist = fopen("filelist", "w");
/* Directory. */
- assertEqualInt(0, mkdir("dir", 0743));
+ assertMakeDir("dir", 0743);
/* File with 10 bytes content. */
- fd = open("dir/file", O_CREAT | O_WRONLY, 0644);
- assert(fd >= 0);
- assertEqualInt(10, write(fd, "123456789", 10));
- close(fd);
- write(filelist, "dir/file\n", 9);
+ assertMakeFile("dir/file", 0644, "1234567890");
+ fprintf(filelist, "dir/file\n");
/* Write dir last. */
- write(filelist, "dir\n", 4);
+ fprintf(filelist, "dir\n");
/* All done. */
- close(filelist);
+ fclose(filelist);
/*
@@ -72,7 +67,7 @@ DEFINE_TEST(test_passthrough_reverse)
failure("Error invoking %s -pd out", testprog);
assertEqualInt(r, 0);
- assertEqualInt(0, chdir("out"));
+ assertChdir("out");
/* Verify stderr and stdout. */
assertTextFileContents("out/dir/file\nout/dir\n1 block\n",
@@ -80,33 +75,11 @@ DEFINE_TEST(test_passthrough_reverse)
assertEmptyFile("../stdout");
/* dir */
- r = lstat("dir", &st);
- if (r == 0) {
- assertEqualInt(r, 0);
- assert(S_ISDIR(st.st_mode));
- failure("st.st_mode=0%o", st.st_mode);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualInt(0700, st.st_mode & 0700);
-#else
- assertEqualInt(0743, st.st_mode & 0777);
-#endif
- }
+ assertIsDir("dir", 0743);
/* Regular file. */
- r = lstat("dir/file", &st);
- failure("Failed to stat dir/file, errno=%d", errno);
- assertEqualInt(r, 0);
- if (r == 0) {
- assert(S_ISREG(st.st_mode));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- assertEqualInt(0600, st.st_mode & 0700);
-#else
- assertEqualInt(0644, st.st_mode & 0777);
-#endif
- assertEqualInt(10, st.st_size);
- assertEqualInt(1, st.st_nlink);
- }
-
- umask(oldumask);
+ assertIsReg("dir/file", 0644);
+ assertFileSize("dir/file", 10);
+ assertFileNLinks("dir/file", 1);
}
diff --git a/usr.bin/cpio/test/test_pathmatch.c b/usr.bin/cpio/test/test_pathmatch.c
index a596eda..177c2bc 100644
--- a/usr.bin/cpio/test/test_pathmatch.c
+++ b/usr.bin/cpio/test/test_pathmatch.c
@@ -25,7 +25,7 @@
#include "test.h"
__FBSDID("$FreeBSD$");
-#include "../pathmatch.h"
+#include "pathmatch.h"
/*
* Verify that the pattern matcher implements the wildcard logic specified
@@ -45,126 +45,126 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_pathmatch)
{
- assertEqualInt(1, pathmatch("a/b/c", "a/b/c", 0));
- assertEqualInt(0, pathmatch("a/b/", "a/b/c", 0));
- assertEqualInt(0, pathmatch("a/b", "a/b/c", 0));
- assertEqualInt(0, pathmatch("a/b/c", "a/b/", 0));
- assertEqualInt(0, pathmatch("a/b/c", "a/b", 0));
+ assertEqualInt(1, lafe_pathmatch("a/b/c", "a/b/c", 0));
+ assertEqualInt(0, lafe_pathmatch("a/b/", "a/b/c", 0));
+ assertEqualInt(0, lafe_pathmatch("a/b", "a/b/c", 0));
+ assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b/", 0));
+ assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b", 0));
/* Empty pattern only matches empty string. */
- assertEqualInt(1, pathmatch("","", 0));
- assertEqualInt(0, pathmatch("","a", 0));
- assertEqualInt(1, pathmatch("*","", 0));
- assertEqualInt(1, pathmatch("*","a", 0));
- assertEqualInt(1, pathmatch("*","abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("","", 0));
+ assertEqualInt(0, lafe_pathmatch("","a", 0));
+ assertEqualInt(1, lafe_pathmatch("*","", 0));
+ assertEqualInt(1, lafe_pathmatch("*","a", 0));
+ assertEqualInt(1, lafe_pathmatch("*","abcd", 0));
/* SUSv2: * matches / */
- assertEqualInt(1, pathmatch("*","abcd/efgh/ijkl", 0));
- assertEqualInt(1, pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(1, pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(1, pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(0, pathmatch("?", "", 0));
- assertEqualInt(0, pathmatch("?", "\0", 0));
- assertEqualInt(1, pathmatch("?", "a", 0));
- assertEqualInt(0, pathmatch("?", "ab", 0));
- assertEqualInt(1, pathmatch("?", ".", 0));
- assertEqualInt(1, pathmatch("?", "?", 0));
- assertEqualInt(1, pathmatch("a", "a", 0));
- assertEqualInt(0, pathmatch("a", "ab", 0));
- assertEqualInt(0, pathmatch("a", "ab", 0));
- assertEqualInt(1, pathmatch("a?c", "abc", 0));
+ assertEqualInt(1, lafe_pathmatch("*","abcd/efgh/ijkl", 0));
+ assertEqualInt(1, lafe_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
+ assertEqualInt(1, lafe_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
+ assertEqualInt(1, lafe_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
+ assertEqualInt(0, lafe_pathmatch("?", "", 0));
+ assertEqualInt(0, lafe_pathmatch("?", "\0", 0));
+ assertEqualInt(1, lafe_pathmatch("?", "a", 0));
+ assertEqualInt(0, lafe_pathmatch("?", "ab", 0));
+ assertEqualInt(1, lafe_pathmatch("?", ".", 0));
+ assertEqualInt(1, lafe_pathmatch("?", "?", 0));
+ assertEqualInt(1, lafe_pathmatch("a", "a", 0));
+ assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
+ assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
+ assertEqualInt(1, lafe_pathmatch("a?c", "abc", 0));
/* SUSv2: ? matches / */
- assertEqualInt(1, pathmatch("a?c", "a/c", 0));
- assertEqualInt(1, pathmatch("a?*c*", "a/c", 0));
- assertEqualInt(1, pathmatch("*a*", "a/c", 0));
- assertEqualInt(1, pathmatch("*a*", "/a/c", 0));
- assertEqualInt(1, pathmatch("*a*", "defaaaaaaa", 0));
- assertEqualInt(0, pathmatch("a*", "defghi", 0));
- assertEqualInt(0, pathmatch("*a*", "defghi", 0));
+ assertEqualInt(1, lafe_pathmatch("a?c", "a/c", 0));
+ assertEqualInt(1, lafe_pathmatch("a?*c*", "a/c", 0));
+ assertEqualInt(1, lafe_pathmatch("*a*", "a/c", 0));
+ assertEqualInt(1, lafe_pathmatch("*a*", "/a/c", 0));
+ assertEqualInt(1, lafe_pathmatch("*a*", "defaaaaaaa", 0));
+ assertEqualInt(0, lafe_pathmatch("a*", "defghi", 0));
+ assertEqualInt(0, lafe_pathmatch("*a*", "defghi", 0));
/* Character classes */
- assertEqualInt(1, pathmatch("abc[def", "abc[def", 0));
- assertEqualInt(0, pathmatch("abc[def]", "abc[def", 0));
- assertEqualInt(0, pathmatch("abc[def", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[def]", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[def]", "abce", 0));
- assertEqualInt(1, pathmatch("abc[def]", "abcf", 0));
- assertEqualInt(0, pathmatch("abc[def]", "abcg", 0));
- assertEqualInt(1, pathmatch("abc[d*f]", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[d*f]", "abc*", 0));
- assertEqualInt(0, pathmatch("abc[d*f]", "abcdefghi", 0));
- assertEqualInt(0, pathmatch("abc[d*", "abcdefghi", 0));
- assertEqualInt(1, pathmatch("abc[d*", "abc[defghi", 0));
- assertEqualInt(1, pathmatch("abc[d-f]", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[d-f]", "abce", 0));
- assertEqualInt(1, pathmatch("abc[d-f]", "abcf", 0));
- assertEqualInt(0, pathmatch("abc[d-f]", "abcg", 0));
- assertEqualInt(0, pathmatch("abc[d-fh-k]", "abca", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-k]", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-k]", "abce", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-k]", "abcf", 0));
- assertEqualInt(0, pathmatch("abc[d-fh-k]", "abcg", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-k]", "abch", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-k]", "abci", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-k]", "abcj", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-k]", "abck", 0));
- assertEqualInt(0, pathmatch("abc[d-fh-k]", "abcl", 0));
- assertEqualInt(0, pathmatch("abc[d-fh-k]", "abc-", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[def", "abc[def", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[def]", "abc[def", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[def", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[def]", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[def]", "abce", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[def]", "abcf", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[def]", "abcg", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abc*", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d*f]", "abcdefghi", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d*", "abcdefghi", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d*", "abc[defghi", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abce", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcf", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d-f]", "abcg", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abca", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abce", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcf", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcg", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abch", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abci", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcj", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abck", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcl", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abc-", 0));
/* [] matches nothing, [!] is the same as ? */
- assertEqualInt(0, pathmatch("abc[]efg", "abcdefg", 0));
- assertEqualInt(0, pathmatch("abc[]efg", "abcqefg", 0));
- assertEqualInt(0, pathmatch("abc[]efg", "abcefg", 0));
- assertEqualInt(1, pathmatch("abc[!]efg", "abcdefg", 0));
- assertEqualInt(1, pathmatch("abc[!]efg", "abcqefg", 0));
- assertEqualInt(0, pathmatch("abc[!]efg", "abcefg", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcdefg", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcqefg", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcefg", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcdefg", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcqefg", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[!]efg", "abcefg", 0));
/* I assume: Trailing '-' is non-special. */
- assertEqualInt(0, pathmatch("abc[d-fh-]", "abcl", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-]", "abch", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-]", "abc-", 0));
- assertEqualInt(1, pathmatch("abc[d-fh-]", "abc-", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d-fh-]", "abcl", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abch", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
/* ']' can be backslash-quoted within a character class. */
- assertEqualInt(1, pathmatch("abc[\\]]", "abc]", 0));
- assertEqualInt(1, pathmatch("abc[\\]d]", "abc]", 0));
- assertEqualInt(1, pathmatch("abc[\\]d]", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[d\\]]", "abc]", 0));
- assertEqualInt(1, pathmatch("abc[d\\]]", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[d]e]", "abcde]", 0));
- assertEqualInt(1, pathmatch("abc[d\\]e]", "abc]", 0));
- assertEqualInt(0, pathmatch("abc[d\\]e]", "abcd]e", 0));
- assertEqualInt(0, pathmatch("abc[d]e]", "abc]", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[\\]]", "abc]", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abc]", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abc]", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d]e]", "abcde]", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d\\]e]", "abc]", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d\\]e]", "abcd]e", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d]e]", "abc]", 0));
/* backslash-quoted chars can appear as either end of a range. */
- assertEqualInt(1, pathmatch("abc[\\d-f]gh", "abcegh", 0));
- assertEqualInt(0, pathmatch("abc[\\d-f]gh", "abcggh", 0));
- assertEqualInt(0, pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
- assertEqualInt(1, pathmatch("abc[d-\\f]gh", "abcegh", 0));
- assertEqualInt(1, pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
- assertEqualInt(1, pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[\\d-f]gh", "abcegh", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abcggh", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d-\\f]gh", "abcegh", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
/* backslash-quoted '-' isn't special. */
- assertEqualInt(0, pathmatch("abc[d\\-f]gh", "abcegh", 0));
- assertEqualInt(1, pathmatch("abc[d\\-f]gh", "abc-gh", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[d\\-f]gh", "abcegh", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[d\\-f]gh", "abc-gh", 0));
/* Leading '!' negates a character class. */
- assertEqualInt(0, pathmatch("abc[!d]", "abcd", 0));
- assertEqualInt(1, pathmatch("abc[!d]", "abce", 0));
- assertEqualInt(1, pathmatch("abc[!d]", "abcc", 0));
- assertEqualInt(0, pathmatch("abc[!d-z]", "abcq", 0));
- assertEqualInt(1, pathmatch("abc[!d-gi-z]", "abch", 0));
- assertEqualInt(1, pathmatch("abc[!fgijkl]", "abch", 0));
- assertEqualInt(0, pathmatch("abc[!fghijkl]", "abch", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[!d]", "abcd", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[!d]", "abce", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[!d]", "abcc", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[!d-z]", "abcq", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[!d-gi-z]", "abch", 0));
+ assertEqualInt(1, lafe_pathmatch("abc[!fgijkl]", "abch", 0));
+ assertEqualInt(0, lafe_pathmatch("abc[!fghijkl]", "abch", 0));
/* Backslash quotes next character. */
- assertEqualInt(0, pathmatch("abc\\[def]", "abc\\d", 0));
- assertEqualInt(1, pathmatch("abc\\[def]", "abc[def]", 0));
- assertEqualInt(0, pathmatch("abc\\\\[def]", "abc[def]", 0));
- assertEqualInt(0, pathmatch("abc\\\\[def]", "abc\\[def]", 0));
- assertEqualInt(1, pathmatch("abc\\\\[def]", "abc\\d", 0));
- assertEqualInt(1, pathmatch("abcd\\", "abcd\\", 0));
- assertEqualInt(0, pathmatch("abcd\\", "abcd\\[", 0));
- assertEqualInt(0, pathmatch("abcd\\", "abcde", 0));
- assertEqualInt(0, pathmatch("abcd\\[", "abcd\\", 0));
+ assertEqualInt(0, lafe_pathmatch("abc\\[def]", "abc\\d", 0));
+ assertEqualInt(1, lafe_pathmatch("abc\\[def]", "abc[def]", 0));
+ assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc[def]", 0));
+ assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
+ assertEqualInt(1, lafe_pathmatch("abc\\\\[def]", "abc\\d", 0));
+ assertEqualInt(1, lafe_pathmatch("abcd\\", "abcd\\", 0));
+ assertEqualInt(0, lafe_pathmatch("abcd\\", "abcd\\[", 0));
+ assertEqualInt(0, lafe_pathmatch("abcd\\", "abcde", 0));
+ assertEqualInt(0, lafe_pathmatch("abcd\\[", "abcd\\", 0));
/*
* Because '.' and '/' have special meanings, we can
@@ -172,72 +172,72 @@ DEFINE_TEST(test_pathmatch)
* differently. (But quoting a character with '\\' suppresses
* special meanings!)
*/
- assertEqualInt(0, pathmatch("a/b/", "a/bc", 0));
- assertEqualInt(1, pathmatch("a/./b", "a/b", 0));
- assertEqualInt(0, pathmatch("a\\/./b", "a/b", 0));
- assertEqualInt(0, pathmatch("a/\\./b", "a/b", 0));
- assertEqualInt(0, pathmatch("a/.\\/b", "a/b", 0));
- assertEqualInt(0, pathmatch("a\\/\\.\\/b", "a/b", 0));
- assertEqualInt(1, pathmatch("./abc/./def/", "abc/def/", 0));
- assertEqualInt(1, pathmatch("abc/def", "./././abc/./def", 0));
- assertEqualInt(1, pathmatch("abc/def/././//", "./././abc/./def/", 0));
- assertEqualInt(1, pathmatch(".////abc/.//def", "./././abc/./def", 0));
- assertEqualInt(1, pathmatch("./abc?def/", "abc/def/", 0));
+ assertEqualInt(0, lafe_pathmatch("a/b/", "a/bc", 0));
+ assertEqualInt(1, lafe_pathmatch("a/./b", "a/b", 0));
+ assertEqualInt(0, lafe_pathmatch("a\\/./b", "a/b", 0));
+ assertEqualInt(0, lafe_pathmatch("a/\\./b", "a/b", 0));
+ assertEqualInt(0, lafe_pathmatch("a/.\\/b", "a/b", 0));
+ assertEqualInt(0, lafe_pathmatch("a\\/\\.\\/b", "a/b", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def/", 0));
+ assertEqualInt(1, lafe_pathmatch("abc/def", "./././abc/./def", 0));
+ assertEqualInt(1, lafe_pathmatch("abc/def/././//", "./././abc/./def/", 0));
+ assertEqualInt(1, lafe_pathmatch(".////abc/.//def", "./././abc/./def", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc?def/", "abc/def/", 0));
failure("\"?./\" is not the same as \"/./\"");
- assertEqualInt(0, pathmatch("./abc?./def/", "abc/def/", 0));
+ assertEqualInt(0, lafe_pathmatch("./abc?./def/", "abc/def/", 0));
failure("Trailing '/' should match no trailing '/'");
- assertEqualInt(1, pathmatch("./abc/./def/", "abc/def", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def", 0));
failure("Trailing '/./' is still the same directory.");
- assertEqualInt(1, pathmatch("./abc/./def/./", "abc/def", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc/./def/./", "abc/def", 0));
failure("Trailing '/.' is still the same directory.");
- assertEqualInt(1, pathmatch("./abc/./def/.", "abc/def", 0));
- assertEqualInt(1, pathmatch("./abc/./def", "abc/def/", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc/./def/.", "abc/def", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/", 0));
failure("Trailing '/./' is still the same directory.");
- assertEqualInt(1, pathmatch("./abc/./def", "abc/def/./", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/./", 0));
failure("Trailing '/.' is still the same directory.");
- assertEqualInt(1, pathmatch("./abc*/./def", "abc/def/.", 0));
+ assertEqualInt(1, lafe_pathmatch("./abc*/./def", "abc/def/.", 0));
/* Matches not anchored at beginning. */
assertEqualInt(0,
- pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
+ lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(1,
- pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
+ lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(0,
- pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
+ lafe_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(1,
- pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
+ lafe_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(0,
- pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
+ lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(0,
- pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
+ lafe_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
/* Matches not anchored at end. */
assertEqualInt(0,
- pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
- pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
- pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
- pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
- pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
- pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+ lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
}
OpenPOWER on IntegriCloud