aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-03-17 17:09:44 +0000
committerIan Lance Taylor <ian@airs.com>2009-03-17 17:09:44 +0000
commite85b18e10cf468cdbac014e960c9e36b071057ab (patch)
tree3001b614784b7ad3242a88164c189410924b4935
parenta89e6478375cb5c3c03ef209164ad1b7b80d6939 (diff)
downloadgdb-e85b18e10cf468cdbac014e960c9e36b071057ab.zip
gdb-e85b18e10cf468cdbac014e960c9e36b071057ab.tar.gz
gdb-e85b18e10cf468cdbac014e960c9e36b071057ab.tar.bz2
* descriptors.cc: Include "options.h".
(FD_CLOEXEC, O_CLOEXEC): Define if not defined. (Descriptors::open): Always use O_CLOEXEC when opening a new descriptor. If we have a plugin, and O_CLOEXEC was not defined, then set FD_CLOEXEC.
-rw-r--r--gold/ChangeLog6
-rw-r--r--gold/descriptors.cc62
2 files changed, 50 insertions, 18 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 7af69c4..9425ea6 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,11 @@
2009-03-17 Ian Lance Taylor <iant@google.com>
+ * descriptors.cc: Include "options.h".
+ (FD_CLOEXEC, O_CLOEXEC): Define if not defined.
+ (Descriptors::open): Always use O_CLOEXEC when opening a new
+ descriptor. If we have a plugin, and O_CLOEXEC was not defined,
+ then set FD_CLOEXEC.
+
* sparc.cc (class Target_sparc): Add has_got_section.
(Target_sparc::Scan::global): If we see _GLOBAL_OFFSET_TABLE_,
make sure we have a GOT section.
diff --git a/gold/descriptors.cc b/gold/descriptors.cc
index 862edae..6937741 100644
--- a/gold/descriptors.cc
+++ b/gold/descriptors.cc
@@ -28,9 +28,20 @@
#include <unistd.h>
#include "parameters.h"
+#include "options.h"
#include "gold-threads.h"
#include "descriptors.h"
+// Very old systems may not define FD_CLOEXEC.
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+
+// O_CLOEXEC is only available on newer systems.
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
namespace gold
{
@@ -87,6 +98,10 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode)
while (true)
{
+ // We always want to set the close-on-exec flag; we don't
+ // require callers to pass it.
+ flags |= O_CLOEXEC;
+
int new_descriptor = ::open(name, flags, mode);
if (new_descriptor < 0
&& errno != ENFILE
@@ -109,24 +124,35 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode)
if (new_descriptor >= 0)
{
- Hold_optional_lock hl(this->lock_);
-
- if (static_cast<size_t>(new_descriptor)
- >= this->open_descriptors_.size())
- this->open_descriptors_.resize(new_descriptor + 64);
-
- Open_descriptor* pod = &this->open_descriptors_[new_descriptor];
- pod->name = name;
- pod->stack_next = -1;
- pod->inuse = true;
- pod->is_write = (flags & O_ACCMODE) != O_RDONLY;
- pod->is_on_stack = false;
-
- ++this->current_;
- if (this->current_ >= this->limit_)
- this->close_some_descriptor();
-
- return new_descriptor;
+ // If we have any plugins, we really do need to set the
+ // close-on-exec flag, even if O_CLOEXEC is not defined.
+ // FIXME: In some cases O_CLOEXEC may be defined in the
+ // header file but not supported by the kernel.
+ // Unfortunately there doesn't seem to be any obvious way to
+ // detect that, as unknown flags passed to open are ignored.
+ if (O_CLOEXEC == 0 && parameters->options().has_plugins())
+ fcntl(new_descriptor, F_SETFD, FD_CLOEXEC);
+
+ {
+ Hold_optional_lock hl(this->lock_);
+
+ if (static_cast<size_t>(new_descriptor)
+ >= this->open_descriptors_.size())
+ this->open_descriptors_.resize(new_descriptor + 64);
+
+ Open_descriptor* pod = &this->open_descriptors_[new_descriptor];
+ pod->name = name;
+ pod->stack_next = -1;
+ pod->inuse = true;
+ pod->is_write = (flags & O_ACCMODE) != O_RDONLY;
+ pod->is_on_stack = false;
+
+ ++this->current_;
+ if (this->current_ >= this->limit_)
+ this->close_some_descriptor();
+
+ return new_descriptor;
+ }
}
// We ran out of file descriptors.