summaryrefslogtreecommitdiff
path: root/usr.bin/file
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2015-05-29 12:33:42 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2015-05-29 12:33:42 +0000
commit7cd598d6097e680a2c6b65365f682834b6e325ca (patch)
tree7770822951dfb36f273bc6b18696eec0abbadb90 /usr.bin/file
parent119276b9e061855a6daf79eb8a3ddc7762af71b6 (diff)
Only mmap() on regular files; mmap() on /dev/stdin will happily map as
much as we ask for but only the first page will be usable. (We could get the actual size with ioctl(FIONREAD) and mmap() that but it would need to be done in the parent - I think just using read() is simpler.)
Diffstat (limited to 'usr.bin/file')
-rw-r--r--usr.bin/file/file.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/usr.bin/file/file.c b/usr.bin/file/file.c
index 406e64b74d9..2d65e65fbde 100644
--- a/usr.bin/file/file.c
+++ b/usr.bin/file/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.42 2015/05/29 11:59:01 nicm Exp $ */
+/* $OpenBSD: file.c,v 1.43 2015/05/29 12:33:41 nicm Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -405,26 +405,28 @@ load_file(struct input_file *inf)
size_t used;
inf->size = inf->msg->sb.st_size;
- if (inf->size > FILE_READ_SIZE)
+ if (inf->size == 0 && S_ISREG(inf->msg->sb.st_mode))
+ return (0); /* empty file */
+ if (inf->size == 0 || inf->size > FILE_READ_SIZE)
inf->size = FILE_READ_SIZE;
- if (inf->size == 0) {
- if (!S_ISREG(inf->msg->sb.st_mode))
- inf->size = FILE_READ_SIZE;
- else
- return (0);
- }
+
+ if (!S_ISREG(inf->msg->sb.st_mode))
+ goto try_read;
inf->base = mmap(NULL, inf->size, PROT_READ, MAP_PRIVATE, inf->fd, 0);
- if (inf->base == MAP_FAILED) {
- inf->base = fill_buffer(inf->fd, inf->size, &used);
- if (inf->base == NULL) {
- xasprintf(&inf->result, "cannot read '%s' (%s)",
- inf->path, strerror(errno));
- return (1);
- }
- inf->size = used;
- } else
- inf->mapped = 1;
+ if (inf->base == MAP_FAILED)
+ goto try_read;
+ inf->mapped = 1;
+ return (0);
+
+try_read:
+ inf->base = fill_buffer(inf->fd, inf->size, &used);
+ if (inf->base == NULL) {
+ xasprintf(&inf->result, "cannot read '%s' (%s)", inf->path,
+ strerror(errno));
+ return (1);
+ }
+ inf->size = used;
return (0);
}