diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2003-05-11 18:18:34 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2003-05-11 18:18:34 +0000 |
commit | fc2395fc3e8918a15c1ea31f804445d5e952b149 (patch) | |
tree | 5766a1e6f67149ab7c6041b0a4f33b49a2286aa0 /usr.bin/xinstall | |
parent | 201916e8c8ad047656a54faba017f264febd94ea (diff) |
when doing sparse writes, we must write the last byte or the file will
be shortened. problem found by wcobb and naddy. ok millert@
Diffstat (limited to 'usr.bin/xinstall')
-rw-r--r-- | usr.bin/xinstall/xinstall.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index 25d4b5ec8a2..b84b0e42aa0 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xinstall.c,v 1.32 2003/05/07 22:38:06 millert Exp $ */ +/* $OpenBSD: xinstall.c,v 1.33 2003/05/11 18:18:33 tedu Exp $ */ /* $NetBSD: xinstall.c,v 1.9 1995/12/20 10:25:17 jonathan Exp $ */ /* @@ -44,7 +44,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93"; #endif -static char rcsid[] = "$OpenBSD: xinstall.c,v 1.32 2003/05/07 22:38:06 millert Exp $"; +static char rcsid[] = "$OpenBSD: xinstall.c,v 1.33 2003/05/11 18:18:33 tedu Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -91,6 +91,7 @@ void usage(void); int create_newfile(char *, struct stat *); int create_tempfile(char *, char *, size_t); int file_write(int, char *, size_t, int *, int *, int); +void file_flush(int, int); int main(argc, argv) @@ -483,6 +484,8 @@ copy(from_fd, from_name, to_fd, to_name, size, sparse) to_name, strerror(nw > 0 ? EIO : serrno)); } } + if (sparse) + file_flush(to_fd, isem); if (nr != 0) { serrno = errno; (void)unlink(to_name); @@ -797,3 +800,35 @@ file_write(fd, str, cnt, rem, isempt, sz) } return(st - str); } + +/* + * file_flush() + * when the last file block in a file is zero, many file systems will not + * let us create a hole at the end. To get the last block with zeros, we + * write the last BYTE with a zero (back up one byte and write a zero). + */ + +void +file_flush(int fd, int isempt) +{ + static char blnk[] = "\0"; + + /* + * silly test, but make sure we are only called when the last block is + * filled with all zeros. + */ + if (!isempt) + return; + + /* + * move back one byte and write a zero + */ + if (lseek(fd, (off_t)-1, SEEK_CUR) < 0) { + warn("Failed seek on file"); + return; + } + + if (write(fd, blnk, 1) < 0) + warn("Failed write to file"); + return; +} |