// descriptors.cc -- manage file descriptors for gold

// Copyright 2008, 2009, 2010, 2011 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 <cstdio>
#include <cstring>
#include <fcntl.h>
#include <unistd.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

static inline void
set_close_on_exec(int fd)
{
// Mingw does not define F_SETFD.
#ifdef F_SETFD
  fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
}

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), initialize_lock_(&this->lock_), 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.
  bool lock_initialized = this->initialize_lock_.initialize();

  gold_assert(lock_initialized || 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;
	  if (descriptor == this->stack_top_)
	    {
	      this->stack_top_ = pod->stack_next;
	      pod->stack_next = -1;
	      pod->is_on_stack = false;
	    }
	  return descriptor;
	}
    }

  while (true)
    {
      // We always want to set the close-on-exec flag; we don't
      // 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
	  && errno != EMFILE)
	{
	  if (descriptor >= 0 && errno == ENOENT)
	    {
	      {
		Hold_lock hl(*this->lock_);

		gold_error(_("file %s was removed during the link"), name);
	      }

	      errno = ENOENT;
	    }

	  return new_descriptor;
	}

      if (new_descriptor >= 0)
	{
	  // 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_valid()
	      && parameters->options().has_plugins())
	    set_close_on_exec(new_descriptor);

	  {
	    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.
      {
	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->is_on_stack)
	{
	  pod->stack_next = this->stack_top_;
	  this->stack_top_ = descriptor;
	  pod->is_on_stack = true;
	}
    }
}

// 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;
	  pod->stack_next = -1;
	  pod->is_on_stack = false;
	  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.
