This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gold][patch] Add execute permission to output file


Gold normally unlinks an output file before creating it, so that the
permissions are correctly set. If the output file exists but is empty,
however, gold assumes that it was pre-created with tight permissions,
and leaves it alone. Unfortunately, the ffmpeg configure script
creates an empty but non-executable file, then expects the output file
to be executable. This patch modifies gold to add execute permission
to the file wherever read permission was already granted. (It still
applies the umask to the final mode.)

Since we already do a stat and check for a regular file in order to do
the chmod, I changed it to call ::unlink directly instead of using
libiberty's unlink_if_ordinary.

OK?

-cary


	* output.cc (Output_file::open): Add execute permission to empty file.
	* testsuite/Makefile.am (permission_test): New test.
	* testsuite/Makefile.in: Regenerate.

[testsuite/Makefile.in diffs omitted]

Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.94
diff -u -p -r1.94 output.cc
--- output.cc	2 Sep 2009 16:39:06 -0000	1.94
+++ output.cc	4 Sep 2009 22:10:13 -0000
@@ -30,7 +30,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <algorithm>
-#include "libiberty.h"   // for unlink_if_ordinary()
+#include "libiberty.h"   // for lbasename()

 #include "parameters.h"
 #include "object.h"
@@ -3461,8 +3461,23 @@ 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;
+		  gold_info("setting mode %o & ~%o = %o", s.st_mode, mask,
s.st_mode & ~mask);
+		  ::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,
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.100
diff -u -p -r1.100 Makefile.am
--- testsuite/Makefile.am	22 Aug 2009 19:02:57 -0000	1.100
+++ testsuite/Makefile.am	4 Sep 2009 22:10:13 -0000
@@ -1139,5 +1139,15 @@ hidden_test: hidden_test_main.o libhidde
 hidden_test.err: hidden_test
 	@touch hidden_test.err

+# Test that if the output file already exists and is empty,
+# it will get execute permission.
+check_PROGRAMS += permission_test
+permission_test: basic_test.o gcctestdir/ld
+	umask 022; \
+	rm -f $@; \
+	touch $@; \
+	chmod 600 $@; \
+	$(CXXLINK) -Bgcctestdir/ basic_test.o
+
 endif GCC
 endif NATIVE_LINKER


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]