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 committed: Add file descriptor cache


PR 5990 is about the fact that gold never actually closes any file
descriptors.  I committed this patch to add a file descriptor cache.
Now if a call to open fails with EMFILE or ENFILE, gold will back off
on the number of open descriptors.  It should now work correctly,
albeit less efficiently, as long as it can five or so descriptors
open.

Ian


	PR 5990
	* descriptors.cc: New file.
	* descriptors.h: New file.
	* gold-threads.h (class Hold_optional_lock): New class.
	* fileread.cc: Include "descriptors.h".
	(File_read::~File_read): Release descriptor rather than closing
	it.
	(File_read::open) [file]: Call open_descriptor rather than open.
	Set is_descriptor_opened_.
	(File_read::open) [memory]: Assert that descriptor is not open.
	(File_read::reopen_descriptor): New function.
	(File_read::release): Release descriptor.
	(File_read::do_read): Make non-const.  Reopen descriptor.
	(File_read::read): Make non-const.
	(File_read::make_view): Reopen descriptor.
	(File_read::do_readv): Likewise.
	* fileread.h (class File_read): Add is_descriptor_opened_ field.
	Update declarations.
	* layout.cc: Include "descriptors.h".
	(Layout::create_build_id): Use open_descriptor rather than open.
	* output.cc: Include "descriptors.h".
	(Output_file::open): Use open_descriptor rather than open.
	* archive.cc (Archive::const_iterator): Change Archive to be
	non-const.
	(Archive::begin, Archive::end): Make non-const.
	(Archive::count_members): Likewise.
	* archive.h (class Archive): Update declarations.
	* object.h (Object::read): Make non-const.
	* Makefile.am (CCFILES): Add descriptors.cc.
	(HFILES): Add descriptors.h.
	* Makefile.in: Rebuild.


Index: Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/Makefile.am,v
retrieving revision 1.40
diff -u -p -r1.40 Makefile.am
--- Makefile.am	22 Jul 2008 22:08:43 -0000	1.40
+++ Makefile.am	25 Jul 2008 04:20:23 -0000
@@ -36,6 +36,7 @@ CCFILES = \
 	copy-relocs.cc \
 	cref.cc \
 	defstd.cc \
+	descriptors.cc \
 	dirsearch.cc \
 	dynobj.cc \
 	dwarf_reader.cc \
@@ -74,6 +75,7 @@ HFILES = \
 	cref.h \
 	defstd.h \
 	dirsearch.h \
+	descriptors.h \
 	dynobj.h \
 	dwarf_reader.h \
 	ehframe.h \
Index: archive.cc
===================================================================
RCS file: /cvs/src/src/gold/archive.cc,v
retrieving revision 1.33
diff -u -p -r1.33 archive.cc
--- archive.cc	22 Jul 2008 22:08:43 -0000	1.33
+++ archive.cc	25 Jul 2008 04:20:23 -0000
@@ -384,7 +384,7 @@ class Archive::const_iterator
     off_t size;
   };
 
-  const_iterator(const Archive* archive, off_t off)
+  const_iterator(Archive* archive, off_t off)
     : archive_(archive), off_(off)
   { this->read_next_header(); }
 
@@ -431,7 +431,7 @@ class Archive::const_iterator
   read_next_header();
 
   // The underlying archive.
-  const Archive* archive_;
+  Archive* archive_;
   // The current offset in the file.
   off_t off_;
   // The current archive header.
@@ -481,7 +481,7 @@ Archive::const_iterator::read_next_heade
 // Initial iterator.
 
 Archive::const_iterator
-Archive::begin() const
+Archive::begin()
 {
   return Archive::const_iterator(this, sarmag);
 }
@@ -489,7 +489,7 @@ Archive::begin() const
 // Final iterator.
 
 Archive::const_iterator
-Archive::end() const
+Archive::end()
 {
   return Archive::const_iterator(this, this->input_file_->file().filesize());
 }
