62 lines
2.3 KiB
C++
62 lines
2.3 KiB
C++
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* FileDescriptor.hpp :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: acossari <acossari@student.codam.nl> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2026/08/24 16:24:03 by acossari #+# #+# */
|
|
/* Updated: 2026/08/24 20:05:59 by acossari ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#pragma once
|
|
|
|
#include <exception>
|
|
#include <string>
|
|
|
|
namespace webserv {
|
|
|
|
// Sole owner of one file descriptor, move-only. Copying would give two owners
|
|
// the same number, and the second close would land on whatever the kernel had
|
|
// handed out in the meantime, killing an unrelated connection.
|
|
class FileDescriptor final {
|
|
public:
|
|
class Error : public std::exception {
|
|
public:
|
|
explicit Error(std::string message);
|
|
const char* what() const noexcept override;
|
|
|
|
private:
|
|
std::string msg_;
|
|
};
|
|
|
|
FileDescriptor() = default;
|
|
|
|
// Takes ownership and sets FD_CLOEXEC, so a successful execve() in a
|
|
// forked child closes the descriptor before the new program starts. A
|
|
// negative fd is accepted and gives an invalid object instead of throwing,
|
|
// so the result of socket() can be passed in and checked with valid().
|
|
explicit FileDescriptor(int fd);
|
|
|
|
~FileDescriptor();
|
|
|
|
FileDescriptor(const FileDescriptor&) = delete;
|
|
FileDescriptor& operator=(const FileDescriptor&) = delete;
|
|
FileDescriptor(FileDescriptor&& other) noexcept;
|
|
FileDescriptor& operator=(FileDescriptor&& other) noexcept;
|
|
|
|
int get() const noexcept { return fd_; }
|
|
bool valid() const noexcept { return fd_ >= 0; }
|
|
|
|
void setNonBlocking();
|
|
|
|
// Closes now instead of at destruction. Idempotent.
|
|
void reset() noexcept;
|
|
|
|
private:
|
|
int fd_ = -1;
|
|
};
|
|
|
|
} // namespace webserv
|