blob: 9a7986ee7a17ded15a0104e987d7590f404e673a [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "files/public/c/lib/fd_table.h"
#include <errno.h>
#include <limits>
#include <utility>
#include "files/public/c/lib/errno_impl.h"
#include "mojo/public/cpp/environment/logging.h"
namespace mojio {
FDTable::FDTable(ErrnoImpl* errno_impl, size_t max_num_fds)
: errno_impl_(errno_impl), table_(max_num_fds) {
MOJO_DCHECK(max_num_fds > 0);
// The index of the last FD has to fit into an |int|.
MOJO_DCHECK(max_num_fds - 1 <=
static_cast<size_t>(std::numeric_limits<int>::max()));
}
FDTable::~FDTable() {
// TODO(vtl): Warn if there are still non-null entries?
}
int FDTable::Add(std::unique_ptr<FDImpl> fd_impl) {
ErrnoImpl::Setter errno_setter(errno_impl_);
MOJO_DCHECK(fd_impl);
for (size_t i = 0; i < table_.size(); i++) {
if (!table_[i]) {
table_[i] = std::move(fd_impl);
return static_cast<int>(i);
}
}
errno_setter.Set(EMFILE);
return -1;
}
FDImpl* FDTable::Get(int fd) const {
ErrnoImpl::Setter errno_setter(errno_impl_);
if (fd < 0 || static_cast<size_t>(fd) >= table_.size() || !table_[fd]) {
errno_setter.Set(EBADF);
return nullptr;
}
return table_[fd].get();
}
std::unique_ptr<FDImpl> FDTable::Remove(int fd) {
ErrnoImpl::Setter errno_setter(errno_impl_);
if (fd < 0 || static_cast<size_t>(fd) >= table_.size() || !table_[fd]) {
errno_setter.Set(EBADF);
return nullptr;
}
return std::move(table_[fd]);
}
} // namespace mojio