// SPDX-License-Identifier: 0BSD


#pragma once


#include <cstdio>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utility>


namespace vore::file {
	namespace {
		class fd {
		public:
			constexpr fd() noexcept = default;
			fd(const char * path, int flags, mode_t mode = 0, int from = AT_FDCWD) noexcept {
				while((this->desc = openat(from, path, flags, mode)) == -1 && errno == EINTR)
					;
				this->opened = this->desc != -1;
			}
			fd(int desc) noexcept : desc(desc), opened(true) {}

			fd(const fd &) = delete;
			fd(fd && oth) noexcept { *this = std::move(oth); }

			fd & operator=(fd && oth) noexcept {
				this->swap(oth);
				return *this;
			}

			~fd() {
				if(this->opened)
					close(this->desc);
			}

			constexpr operator int() const noexcept { return this->desc; }

			void swap(fd & oth) noexcept {
				std::swap(this->desc, oth.desc);
				std::swap(this->opened, oth.opened);
			}

		private:
			int desc    = -1;
			bool opened = false;
		};
	}
}
