summaryrefslogtreecommitdiff
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
commitadda875ca926ef99f0cf86bcbabd673a2aa0e358 (patch)
tree5170ec439963fb19ab21b8930c17ae4652ba1e7c /gold/output.cc
parent4ab6d979f8247c9940cb9339b254f1a0d238af0f (diff)
downloadbinutils-redhat-adda875ca926ef99f0cf86bcbabd673a2aa0e358.tar.gz
* 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 fd47407052..e99464b265 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,