mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd::util: Move syscall() templates out of util; minor reorg includes.
ircd::sys: Add abstract sysfs tool and template from fs::dev.
This commit is contained in:
parent
d9bfdc9678
commit
eb00134100
6 changed files with 236 additions and 42 deletions
|
@ -56,11 +56,8 @@
|
|||
#include "time.h"
|
||||
#include "logger.h"
|
||||
#include "info.h"
|
||||
#include "nacl.h"
|
||||
#include "rand.h"
|
||||
#include "crh.h"
|
||||
#include "ed25519.h"
|
||||
#include "color.h"
|
||||
#include "lex_cast.h"
|
||||
#include "base.h"
|
||||
#include "stringops.h"
|
||||
|
@ -72,9 +69,12 @@
|
|||
#include "iov.h"
|
||||
#include "grammar.h"
|
||||
#include "parse.h"
|
||||
#include "color.h"
|
||||
#include "rfc1459.h"
|
||||
#include "json/json.h"
|
||||
#include "cbor/cbor.h"
|
||||
#include "nacl.h"
|
||||
#include "ed25519.h"
|
||||
#include "openssl.h"
|
||||
#include "pbc.h"
|
||||
#include "fmt.h"
|
||||
|
@ -83,6 +83,7 @@
|
|||
#include "conf.h"
|
||||
#include "magic.h"
|
||||
#include "stats.h"
|
||||
#include "sys.h"
|
||||
#include "prof/prof.h"
|
||||
#include "fs/fs.h"
|
||||
#include "ios.h"
|
||||
|
|
168
include/ircd/sys.h
Normal file
168
include/ircd/sys.h
Normal file
|
@ -0,0 +1,168 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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_SYS_H
|
||||
|
||||
namespace ircd::sys
|
||||
{
|
||||
enum call :uint;
|
||||
|
||||
template<enum call = (enum call)0,
|
||||
class function,
|
||||
class... args>
|
||||
long call(function&&, args&&...);
|
||||
|
||||
template<long number,
|
||||
enum call = (enum call)0,
|
||||
class... args>
|
||||
long call(args&&... a);
|
||||
|
||||
// sysfs read to buffer
|
||||
string_view get(const mutable_buffer &out, const string_view &path);
|
||||
|
||||
// sysfs read cast to type or defaults
|
||||
template<class R = size_t,
|
||||
size_t bufmax = 32>
|
||||
R get(const string_view &path, const R &def = 0);
|
||||
|
||||
extern log::log log;
|
||||
}
|
||||
|
||||
/// System call template options; changes behaviors.
|
||||
enum ircd::sys::call
|
||||
:uint
|
||||
{
|
||||
NOTHROW = 0x01,
|
||||
UNINTERRUPTIBLE = 0x02,
|
||||
};
|
||||
|
||||
/// Return a lex_cast'able (an integer) from a sysfs target.
|
||||
template<class T,
|
||||
size_t bufmax>
|
||||
inline T
|
||||
ircd::sys::get(const string_view &path,
|
||||
const T &def)
|
||||
{
|
||||
char buf[bufmax];
|
||||
const string_view val
|
||||
{
|
||||
get(buf, path)
|
||||
};
|
||||
|
||||
return lex_castable<T>(val)?
|
||||
lex_cast<T>(val):
|
||||
def;
|
||||
}
|
||||
|
||||
/// This template requires a system call number in the parameters. The
|
||||
/// arguments are only the actual arguments passed to the syscall because
|
||||
/// the number is given in the template.
|
||||
///
|
||||
template<long number,
|
||||
enum ircd::sys::call opts,
|
||||
class... args>
|
||||
inline long
|
||||
ircd::sys::call(args&&... a)
|
||||
{
|
||||
return call<opts>(::syscall, number, std::forward<args>(a)...);
|
||||
}
|
||||
|
||||
/// Posix system call template to check for returned error value and throw the
|
||||
/// approps errno in the proper std::system_error exception. Note the usage
|
||||
/// here, the libc wrapper function is the first argument i.e:
|
||||
/// syscall(::foo, bar, baz) not syscall(::foo(bar, baz));
|
||||
///
|
||||
/// when uninterruptible posix system call template; the syscall is
|
||||
/// restarted until it no longer returns with EINTR.
|
||||
///
|
||||
template<enum ircd::sys::call opts,
|
||||
class function,
|
||||
class... args>
|
||||
inline long
|
||||
ircd::sys::call(function&& f,
|
||||
args&&... a)
|
||||
{
|
||||
constexpr auto uninterruptible
|
||||
{
|
||||
opts & call::UNINTERRUPTIBLE
|
||||
};
|
||||
|
||||
long ret; do
|
||||
{
|
||||
ret = f(std::forward<args>(a)...);
|
||||
}
|
||||
while(unlikely(uninterruptible && ret == -1 && errno == EINTR));
|
||||
|
||||
constexpr auto nothrow
|
||||
{
|
||||
opts & call::NOTHROW
|
||||
};
|
||||
|
||||
if(unlikely(!nothrow && ret == -1L))
|
||||
throw std::system_error
|
||||
{
|
||||
errno, std::system_category()
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Legacy convenience forwarder interface
|
||||
//
|
||||
namespace ircd {
|
||||
|
||||
template<class function,
|
||||
class... args>
|
||||
inline auto
|
||||
syscall(function&& f,
|
||||
args&&... a)
|
||||
{
|
||||
return sys::call(std::forward<function>(f), std::forward<args>(a)...);
|
||||
}
|
||||
|
||||
template<long number,
|
||||
class... args>
|
||||
inline auto
|
||||
syscall(args&&... a)
|
||||
{
|
||||
return sys::call<number>(std::forward<args>(a)...);
|
||||
}
|
||||
|
||||
template<class function,
|
||||
class... args>
|
||||
inline auto
|
||||
syscall_nointr(function&& f,
|
||||
args&&... a)
|
||||
{
|
||||
constexpr enum sys::call opts
|
||||
{
|
||||
sys::call::UNINTERRUPTIBLE
|
||||
};
|
||||
|
||||
return sys::call<opts>(std::forward<function>(f), std::forward<args>(a)...);
|
||||
}
|
||||
|
||||
template<long number,
|
||||
class... args>
|
||||
inline auto
|
||||
syscall_nointr(args&&... a)
|
||||
{
|
||||
constexpr enum sys::call opts
|
||||
{
|
||||
sys::call::UNINTERRUPTIBLE
|
||||
};
|
||||
|
||||
return sys::call<number, opts>(std::forward<args>(a)...);
|
||||
}
|
||||
|
||||
} // namespace ircd
|
|
@ -39,7 +39,6 @@ namespace ircd
|
|||
#include "reentrance.h"
|
||||
#include "enum.h"
|
||||
#include "custom_ptr.h"
|
||||
#include "syscall.h"
|
||||
#include "env.h"
|
||||
#include "va_rtti.h"
|
||||
#include "unique_iterator.h"
|
||||
|
|
|
@ -169,6 +169,7 @@ endif
|
|||
if IOU
|
||||
libircd_la_SOURCES += fs_iou.cc
|
||||
endif
|
||||
libircd_la_SOURCES += sys.cc
|
||||
libircd_la_SOURCES += mods.cc
|
||||
if LINUX
|
||||
libircd_la_SOURCES += mods_ldso.cc
|
||||
|
|
|
@ -60,51 +60,16 @@ ircd::string_view
|
|||
ircd::fs::dev::sysfs(const mutable_buffer &out,
|
||||
const ulong &id,
|
||||
const string_view &relpath)
|
||||
try
|
||||
{
|
||||
thread_local char path_buf[1024];
|
||||
const string_view path{fmt::sprintf
|
||||
{
|
||||
path_scratch, "%s/%s/%s",
|
||||
blk::BASE_PATH,
|
||||
path_buf, "dev/block/%s/%s",
|
||||
sysfs_id(name_scratch, id),
|
||||
relpath
|
||||
}};
|
||||
|
||||
fs::fd::opts fdopts;
|
||||
fdopts.errlog = false;
|
||||
const fs::fd fd
|
||||
{
|
||||
path, fdopts
|
||||
};
|
||||
|
||||
fs::read_opts ropts;
|
||||
ropts.aio = false;
|
||||
string_view ret
|
||||
{
|
||||
fs::read(fd, out, ropts)
|
||||
};
|
||||
|
||||
ret = rstrip(ret, '\n');
|
||||
ret = rstrip(ret, ' ');
|
||||
return ret;
|
||||
}
|
||||
catch(const ctx::interrupted &)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
#if 0
|
||||
log::derror
|
||||
{
|
||||
log, "sysfs query dev_id:%lu `%s' :%s",
|
||||
id,
|
||||
relpath,
|
||||
e.what(),
|
||||
};
|
||||
#endif
|
||||
|
||||
return {};
|
||||
return sys::get(out, path);
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
|
|
60
ircd/sys.cc
Normal file
60
ircd/sys.cc
Normal file
|
@ -0,0 +1,60 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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.
|
||||
|
||||
decltype(ircd::sys::log)
|
||||
ircd::sys::log
|
||||
{
|
||||
"sys"
|
||||
};
|
||||
|
||||
ircd::string_view
|
||||
ircd::sys::get(const mutable_buffer &out,
|
||||
const string_view &relpath)
|
||||
try
|
||||
{
|
||||
thread_local char buf[1024];
|
||||
string_view path(relpath);
|
||||
path = lstrip(relpath, "/sys/"_sv); // tolerate any errant /sys/ prefix
|
||||
path = strlcpy(buf, "/sys/"_sv);
|
||||
path = strlcat(buf, relpath);
|
||||
|
||||
fs::fd::opts fdopts;
|
||||
fdopts.errlog = false;
|
||||
const fs::fd fd
|
||||
{
|
||||
path, fdopts
|
||||
};
|
||||
|
||||
string_view ret
|
||||
{
|
||||
data(out), sys::call(::read, fd, data(out), size(out))
|
||||
};
|
||||
|
||||
ret = rstrip(ret, '\n');
|
||||
ret = rstrip(ret, ' ');
|
||||
return ret;
|
||||
}
|
||||
catch(const ctx::interrupted &)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
#if 0
|
||||
log::derror
|
||||
{
|
||||
log, "sysfs query `%s' :%s",
|
||||
relpath,
|
||||
e.what(),
|
||||
};
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
Loading…
Reference in a new issue