From Craig Silverstein: delete the output file first if it exists and
is non-empty.
This commit is contained in:
parent
cf0d1c8e4d
commit
4e9d858638
|
@ -27,6 +27,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
|
@ -1672,6 +1673,25 @@ Output_file::open(off_t file_size)
|
||||||
{
|
{
|
||||||
this->file_size_ = 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 mode = parameters->output_is_object() ? 0666 : 0777;
|
||||||
int o = ::open(this->name_, O_RDWR | O_CREAT | O_TRUNC, mode);
|
int o = ::open(this->name_, O_RDWR | O_CREAT | O_TRUNC, mode);
|
||||||
if (o < 0)
|
if (o < 0)
|
||||||
|
|
Loading…
Reference in New Issue