aboutsummaryrefslogtreecommitdiff
path: root/gold/descriptors.cc
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 /gold/descriptors.cc
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.
Diffstat (limited to 'gold/descriptors.cc')
-rw-r--r--gold/descriptors.cc62
1 files changed, 44 insertions, 18 deletions
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.