aboutsummaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2009-09-08 22:32:51 +0000
committerCary Coutant <ccoutant@google.com>2009-09-08 22:32:51 +0000
commit6a89f575aaaf6f183620a91507e965205429a54a (patch)
treeb619bed64d92f4364d6b95a27f03a4d277be5d6f /gold/output.cc
parenta5bbabf3b57792e1bbc7fa3ae2e712dae1da282a (diff)
downloadfsf-binutils-gdb-6a89f575aaaf6f183620a91507e965205429a54a.zip
fsf-binutils-gdb-6a89f575aaaf6f183620a91507e965205429a54a.tar.gz
fsf-binutils-gdb-6a89f575aaaf6f183620a91507e965205429a54a.tar.bz2
* output.cc (Output_file::open): Add execute permission to empty file.
* testsuite/Makefile.am (permission_test): New test. * testsuite/Makefile.in: Regenerate.
Diffstat (limited to 'gold/output.cc')
-rw-r--r--gold/output.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/gold/output.cc b/gold/output.cc
index fd47407..e99464b 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -30,7 +30,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <algorithm>
-#include "libiberty.h" // for unlink_if_ordinary()
+#include "libiberty.h"
#include "parameters.h"
#include "object.h"
@@ -3461,8 +3461,22 @@ Output_file::open(off_t file_size)
else
{
struct stat s;
- if (::stat(this->name_, &s) == 0 && s.st_size != 0)
- unlink_if_ordinary(this->name_);
+ if (::stat(this->name_, &s) == 0
+ && (S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
+ {
+ if (s.st_size != 0)
+ ::unlink(this->name_);
+ else if (!parameters->options().relocatable())
+ {
+ // If we don't unlink the existing file, add execute
+ // permission where read permissions already exist
+ // and where the umask permits.
+ int mask = ::umask(0);
+ ::umask(mask);
+ s.st_mode |= (s.st_mode & 0444) >> 2;
+ ::chmod(this->name_, s.st_mode & ~mask);
+ }
+ }
int mode = parameters->options().relocatable() ? 0666 : 0777;
int o = open_descriptor(-1, this->name_, O_RDWR | O_CREAT | O_TRUNC,