<commit_before>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed in accordance with the terms specified in
 *  the LICENSE file found in the root directory of this source tree.
 */

#pragma once

#include <osquery/utils/expected/expected.h>

#include <linux/bpf.h>

namespace osquery {
namespace ebpf {

enum class MapError {
  Unknown = 1,
  NoSuchKey = 2,
};

namespace impl {
/**
 * Do not use implementation functions directly, use Map class to create and
 * manage eBPF map
 */
Expected<int, MapError> mapCreate(enum bpf_map_type map_type,
                                  std::size_t key_size,
                                  std::size_t value_size,
                                  std::size_t max_entries);
ExpectedSuccess<MapError> mapUpdateElement(int fd,
                                           void const* key,
                                           void const* value,
                                           unsigned long long flags);
ExpectedSuccess<MapError> mapLookupElement(int fd,
                                           void const* key,
                                           void* value);
ExpectedSuccess<MapError> mapDeleteElement(int fd, void const* key);

} // namespace impl

/**
 * Proxy object for the eBPF map structure in kernel.
 */

template <typename KeyType, typename ValueType, enum bpf_map_type map_type>
class Map final {
 private:
  static_assert(
      std::is_pod<KeyType>::value && std::is_pod<ValueType>::value,
      "Both key type and value type must be a plain old data type (POD)");

  /**
   * The only constructor of Map is private for purpose. Use createMap function
   * instead. Map should not be created in case of creating eBPF map failure.
   */
  explicit Map(int fd, std::size_t size) : fd_(fd), size_(size) {}

 public:
  ~Map() {
    if (fd_ >= 0) {
      close(fd_);
    }
  }

  Map(Map const&) = delete;

  Map(Map && from) : fd_(from.fd_), size_(from.size_) {
    from.fd_ = -1;
  }

  Map& operator=(Map const&) = delete;

  Map& operator=(Map&& from) {
    if (fd_ >= 0) {
      close(fd_);
      fd_ = -1;
    }
    std::swap(fd_, from.fd_);
    std::swap(size_, from.size_);
  }

  Expected<ValueType, MapError> lookupElement(KeyType const& key) const {
    auto value = ValueType{};
    auto exp = impl::mapLookupElement(
        fd_, static_cast<void const*>(&key), static_cast<void*>(&value));
    if (exp.isError()) {
      return exp.takeError();
    }
    return value;
  }
<commit_msg>BPF/Map: Add missing return value in move assignment operator (#5874)<commit_after>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed in accordance with the terms specified in
 *  the LICENSE file found in the root directory of this source tree.
 */

#pragma once

#include <osquery/utils/expected/expected.h>

#include <linux/bpf.h>

namespace osquery {
namespace ebpf {

enum class MapError {
  Unknown = 1,
  NoSuchKey = 2,
};

namespace impl {
/**
 * Do not use implementation functions directly, use Map class to create and
 * manage eBPF map
 */
Expected<int, MapError> mapCreate(enum bpf_map_type map_type,
                                  std::size_t key_size,
                                  std::size_t value_size,
                                  std::size_t max_entries);
ExpectedSuccess<MapError> mapUpdateElement(int fd,
                                           void const* key,
                                           void const* value,
                                           unsigned long long flags);
ExpectedSuccess<MapError> mapLookupElement(int fd,
                                           void const* key,
                                           void* value);
ExpectedSuccess<MapError> mapDeleteElement(int fd, void const* key);

} // namespace impl

/**
 * Proxy object for the eBPF map structure in kernel.
 */

template <typename KeyType, typename ValueType, enum bpf_map_type map_type>
class Map final {
 private:
  static_assert(
      std::is_pod<KeyType>::value && std::is_pod<ValueType>::value,
      "Both key type and value type must be a plain old data type (POD)");

  /**
   * The only constructor of Map is private for purpose. Use createMap function
   * instead. Map should not be created in case of creating eBPF map failure.
   */
  explicit Map(int fd, std::size_t size) : fd_(fd), size_(size) {}

 public:
  ~Map() {
    if (fd_ >= 0) {
      close(fd_);
    }
  }

  Map(Map const&) = delete;

  Map(Map && from) : fd_(from.fd_), size_(from.size_) {
    from.fd_ = -1;
  }

  Map& operator=(Map const&) = delete;

  Map& operator=(Map&& from) {
    if (fd_ >= 0) {
      close(fd_);
      fd_ = -1;
    }
    std::swap(fd_, from.fd_);
    std::swap(size_, from.size_);

    return *this;
  }

  Expected<ValueType, MapError> lookupElement(KeyType const& key) const {
    auto value = ValueType{};
    auto exp = impl::mapLookupElement(
        fd_, static_cast<void const*>(&key), static_cast<void*>(&value));
    if (exp.isError()) {
      return exp.takeError();
    }
    return value;
  }

{'fraction_non_alphanumeric': 0.10886862022123035, 'fraction_numerical': 0.004657481078983117, 'mean_word_length': 2.1893564356435644, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3731257', 'n_tokens_mistral': 1517, 'n_tokens_neox': 1464, 'n_words': 473}