aboutsummaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-03-17 22:25:30 +0000
committerIan Lance Taylor <ian@airs.com>2009-03-17 22:25:30 +0000
commit9201d894910e26e87fbfc0af24d9460797b1890f (patch)
tree777029282e401e722d33f5fc0528fc02c267979f /gold/output.cc
parentef4ab7a8185e12b2a2e76982a9fe82c8d0f10a38 (diff)
downloadgdb-9201d894910e26e87fbfc0af24d9460797b1890f.zip
gdb-9201d894910e26e87fbfc0af24d9460797b1890f.tar.gz
gdb-9201d894910e26e87fbfc0af24d9460797b1890f.tar.bz2
* configure.ac: Check for chsize and posix_fallocate. Replace
ftruncate. * ftruncate.c: New file, from gnulib. * output.cc (posix_fallocate): Define dummy version if not HAVE_POSIX_FALLOCATE. (Output_file::map): Call posix_fallocate rather than lseek and write. * gold.h (ftruncate): Declare if not HAVE_FTRUNCATE. * configure, Makefile.in, config.in: Rebuild.
Diffstat (limited to 'gold/output.cc')
-rw-r--r--gold/output.cc28
1 files changed, 22 insertions, 6 deletions
diff --git a/gold/output.cc b/gold/output.cc
index f2ec6ee..2f9db62 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -45,6 +45,18 @@
# define MAP_ANONYMOUS MAP_ANON
#endif
+#ifndef HAVE_POSIX_FALLOCATE
+// A dummy, non general, version of posix_fallocate. Here we just set
+// the file size and hope that there is enough disk space. FIXME: We
+// could allocate disk space by walking block by block and writing a
+// zero byte into each block.
+static int
+posix_fallocate(int o, off_t offset, off_t len)
+{
+ return ftruncate(o, offset + len);
+}
+#endif // !defined(HAVE_POSIX_FALLOCATE)
+
namespace gold
{
@@ -3388,12 +3400,16 @@ Output_file::map()
}
else
{
- // Write out one byte to make the file the right size.
- if (::lseek(o, this->file_size_ - 1, SEEK_SET) < 0)
- gold_fatal(_("%s: lseek: %s"), this->name_, strerror(errno));
- char b = 0;
- if (::write(o, &b, 1) != 1)
- gold_fatal(_("%s: write: %s"), this->name_, strerror(errno));
+ // Ensure that we have disk space available for the file. If we
+ // don't do this, it is possible that we will call munmap,
+ // close, and exit with dirty buffers still in the cache with no
+ // assigned disk blocks. If the disk is out of space at that
+ // point, the output file will wind up incomplete, but we will
+ // have already exited. The alternative to fallocate would be
+ // to use fdatasync, but that would be a more significant
+ // performance hit.
+ if (::posix_fallocate(o, 0, this->file_size_) < 0)
+ gold_fatal(_("%s: %s"), this->name_, strerror(errno));
// Map the file into memory.
this->map_is_anonymous_ = false;