diff options
author | Ian Lance Taylor <iant@google.com> | 2007-10-10 06:29:10 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2007-10-10 06:29:10 +0000 |
commit | 4e9d858638034246a4ab4595f5497c7393c3bfbf (patch) | |
tree | ce12b58bbbdfaeb83860f343f6c8b0c5227e50d0 | |
parent | cf0d1c8e4d67e3236e0a977cd6933ef5ed1a06e4 (diff) | |
download | gdb-4e9d858638034246a4ab4595f5497c7393c3bfbf.zip gdb-4e9d858638034246a4ab4595f5497c7393c3bfbf.tar.gz gdb-4e9d858638034246a4ab4595f5497c7393c3bfbf.tar.bz2 |
From Craig Silverstein: delete the output file first if it exists and
is non-empty.
-rw-r--r-- | gold/output.cc | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/gold/output.cc b/gold/output.cc index f217b03..f539dea 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -27,6 +27,7 @@ #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> +#include <sys/stat.h> #include <algorithm> #include "parameters.h" @@ -1672,6 +1673,25 @@ Output_file::open(off_t file_size) { this->file_size_ = file_size; + // Unlink the file first; otherwise the open() may fail if the file + // is busy (e.g. it's an executable that's currently being executed). + // + // However, the linker may be part of a system where a zero-length + // file is created for it to write to, with tight permissions (gcc + // 2.95 did something like this). Unlinking the file would work + // around those permission controls, so we only unlink if the file + // has a non-zero size. We also unlink only regular files to avoid + // trouble with directories/etc. + // + // If we fail, continue; this command is merely a best-effort attempt + // to improve the odds for open(). + + // FIXME: unlink the file if it's a symlink, even a symlink to a dir. + // Or do we want to follow the symlink and unlink its target? + struct stat s; + if (::stat(this->name_, &s) == 0 && s.st_size != 0 && S_ISREG(s.st_mode)) + ::unlink(this->name_); + int mode = parameters->output_is_object() ? 0666 : 0777; int o = ::open(this->name_, O_RDWR | O_CREAT | O_TRUNC, mode); if (o < 0) |