0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::fs: Add basic fd wrapper object.

This commit is contained in:
Jason Volk 2018-05-30 01:38:20 -07:00
parent 73fc596cb6
commit 955d8921b9
3 changed files with 167 additions and 0 deletions

51
include/ircd/fs/fd.h Normal file
View file

@ -0,0 +1,51 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_FS_FD_H
namespace ircd::fs
{
struct fd;
}
/// Object for maintaining state to an open file or directory. Instances can
/// be used with various functions around ircd::fs.
struct ircd::fs::fd
{
struct opts;
int fdno{-1};
public:
operator const int &() const
{
return fdno;
}
fd(const string_view &path, const opts &);
fd(const string_view &path);
fd() = default;
fd(fd &&) noexcept;
fd(const fd &) = delete;
fd &operator=(fd &&) noexcept;
fd &operator=(const fd &) = delete;
~fd() noexcept(false);
};
struct ircd::fs::fd::opts
{
ulong flags {0};
ulong mask {0};
bool ate {false};
opts(const std::ios::open_mode &);
opts() = default;
};

View file

@ -91,6 +91,7 @@ namespace ircd::fs
extern aio *aioctx;
}
#include "fd.h"
#include "read.h"
#include "write.h"
#include "stdin.h"

View file

@ -260,6 +260,121 @@ ircd::fs::write__std(const string_view &path,
return buf;
}
///////////////////////////////////////////////////////////////////////////////
//
// fs/fd.h
//
// TODO: x-platform
//
namespace ircd::fs
{
thread_local char path_buf[2048];
static const char *path_str(const string_view &);
static uint posix_flags(const std::ios::open_mode &mode);
}
uint
ircd::fs::posix_flags(const std::ios::open_mode &mode)
{
static const auto rdwr
{
std::ios::in | std::ios::out
};
uint ret{0};
if((mode & rdwr) == rdwr)
ret |= O_RDWR;
else if(mode & std::ios::out)
ret |= O_WRONLY;
else
ret |= O_RDONLY;
ret |= mode & std::ios::trunc? O_TRUNC : 0;
ret |= mode & std::ios::app? O_APPEND : 0;
ret |= ret & O_WRONLY? O_CREAT : 0;
ret |= ret & O_RDWR && ret & (O_TRUNC | O_APPEND)? O_CREAT : 0;
return ret;
}
const char *
ircd::fs::path_str(const string_view &s)
{
return data(strlcpy(path_buf, s));
}
//
// fd::opts
//
ircd::fs::fd::opts::opts(const std::ios::open_mode &mode)
:flags
{
posix_flags(mode)
| O_CLOEXEC
}
,mask
{
flags & O_CREAT?
S_IRUSR | S_IWUSR:
0U
}
,ate
{
bool(mode & std::ios::ate)
}
{
}
//
// fd::fd
//
ircd::fs::fd::fd(const string_view &path)
:fd{path, opts{}}
{
}
ircd::fs::fd::fd(const string_view &path,
const opts &opts)
:fdno
{
int(syscall(::open, path_str(path), int(opts.flags), mode_t(opts.mask)))
}
{
if(opts.ate)
syscall(::lseek, fdno, 0, SEEK_END);
}
ircd::fs::fd::fd(fd &&o)
noexcept
:fdno
{
std::move(o.fdno)
}
{
o.fdno = -1;
}
ircd::fs::fd &
ircd::fs::fd::operator=(fd &&o)
noexcept
{
this->~fd();
fdno = std::move(o.fdno);
o.fdno = -1;
return *this;
}
ircd::fs::fd::~fd()
noexcept(false)
{
if(fdno < 0)
return;
syscall(::close, fdno);
}
///////////////////////////////////////////////////////////////////////////////
//
// fs.h / misc