From e85b18e10cf468cdbac014e960c9e36b071057ab Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 17 Mar 2009 17:09:44 +0000 Subject: [PATCH] * 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. --- gold/ChangeLog | 6 +++++ gold/descriptors.cc | 62 ++++++++++++++++++++++++++++++++------------- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 7af69c49855..9425ea6e60e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,11 @@ 2009-03-17 Ian Lance Taylor + * 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 862edae7fb3..6937741841f 100644 --- a/gold/descriptors.cc +++ b/gold/descriptors.cc @@ -28,9 +28,20 @@ #include #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(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(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. -- 2.30.2