X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fdescriptors.cc;h=53d24c5c51c0caff5114fbfcd8b575018b9115cf;hb=452f10a186cdb18091f590315c55488b871812e3;hp=3d059e2c222ed79a02157d282d9a2d70d4ddce55;hpb=7f055c204a4371154123a1816fbec9855ee60ad5;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/descriptors.cc b/gold/descriptors.cc index 3d059e2c22..53d24c5c51 100644 --- a/gold/descriptors.cc +++ b/gold/descriptors.cc @@ -1,6 +1,6 @@ // descriptors.cc -- manage file descriptors for gold -// Copyright 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2008-2020 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -23,24 +23,37 @@ #include "gold.h" #include +#include #include #include +#include #include +#include "debug.h" #include "parameters.h" #include "options.h" #include "gold-threads.h" #include "descriptors.h" +#include "binary-io.h" + +// O_CLOEXEC is only available on newer systems. +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif // 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 +static inline void +set_close_on_exec(int fd ATTRIBUTE_UNUSED) +{ +// Mingw does not define F_SETFD. +#ifdef F_SETFD + fcntl(fd, F_SETFD, FD_CLOEXEC); #endif +} namespace gold { @@ -70,6 +83,9 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) gold_assert(lock_initialized || descriptor < 0); + if (is_debugging_enabled(DEBUG_FILES)) + this->limit_ = 8; + if (descriptor >= 0) { Hold_lock hl(*this->lock_); @@ -88,6 +104,8 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) pod->stack_next = -1; pod->is_on_stack = false; } + gold_debug(DEBUG_FILES, "Reused existing descriptor %d for \"%s\"", + descriptor, name); return descriptor; } } @@ -98,6 +116,9 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) // require callers to pass it. flags |= O_CLOEXEC; + // Always open the file as a binary file. + flags |= O_BINARY; + int new_descriptor = ::open(name, flags, mode); if (new_descriptor < 0 && errno != ENFILE @@ -108,13 +129,14 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) { Hold_lock hl(*this->lock_); - gold_error(_("file %s was removed during the link"), - this->open_descriptors_[descriptor].name); + gold_error(_("file %s was removed during the link"), name); } errno = ENOENT; } + gold_debug(DEBUG_FILES, "Opened new descriptor %d for \"%s\"", + new_descriptor, name); return new_descriptor; } @@ -129,7 +151,7 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) if (O_CLOEXEC == 0 && parameters->options_valid() && parameters->options().has_plugins()) - fcntl(new_descriptor, F_SETFD, FD_CLOEXEC); + set_close_on_exec(new_descriptor); { Hold_optional_lock hl(this->lock_); @@ -149,6 +171,8 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) if (this->current_ >= this->limit_) this->close_some_descriptor(); + gold_debug(DEBUG_FILES, "Opened new descriptor %d for \"%s\"", + new_descriptor, name); return new_descriptor; } } @@ -196,6 +220,9 @@ Descriptors::release(int descriptor, bool permanent) pod->is_on_stack = true; } } + + gold_debug(DEBUG_FILES, "Released descriptor %d for \"%s\"", + descriptor, pod->name); } // Close some descriptor. The lock is held when this is called. We @@ -220,6 +247,8 @@ Descriptors::close_some_descriptor() if (::close(i) < 0) gold_warning(_("while closing %s: %s"), pod->name, strerror(errno)); --this->current_; + gold_debug(DEBUG_FILES, "Closed descriptor %d for \"%s\"", + i, pod->name); pod->name = NULL; if (last < 0) this->stack_top_ = pod->stack_next; @@ -238,6 +267,30 @@ Descriptors::close_some_descriptor() return false; } +// Close all the descriptors open for reading. + +void +Descriptors::close_all() +{ + Hold_optional_lock hl(this->lock_); + + for (size_t i = 0; i < this->open_descriptors_.size(); i++) + { + Open_descriptor* pod = &this->open_descriptors_[i]; + if (pod->name != NULL && !pod->inuse && !pod->is_write) + { + if (::close(i) < 0) + gold_warning(_("while closing %s: %s"), pod->name, strerror(errno)); + gold_debug(DEBUG_FILES, "Closed descriptor %d for \"%s\" (close_all)", + static_cast(i), pod->name); + pod->name = NULL; + pod->stack_next = -1; + pod->is_on_stack = false; + } + } + this->stack_top_ = -1; +} + // The single global variable which manages descriptors. Descriptors descriptors;