@@ -515,7 +515,7 @@ Archive::include_all_members(Symbol_tabl
 // reports.
 
 size_t
-Archive::count_members() const
+Archive::count_members()
 {
   size_t ret = 0;
   for (Archive::const_iterator p = this->begin();
Index: archive.h
===================================================================
RCS file: /cvs/src/src/gold/archive.h,v
retrieving revision 1.21
diff -u -p -r1.21 archive.h
--- archive.h	22 Jul 2008 22:08:43 -0000	1.21
+++ archive.h	25 Jul 2008 04:20:23 -0000
@@ -133,7 +133,7 @@ class Archive
 
   // Return the number of members in the archive.
   size_t
-  count_members() const;
+  count_members();
 
  private:
   Archive(const Archive&);
@@ -175,10 +175,10 @@ class Archive
   class const_iterator;
 
   const_iterator
-  begin() const;
+  begin();
 
   const_iterator
-  end() const;
+  end();
 
   friend class const_iterator;
 
Index: descriptors.cc
===================================================================
RCS file: descriptors.cc
diff -N descriptors.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ descriptors.cc	25 Jul 2008 04:20:23 -0000
@@ -0,0 +1,211 @@
+// descriptors.cc -- manage file descriptors for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+#include "gold.h"
+
+#include <cerrno>
+#include <cstring>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parameters.h"
+#include "gold-threads.h"
+#include "descriptors.h"
+
+namespace gold
+{
+
+// Class Descriptors.
+
+// The default for limit_ is meant to simply be large.  It gets
+// adjusted downward if we run out of file descriptors.
+
+Descriptors::Descriptors()
+  : lock_(NULL), open_descriptors_(), stack_top_(-1), current_(0),
+    limit_(8192 - 16)
+{
+  this->open_descriptors_.reserve(128);
+}
+
+// Open a file.
+
+int
+Descriptors::open(int descriptor, const char* name, int flags, int mode)
+{
+  // We don't initialize this until we are called, because we can't
+  // initialize a Lock until we have parsed the options to find out
+  // whether we are running with threads.  We can be called before
+  // options are valid when reading a linker script.
+  if (this->lock_ == NULL)
+    {
+      if (parameters->options_valid())
+	this->lock_ = new Lock();
+      else
+	gold_assert(descriptor < 0);
+    }
+
+  if (descriptor >= 0)
+    {
+      Hold_lock hl(*this->lock_);
+
+      gold_assert(static_cast<size_t>(descriptor)
+		  < this->open_descriptors_.size());
+      Open_descriptor* pod = &this->open_descriptors_[descriptor];
+      if (pod->name == name
+	  || (pod->name != NULL && strcmp(pod->name, name) == 0))
+	{
+	  gold_assert(!pod->inuse);
+	  pod->inuse = true;
+	  return descriptor;
+	}
+    }
+
+  while (true)
+    {
+      int new_descriptor = ::open(name, flags, mode);
+      if (new_descriptor < 0
+	  && errno != ENFILE
+	  && errno != EMFILE)
+	{
+	  if (descriptor >= 0 && errno == ENOENT)
+	    {
+	      {
+		Hold_lock hl(*this->lock_);
+
+		gold_error(_("file %s was removed during the link"),
+			   this->open_descriptors_[descriptor].name);
+	      }
+
+	      errno = ENOENT;
+	    }
+
+	  return new_descriptor;
+	}
+
+      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;
+
+	  ++this->current_;
+	  if (this->current_ >= this->limit_)
+	    this->close_some_descriptor();
+
+	  return new_descriptor;
+	}
+
+      // We ran out of file descriptors.
+      {
+	Hold_optional_lock hl(this->lock_);
+
+	this->limit_ = this->current_ - 16;
+	if (this->limit_ < 8)
+	  this->limit_ = 8;
+	if (!this->close_some_descriptor())
+	  gold_fatal(_("out of file descriptors and couldn't close any"));
+      }
+    }
+}
+
+// Release a descriptor.
+
+void
+Descriptors::release(int descriptor, bool permanent)
+{
+  Hold_optional_lock hl(this->lock_);
+
+  gold_assert(descriptor >= 0
+	      && (static_cast<size_t>(descriptor)
+		  < this->open_descriptors_.size()));
+  Open_descriptor* pod = &this->open_descriptors_[descriptor];
+
+  if (permanent
+      || (this->current_ > this->limit_ && !pod->is_write))
+    {
+      if (::close(descriptor) < 0)
+	gold_warning(_("while closing %s: %s"), pod->name, strerror(errno));
+      pod->name = NULL;
+      --this->current_;
+    }
+  else
+    {
+      pod->inuse = false;
+      if (!pod->is_write)
+	{
+	  pod->stack_next = this->stack_top_;
+	  this->stack_top_ = descriptor;
+	}
+    }
+}
+
+// Close some descriptor.  The lock is held when this is called.  We
+// close the descriptor on the top of the free stack.  Note that this
+// is the opposite of an LRU algorithm--we close the most recently
+// used descriptor.  That is because the linker tends to cycle through
+// all the files; after we release a file, we are unlikely to need it
+// again until we have looked at all the other files.  Return true if
+// we closed a descriptor.
+
+bool
+Descriptors::close_some_descriptor()
+{
+  int last = -1;
+  int i = this->stack_top_;
+  while (i >= 0)
+    {
+      gold_assert(static_cast<size_t>(i) < this->open_descriptors_.size());
+      Open_descriptor* pod = &this->open_descriptors_[i];
+      if (!pod->inuse && !pod->is_write)
+	{
+	  if (::close(i) < 0)
+	    gold_warning(_("while closing %s: %s"), pod->name, strerror(errno));
+	  --this->current_;
+	  pod->name = NULL;
+	  if (last < 0)
+	    this->stack_top_ = pod->stack_next;
+	  else
+	    this->open_descriptors_[last].stack_next = pod->stack_next;
+	  return true;
+	}
+      last = i;
+      i = pod->stack_next;
+    }
+
+  // We couldn't find any descriptors to close.  This is weird but not
+  // necessarily an error.
+  return false;
+}
+
+// The single global variable which manages descriptors.
+
+Descriptors descriptors;
+
+} // End namespace gold.
Index: descriptors.h
===================================================================
RCS file: descriptors.h
diff -N descriptors.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ descriptors.h	25 Jul 2008 04:20:23 -0000
@@ -0,0 +1,105 @@
+// descriptors.h -- manage file descriptors for gold   -*- C++ -*-
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+#ifndef GOLD_DESCRIPTORS_H
+#define GOLD_DESCRIPTORS_H
+
+#include <vector>
+
+namespace gold
+{
+
+class Lock;
+
+// This class manages file descriptors for gold.
+
+class Descriptors
+{
+ public:
+  Descriptors();
+
+  // Get a file descriptor for a file.  The DESCRIPTOR parameter is
+  // the descriptor the last time the file was used; this will be -1
+  // if this is the first time the file is being opened.  The NAME,
+  // FLAGS, and MODE parameters are as for ::open.  NAME must be in
+  // permanent storage.  This returns the descriptor to use, which may
+  // or may not be the same as DESCRIPTOR.  If there is an error
+  // opening the file, this will return -1 with errno set
+  // appropriately.
+  int
+  open(int descriptor, const char* name, int flags, int mode = 0);
+
+  // Release the file descriptor DESCRIPTOR.  If PERMANENT is true, it
+  // will be closed, and the caller may not reopen it.  If PERMANENT
+  // is false this doesn't necessarily close the descriptor, but it
+  // makes it available to be closed; the descriptor must not be used
+  // again except as an argument to Descriptor::open.
+  void
+  release(int descriptor, bool permanent);
+
+ private:
+  // Information kept for a descriptor.
+  struct Open_descriptor
+  {
+    // File name currently associated with descriptor.  This is empty
+    // if none.
+    const char* name;
+    // Index of next descriptor on stack of released descriptors.
+    int stack_next;
+    // Whether the descriptor is currently in use.
+    bool inuse;
+    // Whether this is a write descriptor.
+    bool is_write;
+  };
+
+  bool
+  close_some_descriptor();
+
+  // We need to lock before accessing any fields.
+  Lock* lock_;
+  // Information for descriptors.
+  std::vector<Open_descriptor> open_descriptors_;
+  // Top of stack.
+  int stack_top_;
+  // The current number of file descriptors open.
+  int current_;
+  // The maximum number of file descriptors we open.
+  int limit_;
+};
+
+// File descriptors are a centralized data structure, and we use a
+// global variable rather than passing the data structure into every
+// routine that does file I/O.
+
+extern Descriptors descriptors;
+
+inline int
+open_descriptor(int descriptor, const char* name, int flags, int mode = 0)
+{ return descriptors.open(descriptor, name, flags, mode); }
+
+inline void
+release_descriptor(int descriptor, bool permanent)
+{ descriptors.release(descriptor, permanent); }
+
+} // End namespace gold.
+
+#endif // !defined(GOLD_DESCRIPTORS_H)
Index: fileread.cc
===================================================================
RCS file: /cvs/src/src/gold/fileread.cc,v
retrieving revision 1.41
diff -u -p -r1.41 fileread.cc
--- fileread.cc	25 Jun 2008 17:10:08 -0000	1.41
+++ fileread.cc	25 Jul 2008 04:20:23 -0000
@@ -36,6 +36,7 @@
 #include "dirsearch.h"
 #include "target.h"
 #include "binary.h"
+#include "descriptors.h"
 #include "fileread.h"
 
 namespace gold
@@ -83,18 +84,14 @@ unsigned long long File_read::total_mapp
 unsigned long long File_read::current_mapped_bytes;
 unsigned long long File_read::maximum_mapped_bytes;
 
-// The File_read class is designed to support file descriptor caching,
-// but this is not currently implemented.
-
 File_read::~File_read()
 {
   gold_assert(this->token_.is_writable());
-  if (this->descriptor_ >= 0)
+  if (this->is_descriptor_opened_)
     {
-      if (close(this->descriptor_) < 0)
-	gold_warning(_("close of %s failed: %s"),
-		     this->name_.c_str(), strerror(errno));
+      release_descriptor(this->descriptor_, true);
       this->descriptor_ = -1;
+      this->is_descriptor_opened_ = false;
     }
   this->name_.clear();
   this->clear_views(true);
@@ -107,13 +104,16 @@ File_read::open(const Task* task, const 
 {
   gold_assert(this->token_.is_writable()
 	      && this->descriptor_ < 0
+	      && !this->is_descriptor_opened_
 	      && this->name_.empty());
   this->name_ = name;
 
-  this->descriptor_ = ::open(this->name_.c_str(), O_RDONLY);
+  this->descriptor_ = open_descriptor(-1, this->name_.c_str(),
+				      O_RDONLY);
 
   if (this->descriptor_ >= 0)
     {
+      this->is_descriptor_opened_ = true;
       struct stat s;
       if (::fstat(this->descriptor_, &s) < 0)
 	gold_error(_("%s: fstat failed: %s"),
@@ -136,6 +136,7 @@ File_read::open(const Task* task, const 
 {
   gold_assert(this->token_.is_writable()
 	      && this->descriptor_ < 0
+	      && !this->is_descriptor_opened_
 	      && this->name_.empty());
   this->name_ = name;
   this->contents_ = contents;
@@ -144,6 +145,22 @@ File_read::open(const Task* task, const 
   return true;
 }
 
+// Reopen a descriptor if necessary.
+
+void
+File_read::reopen_descriptor()
+{
+  if (!this->is_descriptor_opened_)
+    {
+      this->descriptor_ = open_descriptor(this->descriptor_,
+					  this->name_.c_str(),
+					  O_RDONLY);
+      if (this->descriptor_ < 0)
+	gold_fatal(_("could not reopen file %s"), this->name_.c_str());
+      this->is_descriptor_opened_ = true;
+    }
+}
+
 // Release the file.  This is called when we are done with the file in
 // a Task.
 
@@ -159,9 +176,17 @@ File_read::release()
     File_read::maximum_mapped_bytes = File_read::current_mapped_bytes;
 
   // Only clear views if there is only one attached object.  Otherwise
-  // we waste time trying to clear cached archive views.
+  // we waste time trying to clear cached archive views.  Similarly
+  // for releasing the descriptor.
   if (this->object_count_ <= 1)
-    this->clear_views(false);
+    {
+      this->clear_views(false);
+      if (this->is_descriptor_opened_)
+	{
+	  release_descriptor(this->descriptor_, false);
+	  this->is_descriptor_opened_ = false;
+	}
+    }
 
   this->released_ = true;
 }
@@ -243,7 +268,7 @@ File_read::find_view(off_t start, sectio
 // the buffer at P.
 
 void
-File_read::do_read(off_t start, section_size_type size, void* p) const
+File_read::do_read(off_t start, section_size_type size, void* p)
 {
   ssize_t bytes;
   if (this->contents_ != NULL)
@@ -257,6 +282,7 @@ File_read::do_read(off_t start, section_
     }
   else
     {
+      this->reopen_descriptor();
       bytes = ::pread(this->descriptor_, p, size, start);
       if (static_cast<section_size_type>(bytes) == size)
 	return;
@@ -279,7 +305,7 @@ File_read::do_read(off_t start, section_
 // Read data from the file.
 
 void
-File_read::read(off_t start, section_size_type size, void* p) const
+File_read::read(off_t start, section_size_type size, void* p)
 {
   const File_read::View* pv = this->find_view(start, size, -1U, NULL);
   if (pv != NULL)
@@ -349,6 +375,7 @@ File_read::make_view(off_t start, sectio
     }
   else
     {
+      this->reopen_descriptor();
       void* p = ::mmap(NULL, psize, PROT_READ, MAP_PRIVATE,
                        this->descriptor_, poff);
       if (p == MAP_FAILED)
@@ -493,6 +520,8 @@ File_read::do_readv(off_t base, const Re
       last_offset = i_entry.file_offset + i_entry.size;
     }
 
+  this->reopen_descriptor();
+
   gold_assert(iov_index < sizeof iov / sizeof iov[0]);
 
   if (::lseek(this->descriptor_, base + first_offset, SEEK_SET) < 0)
Index: fileread.h
===================================================================
RCS file: /cvs/src/src/gold/fileread.h,v
retrieving revision 1.29
diff -u -p -r1.29 fileread.h
--- fileread.h	2 Apr 2008 20:58:21 -0000	1.29
+++ fileread.h	25 Jul 2008 04:20:23 -0000
@@ -40,17 +40,16 @@ class Input_file_argument;
 class Dirsearch;
 class File_view;
 
-// File_read manages a file descriptor for a file we are reading.  We
-// close file descriptors if we run out of them, so this class reopens
-// the file as needed.
+// File_read manages a file descriptor and mappings for a file we are
+// reading.
 
 class File_read
 {
  public:
   File_read()
-    : name_(), descriptor_(-1), object_count_(0), size_(0), token_(false),
-      views_(), saved_views_(), contents_(NULL), mapped_bytes_(0),
-      released_(true)
+    : name_(), descriptor_(-1), is_descriptor_opened_(false), object_count_(0),
+      size_(0), token_(false), views_(), saved_views_(), contents_(NULL),
+      mapped_bytes_(0), released_(true)
   { }
 
   ~File_read();
@@ -82,12 +81,12 @@ class File_read
   { --this->object_count_; }
 
   // Lock the file for exclusive access within a particular Task::run
-  // execution.  This means that the descriptor can not be closed.
-  // This routine may only be called when the workqueue lock is held.
+  // execution.  This routine may only be called when the workqueue
+  // lock is held.
   void
   lock(const Task* t);
 
-  // Unlock the descriptor, permitting it to be closed if necessary.
+  // Unlock the file.
   void
   unlock(const Task* t);
 
@@ -133,7 +132,7 @@ class File_read
   // Read data from the file into the buffer P starting at file offset
   // START for SIZE bytes.
   void
-  read(off_t start, section_size_type size, void* p) const;
+  read(off_t start, section_size_type size, void* p);
 
   // Return a lasting view into the file starting at file offset START
   // for SIZE bytes.  This is allocated with new, and the caller is
@@ -296,6 +295,10 @@ class File_read
   // A simple list of Views.
   typedef std::list<View*> Saved_views;
 
+  // Open the descriptor if necessary.
+  void
+  reopen_descriptor();
+
   // Find a view into the file.
   View*
   find_view(off_t start, section_size_type size, unsigned int byteshift,
@@ -303,7 +306,7 @@ class File_read
 
   // Read data from the file into a buffer.
   void
-  do_read(off_t start, section_size_type size, void* p) const;
+  do_read(off_t start, section_size_type size, void* p);
 
   // Add a view.
   void
@@ -347,6 +350,8 @@ class File_read
   std::string name_;
   // File descriptor.
   int descriptor_;
+  // Whether we have regained the descriptor after releasing the file.
+  bool is_descriptor_opened_;
   // The number of objects associated with this file.  This will be
   // more than 1 in the case of an archive.
   int object_count_;
Index: gold-threads.h
===================================================================
RCS file: /cvs/src/src/gold/gold-threads.h,v
retrieving revision 1.4
diff -u -p -r1.4 gold-threads.h
--- gold-threads.h	13 Mar 2008 21:04:21 -0000	1.4
+++ gold-threads.h	25 Jul 2008 04:20:23 -0000
@@ -107,6 +107,29 @@ class Hold_lock
   Lock& lock_;
 };
 
+class Hold_optional_lock
+{
+ public:
+  Hold_optional_lock(Lock* lock)
+    : lock_(lock)
+  {
+    if (this->lock_ != NULL)
+      this->lock_->acquire();
+  }
+
+  ~Hold_optional_lock()
+  {
+    if (this->lock_ != NULL)
+      this->lock_->release();
+  }
+
+ private:
+  Hold_optional_lock(const Hold_optional_lock&);
+  Hold_optional_lock& operator=(const Hold_optional_lock&);
+
+  Lock* lock_;
+};
+
 // The interface for the implementation of a condition variable.
 
 class Condvar_impl
Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.110
diff -u -p -r1.110 layout.cc
--- layout.cc	22 Jul 2008 23:55:24 -0000	1.110
+++ layout.cc	25 Jul 2008 04:20:24 -0000
@@ -45,6 +45,7 @@
 #include "compressed_output.h"
 #include "reduced_debug_output.h"
 #include "reloc.h"
+#include "descriptors.h"
 #include "layout.h"
 
 namespace gold
@@ -1507,14 +1508,14 @@ Layout::create_build_id()
       char buffer[uuidsz];
       memset(buffer, 0, uuidsz);
 
-      int descriptor = ::open("/dev/urandom", O_RDONLY);
+      int descriptor = open_descriptor(-1, "/dev/urandom", O_RDONLY);
       if (descriptor < 0)
 	gold_error(_("--build-id=uuid failed: could not open /dev/urandom: %s"),
 		   strerror(errno));
       else
 	{
 	  ssize_t got = ::read(descriptor, buffer, uuidsz);
-	  ::close(descriptor);
+	  release_descriptor(descriptor, true);
 	  if (got < 0)
 	    gold_error(_("/dev/urandom: read failed: %s"), strerror(errno));
 	  else if (static_cast<size_t>(got) != uuidsz)
Index: object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.63
diff -u -p -r1.63 object.h
--- object.h	24 Jul 2008 01:24:50 -0000	1.63
+++ object.h	25 Jul 2008 04:20:24 -0000
@@ -410,7 +410,7 @@ class Object
 
   // Read data from the underlying file.
   void
-  read(off_t start, section_size_type size, void* p) const
+  read(off_t start, section_size_type size, void* p)
   { this->input_file()->file().read(start + this->offset_, size, p); }
 
   // Read multiple data from the underlying file.
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.81
diff -u -p -r1.81 output.cc
--- output.cc	22 Jul 2008 08:09:48 -0000	1.81
+++ output.cc	25 Jul 2008 04:20:24 -0000
@@ -37,6 +37,7 @@
 #include "symtab.h"
 #include "reloc.h"
 #include "merge.h"
+#include "descriptors.h"
 #include "output.h"
 
 // Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS
@@ -3321,7 +3322,8 @@ Output_file::open(off_t file_size)
 	    unlink_if_ordinary(this->name_);
 
 	  int mode = parameters->options().relocatable() ? 0666 : 0777;
-	  int o = ::open(this->name_, O_RDWR | O_CREAT | O_TRUNC, mode);
+	  int o = open_descriptor(-1, this->name_, O_RDWR | O_CREAT | O_TRUNC,
+				  mode);
 	  if (o < 0)
 	    gold_fatal(_("%s: open: %s"), this->name_, strerror(errno));
 	  this->o_ = o;

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