aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/xinstall/xinstall.c
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>1996-09-05 07:54:08 +0000
committerPeter Wemm <peter@FreeBSD.org>1996-09-05 07:54:08 +0000
commite547f8e83aab5e08da53f69b29b4cfe6db20b115 (patch)
tree1d7681db43ace50ceb293e7bd3c6c2f571fb4a85 /usr.bin/xinstall/xinstall.c
parent8a4854e0f71440c2dd4b96dff314a6e215f0ee9f (diff)
downloadsrc-e547f8e83aab5e08da53f69b29b4cfe6db20b115.tar.gz
src-e547f8e83aab5e08da53f69b29b4cfe6db20b115.zip
Be more careful with mmap. If it fails, fall back to a plain compare or
copy. Dont leave stray INS@xxxx temp files around, especially when installing something less than 8MB and the destination runs out of space, etc. It still doesn't clean up the temp files on SEGV or other signals etc.
Notes
Notes: svn path=/head/; revision=18040
Diffstat (limited to 'usr.bin/xinstall/xinstall.c')
-rw-r--r--usr.bin/xinstall/xinstall.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
index b083a405e0c5..d50925b572ed 100644
--- a/usr.bin/xinstall/xinstall.c
+++ b/usr.bin/xinstall/xinstall.c
@@ -40,7 +40,7 @@ static const char copyright[] =
#ifndef lint
/*static char sccsid[] = "From: @(#)xinstall.c 8.1 (Berkeley) 7/21/93";*/
static const char rcsid[] =
- "$Id: xinstall.c,v 1.10 1996/09/05 07:27:43 peter Exp $";
+ "$Id: xinstall.c,v 1.11 1996/09/05 07:33:24 peter Exp $";
#endif /* not lint */
/*-
@@ -484,6 +484,7 @@ compare(int from_fd, const char *from_name, int to_fd, const char *to_name,
char *p, *q;
int rv;
size_t tsize;
+ int done_compare;
if (from_sb->st_size != to_sb->st_size)
return 1;
@@ -491,20 +492,26 @@ compare(int from_fd, const char *from_name, int to_fd, const char *to_name,
tsize = (size_t)from_sb->st_size;
if (tsize <= 8 * 1024 * 1024) {
+ done_compare = 0;
if (trymmap(from_fd) && trymmap(to_fd)) {
p = mmap(NULL, tsize, PROT_READ, 0, from_fd, (off_t)0);
if ((long)p == -1)
- err(EX_OSERR, "mmap %s", from_name);
+ goto out;
q = mmap(NULL, tsize, PROT_READ, 0, to_fd, (off_t)0);
- if ((long)q == -1)
- err(EX_OSERR, "mmap %s", to_name);
+ if ((long)q == -1) {
+ munmap(p, tsize);
+ goto out;
+ }
rv = memcmp(p, q, tsize);
munmap(p, tsize);
munmap(q, tsize);
- } else {
- char buf1[16384];
- char buf2[16384];
+ done_compare = 1;
+ }
+ out:
+ if (!done_compare) {
+ char buf1[MAXBSIZE];
+ char buf2[MAXBSIZE];
int n1, n2;
rv = 0;
@@ -545,19 +552,28 @@ copy(from_fd, from_name, to_fd, to_name, size)
register int nr, nw;
int serrno;
char *p, buf[MAXBSIZE];
+ int done_copy;
/*
* Mmap and write if less than 8M (the limit is so we don't totally
* trash memory on big files. This is really a minor hack, but it
* wins some CPU back.
*/
+ done_copy = 0;
if (size <= 8 * 1048576 && trymmap(from_fd)) {
if ((p = mmap(NULL, (size_t)size, PROT_READ,
- 0, from_fd, (off_t)0)) == (char *)-1)
- err(EX_OSERR, "mmap %s", from_name);
- if (write(to_fd, p, size) != size)
+ 0, from_fd, (off_t)0)) == (char *)-1)
+ goto out;
+ if ((nw = write(to_fd, p, size)) != size) {
+ serrno = errno;
+ (void)unlink(to_name);
+ errno = nw > 0 ? EIO : serrno;
err(EX_OSERR, "%s", to_name);
- } else {
+ }
+ done_copy = 1;
+ out:
+ }
+ if (!done_copy) {
while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
if ((nw = write(to_fd, buf, nr)) != nr) {
serrno = errno;