summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGELOG.txt16
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.html4
-rw-r--r--dux-demo/ctest.c6
-rw-r--r--dux-demo/main.cc32
-rw-r--r--dux/CMakeLists.txt7
-rw-r--r--dux/include-priv/dux/cxx/priv.hh9
-rw-r--r--dux/include-priv/dux/priv.h6
-rw-r--r--dux/include/dux/arr6
-rw-r--r--dux/include/dux/arr.h81
-rw-r--r--dux/include/dux/base.h14
-rw-r--r--dux/include/dux/c/arr.h18
-rw-r--r--dux/include/dux/c/base.h5
-rw-r--r--dux/include/dux/c/sig.h2
-rw-r--r--dux/include/dux/cxx/arr.hh96
-rw-r--r--dux/include/dux/cxx/base.hh73
-rw-r--r--dux/include/dux/cxx/io.hh58
-rw-r--r--dux/include/dux/cxx/math.hh26
-rw-r--r--dux/include/dux/cxx/seq.hh2
-rw-r--r--dux/include/dux/cxx/sig.hh2
-rw-r--r--dux/include/dux/io.h13
-rw-r--r--dux/include/dux/sig.h2
-rw-r--r--dux/src/abrt.cc4
-rw-r--r--dux/src/crtfile.cc67
-rw-r--r--dux/src/exit.cc2
-rw-r--r--dux/src/file.cc197
-rw-r--r--dux/src/free.cc2
-rw-r--r--dux/src/getenv.cc4
-rw-r--r--dux/src/memeq.cc36
-rw-r--r--dux/src/onexit.cc8
-rw-r--r--dux/src/priv/dbgunreach.c2
-rw-r--r--dux/src/priv/posix/fsync.c34
-rw-r--r--dux/src/priv/posix/openat.c7
-rw-r--r--dux/src/priv/posix/read.c34
-rw-r--r--dux/src/priv/posix/sigaction.c2
-rw-r--r--dux/src/priv/start.cc14
-rw-r--r--dux/src/raise.cc4
-rw-r--r--dux/src/realloc.cc2
-rw-r--r--dux/src/setsighandl.cc12
-rw-r--r--dux/src/sleep.cc6
-rw-r--r--update-checklist.txt2
42 files changed, 719 insertions, 201 deletions
diff --git a/.gitignore b/.gitignore
index 785bf99..c7672b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/build
+/dux-io-demo
vgcore.* \ No newline at end of file
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 42912bc..bd3cbd2 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,19 @@
+| 2↊
+
+- Update the homepage-URL in CMake and the homepage link in the readme;
+- Add I/O modules for file manipulation;
+- Simplify debug logs and align them;
+- Remove error code noimpl;
+- Revert "Make more compile-time objects be internally-linked" from dux-28 as now GCC complains;
+- Split module group arr into C and C++ sections like the others;
+- Add module memeq for comparing memory regions;
+- Implement POSIX functions dux.priv.posix.fsync, dux.priv.posix.read;
+- Update gitignore;
+- Update update-checklist;
+- Rename error code badio to ioerr;
+
+NOTE: dux.pipe.read currently fails on FreeBSD
+
| 29
- Add homepage-URL to CMake;
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fd68ee4..0013a2c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,7 @@ project(
# Constants:
set(
DUX_VERSION
- 33
+ 34
)
# Subdirectories
diff --git a/README.html b/README.html
index a8afe7c..cc3a7cb 100644
--- a/README.html
+++ b/README.html
@@ -2,7 +2,7 @@
<html>
<h1>dux</h1>
<h3><a href="https://discord.gg/UshkEdZPdM">Discord Server</a></h3>
- <p><i><a href="https://mandelbrot.dk/dux">dux</a></i> is a free, open-source, and semi-portable general-purpose library for the C and C++ programming languages.</p>
+ <p><i><a href="https://mandelbrot.dk/dux/about">dux</a></i> is a free, open-source, and semi-portable general-purpose library for the C and C++ programming languages.</p>
<p>The main purpose of dux is to implement a clean, morden and featureful library.</p>
<o>Our primary goal is to implement this almost completely ourselves and with as few dependencies as possible. Therefore, dux may not be (and is currently not) as portable as many other libraries, with the currently supported platforms being:</p>
<ul>
@@ -29,5 +29,5 @@
<p>This file is part of <i>dux</i>.</p>
<p><i>dux</i> is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</p>
<p><i>dux</i> is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.</p>
- <p>You should have received a copy of the GNU Affero General Public License along with <i>dux</i>. If not, see <a href="https://www.gnu.org/licenses">https://www.gnu.org/licenses</a>.</p>
+ <p>You should have received a copy of the GNU Affero General Public License along with <i>dux</i>. If not, see <a href="http://www.gnu.org/licenses">https://www.gnu.org/licenses</a>.</p>
</html>
diff --git a/dux-demo/ctest.c b/dux-demo/ctest.c
index 8869c00..7b67510 100644
--- a/dux-demo/ctest.c
+++ b/dux-demo/ctest.c
@@ -19,9 +19,9 @@ static bool dux_local_sighandl(enum dux_sig const _sig) {
}
void ctest(void const * const restrict _params) {
- dux_dbglog("dux :: demo :: Performing C-tests!\n");
- if (dux_getnummainparams(_params) == dux_uwrdl(0x0)) {dux_dbglog("dux :: demo :: No parameters!\n");}
- else {for (dux_uwrd n = dux_uwrdl(0x0);n < dux_getnummainparams(_params);++n) {dux_dbglog("dux :: demo :: Parameter %zu: %s\n",n + dux_uwrdl(0x1),dux_getmainparam(_params,n));}}
+ dux_dbglog("dux.demo :: Performing C-tests!\n");
+ if (dux_getnummainparams(_params) == dux_uwrdl(0x0)) {dux_dbglog("dux.demo :: No parameters!\n");}
+ else {for (dux_uwrd n = dux_uwrdl(0x0);n < dux_getnummainparams(_params);++n) {dux_dbglog("dux.demo :: Parameter %zu: %s\n",n + dux_uwrdl(0x1),dux_getmainparam(_params,n));}}
{
dux_setsighandl(dux_sig_intr,dux_local_sighandl);
dux_raise(dux_sig_intr);
diff --git a/dux-demo/main.cc b/dux-demo/main.cc
index c67d5de..94768ba 100644
--- a/dux-demo/main.cc
+++ b/dux-demo/main.cc
@@ -47,7 +47,7 @@ static_assert([] {
static_assert(chk(::dux::sig::io, SIGIO));
static_assert(chk(::dux::sig::intr, SIGINT));
static_assert(chk(::dux::sig::kill, SIGKILL));
- static_assert(chk(::dux::sig::pipe, SIGPIPE));
+ static_assert(chk(::dux::sig::file, SIGPIPE));
static_assert(chk(::dux::sig::prof, SIGPROF));
static_assert(chk(::dux::sig::quit, SIGQUIT));
static_assert(chk(::dux::sig::segv, SIGSEGV));
@@ -77,20 +77,20 @@ static_assert([] {
extern "C" auto ctest(void const * params) -> void;
extern "C" auto dux_main(::dux::mainparams const * const restrict _params) -> ::dux::stat {
- if (_params->num() == dux_uwrdl(0x0)) {::dux::dbglog("dux :: demo :: No parameters!\n");}
- else {for (auto n {dux_uwrdl(0x0)};n < _params->num();++n) {::dux::dbglog("dux :: demo :: Parameter #%zu: %s\n",n + dux_uwrdl(0x1),_params->param(n).ptr);}}
+ if (_params->num() == dux_uwrdl(0x0)) {::dux::dbglog("dux.demo :: No parameters!\n");}
+ else {for (auto n {dux_uwrdl(0x0)};n < _params->num();++n) {::dux::dbglog("dux.demo :: Parameter #%zu: %s\n",n + dux_uwrdl(0x1),_params->param(n).ptr);}}
{
constexpr auto estim {dux_uint64l(0x100)};
- ::dux::dbglog("Trying to roll two identical 8-bit numbers in a row. Estimated number of tries: " dux_printfuint64 ".\n",estim);
+ ::dux::dbglog("dux.demo :: Trying to roll two identical 8-bit numbers in a row. Estimated number of tries: " dux_printfuint64 ".\n",estim);
auto num0 {::dux::rnd<::dux::uint8>()};
auto num1 {::dux::rnd<::dux::uint8>()};
for (auto n = dux_uint64l(0x1);;++n) {
if (num0 == num1) [[unlikely]] {
- ::dux::dbglog("Done! Took " dux_printfuint64 " attempts (estimated: " dux_printfuint64 ") to roll the same 8-bit number (" dux_printfuint8 ") two times in a row.\n",n,estim,num0);
- ::dux::dbglog("Odds: %f%%",((double)n / (double)estim) * (double)100.0);
+ ::dux::dbglog("dux.demo :: Done! Took " dux_printfuint64 " attempts (estimated: " dux_printfuint64 ") to roll the same 8-bit number (" dux_printfuint8 ") two times in a row.\n",n,estim,num0);
+ ::dux::dbglog("dux.demo :: Odds: %f%%",((double)n / (double)estim) * (double)100.0);
if (n == dux_uint64l(0x45)) {::dux::dbglog(" - Nice!");} /* 69 */
else if (n == dux_uint64l(0x1)) {::dux::dbglog(" - bruh");}
- ::dux::dbglog("\n\nContinuing to the testing stage...\n\n");
+ ::dux::dbglog("\n");
goto test;
}
num0 = ::dux::rnd<::dux::uint8>();
@@ -99,7 +99,7 @@ extern "C" auto dux_main(::dux::mainparams const * const restrict _params) -> ::
}
test:;
auto const time = ::dux::gettime();
- ::dux::dbglog("Current time: " dux_printfsint64 "\n",time);
+ ::dux::dbglog("dux.demo :: Current time: " dux_printfsint64 "\n",time);
dux_ass("",time >= dux_sint64l(0x5C10DFA4));
{
::dux::reseterr();
@@ -156,7 +156,7 @@ test:;
}
{
::dux::seterr(::dux::errcd::test);
- dux_ass("Testing if the test error was set",::dux::geterr() >::dux::errcd::noerr);
+ dux_ass("Error setter didn't work!",::dux::geterr() >::dux::errcd::noerr);
::dux::reseterr();
}
{
@@ -205,15 +205,25 @@ test:;
dux_ass("",arr[dux_uwrdl(0x6)] == false);
dux_ass("",arr[dux_uwrdl(0x7)] == true);
}
+ {
+ dux_ass("",::dux::memeq("ABC",dux_uwrdl(0x3),"ABC"));
+ auto file {::dux::crtfile("dux-io-demo")};
+ file.write("Hello there!");
+ file.open("dux-io-demo",::dux::iotyp::r);
+ auto const dat {file.read(dux_uwrdl(0xC))};
+ dux_ass("",dat.sz() == dux_uwrdl(0xC));
+ dux_ass("",::dux::memeq(dat.craw(),dat.sz(),"Hello there!"));
+ file.close();
+ }
if (::dux::haserr()) [[unlikely]] {
- ::dux::dbglog("dux :: \x1B[91mdemo\x1B[0m :: Got error %S!\n",::dux::errcdnm(::dux::geterr()));
+ ::dux::dbglog("dux.\x1B[91mdemo\x1B[0m :: Got error %S!\n",::dux::errcdnm(::dux::geterr()));
::dux::exit(::dux::stat::err);
}
::ctest(_params);
::dux::onexit([](::dux::stat) {
::dux::onexit([](::dux::stat) {});
dux_ass("",::dux::haserr());
- ::dux::dbglog("dux :: demo :: All tests passed!\n");
+ ::dux::dbglog("dux.demo :: All tests passed!\n");
});
::dux::exit(::dux::stat::ok);
}
diff --git a/dux/CMakeLists.txt b/dux/CMakeLists.txt
index 332980f..e4ceb10 100644
--- a/dux/CMakeLists.txt
+++ b/dux/CMakeLists.txt
@@ -27,7 +27,7 @@ project(
DESCRIPTION
"General purpose library."
HOMEPAGE_URL
- "https://mandelbrot.dk/dux"
+ "https://mandelbrot.dk/dux/about/"
LANGUAGES
C
CXX
@@ -42,12 +42,14 @@ add_library(
SHARED
"src/priv/posix/clock_gettime.c"
"src/priv/posix/close.c"
+ "src/priv/posix/fsync.c"
"src/priv/posix/getpid.c"
"src/priv/posix/getrandom.c"
"src/priv/posix/kill.c"
"src/priv/posix/mmap.c"
"src/priv/posix/nanosleep.c"
"src/priv/posix/openat.c"
+ "src/priv/posix/read.c"
"src/priv/posix/sigaction.c"
"src/priv/posix/write.c"
"src/priv/alloc.cc"
@@ -67,8 +69,10 @@ add_library(
"src/priv/syscall.S"
"src/abrt.cc"
"src/alloc.cc"
+ "src/crtfile.cc"
"src/errcdnm.cc"
"src/exit.cc"
+ "src/file.cc"
"src/fndchr.cc"
"src/free.cc"
"src/freernd.cc"
@@ -79,6 +83,7 @@ add_library(
"src/gettime.cc"
"src/ismainthrd.cc"
"src/mainparams.cc"
+ "src/memeq.cc"
"src/onexit.cc"
"src/raise.cc"
"src/realloc.cc"
diff --git a/dux/include-priv/dux/cxx/priv.hh b/dux/include-priv/dux/cxx/priv.hh
index 177369d..3e48839 100644
--- a/dux/include-priv/dux/cxx/priv.hh
+++ b/dux/include-priv/dux/cxx/priv.hh
@@ -21,6 +21,15 @@
# include <csetjmp>
namespace dux::priv {
+ class filesysdat {
+ public:
+# if defined(dux_os_posix)
+ int fd;
+# endif
+ };
+}
+
+namespace dux::priv {
inline ::std::jmp_buf exitjmp;
inline ::dux::stat volatile exitstat;
diff --git a/dux/include-priv/dux/priv.h b/dux/include-priv/dux/priv.h
index 4214e56..02f1364 100644
--- a/dux/include-priv/dux/priv.h
+++ b/dux/include-priv/dux/priv.h
@@ -17,6 +17,7 @@
along with dux. If not, see <https://www.gnu.org/licenses/>.
*/
+# include <fcntl.h>
# include <signal.h>
# include <sys/mman.h>
# include <sys/types.h>
@@ -32,9 +33,10 @@ int dux_priv_posix_clock_gettime(clockid_t clockid,struct times
pid_t dux_priv_posix_getpid( void);
pid_t dux_priv_posix_gettid( void);
int dux_priv_posix_kill( pid_t pid, int sig);
-void * dux_priv_posix_mmap( void * addr, dux_priv_uwrd length,int prot, int flags,int fd,off_t offset);
+void * dux_priv_posix_mmap( void * addr, dux_priv_uwrd length, int prot, int flags,int fd,off_t offset);
int dux_priv_posix_nanosleep( struct timespec const * req, struct timespec * rem);
-int dux_priv_posix_sigaction( int signum, struct sigaction const * act, struct sigaction * oldact);
+int dux_priv_posix_openat( int fd, char const * pathname,int flags, mode_t mode);
+int dux_priv_posix_sigaction( int signum, struct sigaction const * act, struct sigaction * oldact);
int dux_priv_start(int argc,char const * const * argv);
diff --git a/dux/include/dux/arr b/dux/include/dux/arr
index 307cb9c..5ebe2de 100644
--- a/dux/include/dux/arr
+++ b/dux/include/dux/arr
@@ -22,3 +22,9 @@
# include <dux/mem>
# include <dux/arr.h>
+
+# if defined(dux_lang_c)
+# include <dux/c/arr.h>
+# elif defined(dux_lang_cxx)
+# include <dux/cxx/arr.hh>
+# endif
diff --git a/dux/include/dux/arr.h b/dux/include/dux/arr.h
index 66bf351..86f5c17 100644
--- a/dux/include/dux/arr.h
+++ b/dux/include/dux/arr.h
@@ -16,84 +16,3 @@
You should have received a copy of the GNU Affero General Public License
along with dux. If not, see <https://www.gnu.org/licenses/>.
*/
-
-# if defined(dux_lang_cxx)
-
-namespace dux {
- template<typename T> class arr {
- public:
- [[nodiscard]] constexpr arr() noexcept : _isalloc(false) {}
- [[nodiscard]] constexpr arr(::dux::arr<T> && _oth) noexcept : _dat(_oth._dat), _isalloc(_oth._isalloc),_sz(_oth._sz) {_oth.kill();}
- [[nodiscard]] constexpr arr(T * const restrict _dat, ::dux::uwrd const _sz,bool const _isalloc = false) noexcept : _dat(_dat), _isalloc(_isalloc), _sz(_sz) {}
- template<::dux::uwrd N> [[nodiscard]] constexpr arr(T const (& _arr)[N]) noexcept : _dat(const_cast<char *>(_arr)),_isalloc(false), _sz(N) {}
-
- constexpr auto operator = (::dux::arr<T> const & _oth) noexcept -> ::dux::arr<T> const & {
- if (_oth._isalloc) {
- this->alloc(_oth.sz());
- ::dux::cpy(_oth.dat(),_oth.sz(),this->dat());
- }
- else {this->setraw(_oth._dat,_oth._sz,_oth._isalloc);}
- return *this;
- }
-
- constexpr auto operator = (::dux::arr<T> const && _oth) noexcept -> ::dux::arr<T> const & {
- this->setraw(_oth.alloc,_oth._dat,_oth._sz);
- _oth._isalloc = false; /* Mutable field. */
- return *this;
- }
-
- constexpr ~arr() noexcept {if (this->_isalloc) {::dux::free(this->_dat);}}
-
- constexpr auto dat() noexcept -> T * {return this->_dat;}
- constexpr auto dat() const noexcept -> T const * {return this->_dat;}
- constexpr auto sz() const noexcept -> ::dux::uwrd {return this->_sz;}
-
- constexpr auto begin() noexcept -> T * {return this->dat();}
- constexpr auto begin() const noexcept -> T const * {return this->dat();}
- constexpr auto end() noexcept -> T * {return this->dat() + this->sz();}
- constexpr auto end() const noexcept -> T const * {return this->dat() + this->sz();}
- constexpr auto cbegin() const noexcept -> T const * {return this->begin();}
- constexpr auto cend() const noexcept -> T const * {return this->end();}
-
- constexpr auto operator [] (::dux::uwrd const _n) noexcept -> T & {return this->_dat[_n];}
- constexpr auto operator [] (::dux::uwrd const _n) const noexcept -> T const & {return this->_dat[_n];}
-
- constexpr auto setraw(T * const restrict _dat,::dux::uwrd const _sz,bool const _isalloc = false) noexcept -> void {
- this->_isalloc = _isalloc;
- this->_dat = _dat;
- this->_sz = _sz;
- }
- constexpr auto setraw(T const * const restrict _dat,::dux::uwrd const _sz) noexcept -> void {
- this->_isalloc = false;
- this->_dat = const_cast<T *>(_dat);
- this->_sz = _sz;
- }
-
- constexpr auto kill() noexcept -> void {
- this->_dat = nullptr;
- this->_isalloc = false;
- }
-
- constexpr auto alloc(::dux::uwrd const _sz) noexcept -> void {
- this->_dat = ::dux::alloc<T>(_sz);
- if (::dux::haserr()) [[unlikely]] {
- this->_isalloc = false;
- return;
- }
- this->_isalloc = true;
- this->_sz = _sz;
- }
- constexpr auto free() noexcept -> void {
- if (!this->_isalloc) [[unlikely]] {return;}
- ::dux::free(this->_dat);
- this->_isalloc = false;
- this->_sz = dux_uwrdl(0x0);
- }
- private:
- T * _dat;
- bool mutable _isalloc;
- ::dux::uwrd _sz;
- };
-}
-
-# endif
diff --git a/dux/include/dux/base.h b/dux/include/dux/base.h
index 21c2bfe..59e8f31 100644
--- a/dux/include/dux/base.h
+++ b/dux/include/dux/base.h
@@ -68,7 +68,7 @@
# endif
# endif
-# define dux_priv_ver 0x21
+# define dux_priv_ver 0x22
# if !defined(dux_dbg)
# if defined(_DEBUG) || !defined(NDEBUG)
@@ -463,9 +463,8 @@ enum dux_priv_errcd {
dux_priv_errcd_badacs, /* Bad access: Access denied */
dux_priv_errcd_badaddr, /* Bad address: Addres was out of bounds or invalid */
dux_priv_errcd_badalloc, /* Bad allocation: Memory allocation failed */
- dux_priv_errcd_badio, /* Bad input/output: Unable to read or write to pipe */
dux_priv_errcd_badperms, /* Bad permissions: Operation was not permitted */
- dux_priv_errcd_badpipe, /* Bad pipe: Pipe was not valid */
+ dux_priv_errcd_badfile, /* Bad file: Pipe was not valid */
dux_priv_errcd_badseq, /* Bad sequence: Memory sequence is illegal */
dux_priv_errcd_badstr, /* Bad string: String was invalid */
dux_priv_errcd_badutf, /* Bad UTF: UTF codepoint was illegal */
@@ -473,10 +472,10 @@ enum dux_priv_errcd {
dux_priv_errcd_illcallseq, /* Illegal call sequence: Function was called in an illegal order */
dux_priv_errcd_illparam, /* Illegal parameter: Provided parameter was not valid */
dux_priv_errcd_illsz, /* Illegal size: Size was illegal */
+ dux_priv_errcd_ioerr, /* Bad input/output: Unable to read or write to file */
dux_priv_errcd_matherr, /* Mathematical error: Mathematical operation(s) could not be performed */
dux_priv_errcd_nodir, /* No directory: Directory does not exist */
dux_priv_errcd_nofile, /* No file: File does not exist */
- dux_priv_errcd_noimpl, /* No implementaton: The function is not implemented on the target platform */
dux_priv_errcd_nospc, /* No space: Destination is out of available space */
dux_priv_errcd_outofrange, /* Out of range: Provided value is out of range */
dux_priv_errcd_runerr, /* Runtime error: An unpredictable error occured */
@@ -501,9 +500,10 @@ dux_attr_hot dux_priv_uwrd dux_priv_syscall(dux_priv_uwrd syscallid,...);
/* POSIX functions we implement ourselves. If the function uses a non-fundamental type, we put it in the private header. */
int dux_priv_posix_close( int fildes);
-dux_priv_swrd dux_priv_posix_write( int fildes, void const * buf, dux_priv_uwrd nbyte);
-dux_priv_swrd dux_priv_posix_getrandom(void * buf, dux_priv_uwrd buflen, unsigned int flags);
-int dux_priv_posix_openat( int fd, char const * pathname,int flags);
+int dux_priv_posix_fsync( int fd);
+dux_priv_swrd dux_priv_posix_write( int fildes, void const * buf, dux_priv_uwrd nbyte);
+dux_priv_swrd dux_priv_posix_getrandom(void * buf, dux_priv_uwrd buflen,unsigned int flags);
+dux_priv_swrd dux_priv_posix_read( int fd, void * buf, dux_priv_uwrd count);
dux_priv_endcdecls
diff --git a/dux/include/dux/c/arr.h b/dux/include/dux/c/arr.h
new file mode 100644
index 0000000..86f5c17
--- /dev/null
+++ b/dux/include/dux/c/arr.h
@@ -0,0 +1,18 @@
+/*
+ Copyright 2021, 2022 Gabriel Jensen.
+
+ This file is part of dux.
+
+ dux is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with dux. If not, see <https://www.gnu.org/licenses/>.
+*/
diff --git a/dux/include/dux/c/base.h b/dux/include/dux/c/base.h
index 9cfa0c0..3fa6e4f 100644
--- a/dux/include/dux/c/base.h
+++ b/dux/include/dux/c/base.h
@@ -80,9 +80,8 @@ enum dux_errcd {
dux_errcd_badacs = dux_priv_errcd_badacs,
dux_errcd_badaddr = dux_priv_errcd_badaddr,
dux_errcd_badalloc = dux_priv_errcd_badalloc,
- dux_errcd_badio = dux_priv_errcd_badio,
dux_errcd_badperms = dux_priv_errcd_badperms,
- dux_errcd_badpipe = dux_priv_errcd_badpipe,
+ dux_errcd_badfile = dux_priv_errcd_badfile,
dux_errcd_badseq = dux_priv_errcd_badseq,
dux_errcd_badstr = dux_priv_errcd_badstr,
dux_errcd_badutf = dux_priv_errcd_badutf,
@@ -90,10 +89,10 @@ enum dux_errcd {
dux_errcd_illcallseq = dux_priv_errcd_illcallseq,
dux_errcd_illparam = dux_priv_errcd_illparam,
dux_errcd_illsz = dux_priv_errcd_illsz,
+ dux_errcd_ioerr = dux_priv_errcd_ioerr,
dux_errcd_matherr = dux_priv_errcd_matherr,
dux_errcd_nodir = dux_priv_errcd_nodir,
dux_errcd_nofile = dux_priv_errcd_nofile,
- dux_errcd_noimpl = dux_priv_errcd_noimpl,
dux_errcd_nospc = dux_priv_errcd_nospc,
dux_errcd_outofrange = dux_priv_errcd_outofrange,
dux_errcd_runerr = dux_priv_errcd_runerr,
diff --git a/dux/include/dux/c/sig.h b/dux/include/dux/c/sig.h
index 63e8b1a..3d21cb0 100644
--- a/dux/include/dux/c/sig.h
+++ b/dux/include/dux/c/sig.h
@@ -30,7 +30,7 @@ enum dux_sig {
dux_sig_iot = dux_priv_sig_iot,
dux_sig_intr = dux_priv_sig_intr,
dux_sig_kill = dux_priv_sig_kill,
- dux_sig_pipe = dux_priv_sig_pipe,
+ dux_sig_file = dux_priv_sig_file,
dux_sig_poll = dux_priv_sig_poll,
dux_sig_prof = dux_priv_sig_prof,
dux_sig_pwr = dux_priv_sig_pwr,
diff --git a/dux/include/dux/cxx/arr.hh b/dux/include/dux/cxx/arr.hh
new file mode 100644
index 0000000..4b0d81e
--- /dev/null
+++ b/dux/include/dux/cxx/arr.hh
@@ -0,0 +1,96 @@
+/*
+ Copyright 2021, 2022 Gabriel Jensen.
+
+ This file is part of dux.
+
+ dux is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with dux. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+namespace dux {
+ template<typename T> class arr {
+ public:
+ [[nodiscard]] constexpr arr() noexcept : _isalloc(false) {}
+ [[nodiscard]] constexpr arr(::dux::arr<T> && _oth) noexcept : _dat(_oth._dat), _isalloc(_oth._isalloc),_sz(_oth._sz) {_oth.kill();}
+ [[nodiscard]] constexpr arr(T * const restrict _dat, ::dux::uwrd const _sz,bool const _isalloc = false) noexcept : _dat(_dat), _isalloc(_isalloc), _sz(_sz) {}
+ template<::dux::uwrd N> [[nodiscard]] constexpr arr(T const (& _arr)[N]) noexcept : _dat(const_cast<char *>(_arr)),_isalloc(false), _sz(N) {}
+
+ constexpr auto operator = (::dux::arr<T> const & _oth) noexcept -> ::dux::arr<T> const & {
+ if (_oth._isalloc) {
+ this->alloc(_oth.sz());
+ ::dux::cpy(_oth.raw(),_oth.sz(),this->raw());
+ }
+ else {this->setraw(_oth._dat,_oth._sz,_oth._isalloc);}
+ return *this;
+ }
+
+ constexpr auto operator = (::dux::arr<T> const && _oth) noexcept -> ::dux::arr<T> const & {
+ this->setraw(_oth.alloc,_oth._dat,_oth._sz);
+ _oth._isalloc = false; /* Mutable field. */
+ return *this;
+ }
+
+ constexpr ~arr() noexcept {if (this->_isalloc) {::dux::free(this->_dat);}}
+
+ constexpr auto craw() const noexcept -> T const * {return this->_dat;}
+ constexpr auto raw() noexcept -> T * {return this->_dat;}
+ constexpr auto raw() const noexcept -> T const * {return this->_dat;}
+ constexpr auto sz() const noexcept -> ::dux::uwrd {return this->_sz;}
+
+ constexpr auto begin() noexcept -> T * {return this->raw();}
+ constexpr auto begin() const noexcept -> T const * {return this->raw();}
+ constexpr auto end() noexcept -> T * {return this->raw() + this->sz();}
+ constexpr auto end() const noexcept -> T const * {return this->raw() + this->sz();}
+ constexpr auto cbegin() const noexcept -> T const * {return this->begin();}
+ constexpr auto cend() const noexcept -> T const * {return this->end();}
+
+ constexpr auto operator [] (::dux::uwrd const _n) noexcept -> T & {return this->_dat[_n];}
+ constexpr auto operator [] (::dux::uwrd const _n) const noexcept -> T const & {return this->_dat[_n];}
+
+ constexpr auto setraw(T * const restrict _dat,::dux::uwrd const _sz,bool const _isalloc = false) noexcept -> void {
+ this->_isalloc = _isalloc;
+ this->_dat = _dat;
+ this->_sz = _sz;
+ }
+ constexpr auto setraw(T const * const restrict _dat,::dux::uwrd const _sz) noexcept -> void {
+ this->_isalloc = false;
+ this->_dat = const_cast<T *>(_dat);
+ this->_sz = _sz;
+ }
+
+ constexpr auto kill() noexcept -> void {
+ this->_dat = nullptr;
+ this->_isalloc = false;
+ }
+
+ constexpr auto alloc(::dux::uwrd const _sz) noexcept -> void {
+ this->_dat = ::dux::alloc<T>(_sz);
+ if (::dux::haserr()) [[unlikely]] {
+ this->_isalloc = false;
+ return;
+ }
+ this->_isalloc = true;
+ this->_sz = _sz;
+ }
+ constexpr auto free() noexcept -> void {
+ if (!this->_isalloc) [[unlikely]] {return;}
+ ::dux::free(this->_dat);
+ this->_isalloc = false;
+ this->_sz = dux_uwrdl(0x0);
+ }
+ private:
+ T * _dat;
+ bool mutable _isalloc;
+ ::dux::uwrd _sz;
+ };
+}
diff --git a/dux/include/dux/cxx/base.hh b/dux/include/dux/cxx/base.hh
index fec8148..1f37dd9 100644
--- a/dux/include/dux/cxx/base.hh
+++ b/dux/include/dux/cxx/base.hh
@@ -18,8 +18,8 @@
*/
namespace dux {
- constexpr static auto dbg {dux_dbg};
- constexpr static auto ver {dux_priv_ver};
+ constexpr auto dbg {dux_dbg};
+ constexpr auto ver {dux_priv_ver};
}
namespace dux {
@@ -37,27 +37,27 @@ namespace dux {
using nullptrtyp = decltype (nullptr);
}
-namespace dux { /* Clang may not be retarted. */
- template<typename T> constexpr auto static maxval {T {0x0}};
- template<> constexpr auto static maxval<bool> {static_cast<bool>( true)};
- template<> constexpr auto static maxval<char> {static_cast<char>( dux_chrmax)};
- template<> constexpr auto static maxval<char16_t> {static_cast<char16_t>( dux_chr16max)};
- template<> constexpr auto static maxval<char32_t> {static_cast<char32_t>( dux_chr32max)};
- template<> constexpr auto static maxval<char8_t> {static_cast<char8_t>( dux_chr8max)};
- template<> constexpr auto static maxval<double> {static_cast<double>( dux_dblmax)};
- template<> constexpr auto static maxval<int> {static_cast<int>( dux_intmax)};
- template<> constexpr auto static maxval<long> {static_cast<long>( dux_lngmax)};
- template<> constexpr auto static maxval<long double> {static_cast<long double>( dux_ldblmax)};
- template<> constexpr auto static maxval<long long> {static_cast<long long>( dux_llngmax)};
- template<> constexpr auto static maxval<::dux::nullptrtyp> { nullptr};
- template<> constexpr auto static maxval<short> {static_cast<short>( dux_shrtmax)};
- template<> constexpr auto static maxval<signed char> {static_cast<signed char>( dux_schrmax)};
- template<> constexpr auto static maxval<unsigned char> {static_cast<unsigned char>( dux_uchrmax)};
- template<> constexpr auto static maxval<unsigned int> {static_cast<unsigned int>( dux_uintmax)};
- template<> constexpr auto static maxval<unsigned long> {static_cast<unsigned long>( dux_ulngmax)};
- template<> constexpr auto static maxval<unsigned long long> {static_cast<unsigned long long>(dux_ullngmax)};
- template<> constexpr auto static maxval<unsigned short> {static_cast<unsigned short>( dux_ushrtmax)};
- template<> constexpr auto static maxval<wchar_t> {static_cast<wchar_t>( dux_wchrmax)};
+namespace dux { /* Clang (13.0.1) complains about multiple definitions here. Clang is retarded. */
+ template<typename T> constexpr auto maxval {T {0x0}};
+ template<> constexpr auto maxval<bool> {static_cast<bool>( true)};
+ template<> constexpr auto maxval<char> {static_cast<char>( dux_chrmax)};
+ template<> constexpr auto maxval<char16_t> {static_cast<char16_t>( dux_chr16max)};
+ template<> constexpr auto maxval<char32_t> {static_cast<char32_t>( dux_chr32max)};
+ template<> constexpr auto maxval<char8_t> {static_cast<char8_t>( dux_chr8max)};
+ template<> constexpr auto maxval<double> {static_cast<double>( dux_dblmax)};
+ template<> constexpr auto maxval<int> {static_cast<int>( dux_intmax)};
+ template<> constexpr auto maxval<long> {static_cast<long>( dux_lngmax)};
+ template<> constexpr auto maxval<long double> {static_cast<long double>( dux_ldblmax)};
+ template<> constexpr auto maxval<long long> {static_cast<long long>( dux_llngmax)};
+ template<> constexpr auto maxval<::dux::nullptrtyp> { nullptr};
+ template<> constexpr auto maxval<short> {static_cast<short>( dux_shrtmax)};
+ template<> constexpr auto maxval<signed char> {static_cast<signed char>( dux_schrmax)};
+ template<> constexpr auto maxval<unsigned char> {static_cast<unsigned char>( dux_uchrmax)};
+ template<> constexpr auto maxval<unsigned int> {static_cast<unsigned int>( dux_uintmax)};
+ template<> constexpr auto maxval<unsigned long> {static_cast<unsigned long>( dux_ulngmax)};
+ template<> constexpr auto maxval<unsigned long long> {static_cast<unsigned long long>(dux_ullngmax)};
+ template<> constexpr auto maxval<unsigned short> {static_cast<unsigned short>( dux_ushrtmax)};
+ template<> constexpr auto maxval<wchar_t> {static_cast<wchar_t>( dux_wchrmax)};
}
namespace dux::priv {
@@ -76,19 +76,19 @@ namespace dux::priv {
template<typename T> struct isptrtyp<T *> {constexpr static auto val {true};};
}
namespace dux {
- template<typename T> constexpr static auto isptrtyp {::dux::priv::isptrtyp<T>::val};
+ template<typename T> constexpr auto isptrtyp {::dux::priv::isptrtyp<T>::val};
}
namespace dux {
- template<typename T> constexpr static auto ischrtyp {::dux::issame<T,char> || ::dux::issame<T,char16_t> || ::dux::issame<T,char32_t> || ::dux::issame<T,char8_t> || ::dux::issame<T,wchar_t>};
- template<typename T,typename T0> constexpr static auto iscnvto {requires {static_cast<T0>(T {});}};
- template<typename T> constexpr static auto isflttyp {::dux::issame<T,double> || ::dux::issame<T,float> || ::dux::issame<T,long double>};
- template<typename T> constexpr static auto issinttyp {::dux::issame<T,int> || ::dux::issame<T,long> || ::dux::issame<T,long long> || ::dux::issame<T,short> || ::dux::issame<T,signed char>};
- template<typename T> constexpr static auto isuinttyp {::dux::issame<T,unsigned char> || ::dux::issame<T,unsigned int> || ::dux::issame<T,unsigned long> || ::dux::issame<T,unsigned long long> || ::dux::issame<T,unsigned short>};
+ template<typename T> constexpr auto ischrtyp {::dux::issame<T,char> || ::dux::issame<T,char16_t> || ::dux::issame<T,char32_t> || ::dux::issame<T,char8_t> || ::dux::issame<T,wchar_t>};
+ template<typename T,typename T0> constexpr auto iscnvto {requires {static_cast<T0>(T {});}};
+ template<typename T> constexpr auto isflttyp {::dux::issame<T,double> || ::dux::issame<T,float> || ::dux::issame<T,long double>};
+ template<typename T> constexpr auto issinttyp {::dux::issame<T,int> || ::dux::issame<T,long> || ::dux::issame<T,long long> || ::dux::issame<T,short> || ::dux::issame<T,signed char>};
+ template<typename T> constexpr auto isuinttyp {::dux::issame<T,unsigned char> || ::dux::issame<T,unsigned int> || ::dux::issame<T,unsigned long> || ::dux::issame<T,unsigned long long> || ::dux::issame<T,unsigned short>};
- template<typename T> constexpr static auto isinttyp {::dux::issinttyp<T> || ::dux::isuinttyp<T>};
+ template<typename T> constexpr auto isinttyp {::dux::issinttyp<T> || ::dux::isuinttyp<T>};
- template<typename T> constexpr static auto isarithtyp {::dux::isflttyp<T> || ::dux::isinttyp<T>};
+ template<typename T> constexpr auto isarithtyp {::dux::isflttyp<T> || ::dux::isinttyp<T>};
}
namespace dux {
@@ -178,9 +178,8 @@ namespace dux {
badacs = ::dux_priv_errcd_badacs,
badaddr = ::dux_priv_errcd_badaddr,
badalloc = ::dux_priv_errcd_badalloc,
- badio = ::dux_priv_errcd_badio,
badperms = ::dux_priv_errcd_badperms,
- badpipe = ::dux_priv_errcd_badpipe,
+ badfile = ::dux_priv_errcd_badfile,
badseq = ::dux_priv_errcd_badseq,
badstr = ::dux_priv_errcd_badstr,
badutf = ::dux_priv_errcd_badutf,
@@ -188,10 +187,10 @@ namespace dux {
illcallseq = ::dux_priv_errcd_illcallseq,
illparam = ::dux_priv_errcd_illparam,
illsz = ::dux_priv_errcd_illsz,
+ ioerr = ::dux_priv_errcd_ioerr,
matherr = ::dux_priv_errcd_matherr,
nodir = ::dux_priv_errcd_nodir,
nofile = ::dux_priv_errcd_nofile,
- noimpl = ::dux_priv_errcd_noimpl,
nospc = ::dux_priv_errcd_nospc,
outofrange = ::dux_priv_errcd_outofrange,
runerr = ::dux_priv_errcd_runerr,
@@ -351,11 +350,11 @@ constexpr auto ::dux::errcdnm(::dux::errcd const _cd) noexcept -> ::dux::str {
return ::dux::priv::strlittoduxstr("BADADDR");
case ::dux::errcd::badalloc:
return ::dux::priv::strlittoduxstr("BADALLOC");
- case ::dux::errcd::badio:
+ case ::dux::errcd::ioerr:
return ::dux::priv::strlittoduxstr("BADIO");
case ::dux::errcd::badperms:
return ::dux::priv::strlittoduxstr("BADPERMS");
- case ::dux::errcd::badpipe:
+ case ::dux::errcd::badfile:
return ::dux::priv::strlittoduxstr("BADPIPE");
case ::dux::errcd::badseq:
return ::dux::priv::strlittoduxstr("BADSEQ");
@@ -379,8 +378,6 @@ constexpr auto ::dux::errcdnm(::dux::errcd const _cd) noexcept -> ::dux::str {
return ::dux::priv::strlittoduxstr("NOERR");
case ::dux::errcd::nofile:
return ::dux::priv::strlittoduxstr("NOFILE");
- case ::dux::errcd::noimpl:
- return ::dux::priv::strlittoduxstr("NOIMPL");
case ::dux::errcd::nospc:
return ::dux::priv::strlittoduxstr("NOSPC");
case ::dux::errcd::outofrange:
diff --git a/dux/include/dux/cxx/io.hh b/dux/include/dux/cxx/io.hh
index 333504f..19ecaf7 100644
--- a/dux/include/dux/cxx/io.hh
+++ b/dux/include/dux/cxx/io.hh
@@ -17,10 +17,66 @@
along with dux. If not, see <https://www.gnu.org/licenses/>.
*/
+namespace dux::ioacs {
+ constexpr static auto uid {static_cast<::dux::uint16>(dux_priv_ioacs_uid)};
+ constexpr static auto gid {static_cast<::dux::uint16>(dux_priv_ioacs_gid)};
+ constexpr static auto stck {static_cast<::dux::uint16>(dux_priv_ioacs_stck)};
+ constexpr static auto usrr {static_cast<::dux::uint16>(dux_priv_ioacs_usrr)};
+ constexpr static auto usrw {static_cast<::dux::uint16>(dux_priv_ioacs_usrw)};
+ constexpr static auto usrx {static_cast<::dux::uint16>(dux_priv_ioacs_usrx)};
+ constexpr static auto grpr {static_cast<::dux::uint16>(dux_priv_ioacs_grpr)};
+ constexpr static auto grpw {static_cast<::dux::uint16>(dux_priv_ioacs_grpr)};
+ constexpr static auto grpx {static_cast<::dux::uint16>(dux_priv_ioacs_grpr)};
+ constexpr static auto othr {static_cast<::dux::uint16>(dux_priv_ioacs_othr)};
+ constexpr static auto othw {static_cast<::dux::uint16>(dux_priv_ioacs_othr)};
+ constexpr static auto othx {static_cast<::dux::uint16>(dux_priv_ioacs_othr)};
+}
+
namespace dux {
- enum iotyp : ::dux::uint8 {
+ enum class iotyp : ::dux::uint8 {
r = static_cast<::dux::uint8>(::dux_priv_iotyp_r),
rw = static_cast<::dux::uint8>(::dux_priv_iotyp_rw),
w = static_cast<::dux::uint8>(::dux_priv_iotyp_w),
};
}
+
+namespace dux {
+ class file;
+}
+
+namespace dux {
+ [[nodiscard]] auto crtfile(char const * path,::dux::uint16 acs = ::dux::ioacs::usrr | ::dux::ioacs::usrw | ::dux::ioacs::grpr | ::dux::ioacs::othr /* -rw-r--r-- */) noexcept -> ::dux::file;
+}
+
+namespace dux {
+ class file {
+ public:
+ [[nodiscard]] file() noexcept;
+ ~file() noexcept;
+
+ auto close() noexcept -> void;
+ auto del() noexcept -> void = delete;
+ [[nodiscard]] auto isopen() noexcept -> bool;
+ auto open( char const * path, ::dux::iotyp typ) noexcept -> void;
+ [[nodiscard]] auto path() const noexcept -> ::dux::str;
+ [[nodiscard]] auto read( ::dux::uwrd num = dux_uwrdl(-0x1)) noexcept -> ::dux::arr<::dux::uint8>;
+ auto mv( char const * newpath) noexcept -> ::dux::str = delete;
+ auto reopen() noexcept -> void;
+ [[nodiscard]] auto typ() const noexcept -> ::dux::iotyp;
+ auto write( void const * buf, ::dux::uwrd sz) noexcept -> void;
+
+ template<::dux::uwrd N> auto write(char const (& _buf)[N]) noexcept -> void {this->write(_buf,N - dux_uwrdl(0x1));}
+ template<typename T> auto write(T const & _val) noexcept -> void {this->write(&_val,sizeof (T));}
+ template<typename T> auto write(::dux::arr<T> const & _buf) noexcept -> void {
+ dux_ass("",_buf.isalloc());
+ this->write(_buf.raw(),_buf.sz() * sizeof (T));
+ }
+
+ friend auto ::dux::crtfile(char const * path,::dux::uint16 acs) noexcept -> ::dux::file;
+ private:
+ bool _isopen;
+ ::dux::str _path;
+ void * _sysdat;
+ ::dux::iotyp _typ;
+ };
+}
diff --git a/dux/include/dux/cxx/math.hh b/dux/include/dux/cxx/math.hh
index 89fb670..a0b885b 100644
--- a/dux/include/dux/cxx/math.hh
+++ b/dux/include/dux/cxx/math.hh
@@ -18,29 +18,29 @@
*/
namespace dux::num {
- constexpr static auto e {dux_priv_num_e};
- constexpr static auto phi {dux_priv_num_phi};
- constexpr static auto pi {dux_priv_num_pi};
+ constexpr auto e {dux_priv_num_e};
+ constexpr auto phi {dux_priv_num_phi};
+ constexpr auto pi {dux_priv_num_pi};
}
namespace dux::priv {
- template<::dux::arithtyp T> constexpr static auto inf {::dux::maxval<T>};
- template<> constexpr static auto inf<double> {dux_priv_infd};
- template<> constexpr static auto inf<float> {dux_priv_inff};
- template<> constexpr static auto inf<long double> {dux_priv_infld};
+ template<::dux::arithtyp T> constexpr auto inf {::dux::maxval<T>};
+ template<> constexpr auto inf<double> {dux_priv_infd};
+ template<> constexpr auto inf<float> {dux_priv_inff};
+ template<> constexpr auto inf<long double> {dux_priv_infld};
}
namespace dux {
- template<::dux::arithtyp T> constexpr static auto inf {::dux::priv::inf<T>};
+ template<::dux::arithtyp T> constexpr auto inf {::dux::priv::inf<T>};
}
namespace dux::priv {
- template<::dux::arithtyp T> constexpr static auto nan {T {0x0}};
- template<> constexpr static auto nan<double> {dux_priv_nand};
- template<> constexpr static auto nan<float> {dux_priv_nanf};
- template<> constexpr static auto nan<long double> {dux_priv_nanld};
+ template<::dux::arithtyp T> constexpr auto nan {T {0x0}};
+ template<> constexpr auto nan<double> {dux_priv_nand};
+ template<> constexpr auto nan<float> {dux_priv_nanf};
+ template<> constexpr auto nan<long double> {dux_priv_nanld};
}
namespace dux {
- template<::dux::arithtyp T> constexpr static auto nan {::dux::priv::nan<T>};
+ template<::dux::arithtyp T> constexpr auto nan {::dux::priv::nan<T>};
}
namespace dux {
diff --git a/dux/include/dux/cxx/seq.hh b/dux/include/dux/cxx/seq.hh
index f206c61..afff578 100644
--- a/dux/include/dux/cxx/seq.hh
+++ b/dux/include/dux/cxx/seq.hh
@@ -18,6 +18,8 @@
*/
namespace dux {
+ [[nodiscard]] auto memeq(void const * lptr,::dux::uwrd const num,void const * rptr) noexcept -> bool;
+
template<typename T> inline auto bytefill(T * const _in,::dux::uwrd const _num,::dux::uint8 const _val) noexcept -> void {
static_assert(!::dux::issame<T,void>);
dux_priv_ifconsteval {
diff --git a/dux/include/dux/cxx/sig.hh b/dux/include/dux/cxx/sig.hh
index b295730..652bda2 100644
--- a/dux/include/dux/cxx/sig.hh
+++ b/dux/include/dux/cxx/sig.hh
@@ -31,7 +31,7 @@ namespace dux {
iot = static_cast<::dux::uint8>(dux_priv_sig_iot),
intr = static_cast<::dux::uint8>(dux_priv_sig_intr),
kill = static_cast<::dux::uint8>(dux_priv_sig_kill),
- pipe = static_cast<::dux::uint8>(dux_priv_sig_pipe),
+ file = static_cast<::dux::uint8>(dux_priv_sig_file),
poll = static_cast<::dux::uint8>(dux_priv_sig_poll),
prof = static_cast<::dux::uint8>(dux_priv_sig_prof),
pwr = static_cast<::dux::uint8>(dux_priv_sig_pwr),
diff --git a/dux/include/dux/io.h b/dux/include/dux/io.h
index 9908110..60c31df 100644
--- a/dux/include/dux/io.h
+++ b/dux/include/dux/io.h
@@ -22,3 +22,16 @@ enum dux_priv_iotyp {
dux_priv_iotyp_rw,
dux_priv_iotyp_w,
};
+
+# define dux_priv_ioacs_uid (dux_uint16l(04000))
+# define dux_priv_ioacs_gid (dux_uint16l(02000))
+# define dux_priv_ioacs_stck (dux_uint16l(01000))
+# define dux_priv_ioacs_usrr (dux_uint16l(0400))
+# define dux_priv_ioacs_usrw (dux_uint16l(0200))
+# define dux_priv_ioacs_usrx (dux_uint16l(0100))
+# define dux_priv_ioacs_grpr (dux_uint16l(040))
+# define dux_priv_ioacs_grpw (dux_uint16l(020))
+# define dux_priv_ioacs_grpx (dux_uint16l(010))
+# define dux_priv_ioacs_othr (dux_uint16l(04))
+# define dux_priv_ioacs_othw (dux_uint16l(02))
+# define dux_priv_ioacs_othx (dux_uint16l(01))
diff --git a/dux/include/dux/sig.h b/dux/include/dux/sig.h
index b01e279..c0ef68b 100644
--- a/dux/include/dux/sig.h
+++ b/dux/include/dux/sig.h
@@ -61,7 +61,7 @@ enum dux_priv_sig { /* Refer to `man 7 signal` for values. */
dux_priv_sig_iot = 0x6,
dux_priv_sig_intr = 0x2,
dux_priv_sig_kill = 0x9,
- dux_priv_sig_pipe = 0xD,
+ dux_priv_sig_file = 0xD,
# if defined(dux_os_linux)
dux_priv_sig_poll = 0x1D,
# else
diff --git a/dux/src/abrt.cc b/dux/src/abrt.cc
index 07712e6..ef0fbf5 100644
--- a/dux/src/abrt.cc
+++ b/dux/src/abrt.cc
@@ -26,8 +26,8 @@
auto ::dux::abrt() noexcept -> void {
static ::std::atomic_flag lock;
while (lock.test_and_set()) {} /* We make sure we don't abort from multiple threads. */
- ::dux::dbglog("dux :: abrt :: Aborting!\n");
- if (::dux::haserr()) {::dux::dbglog("dux :: abrt :: Last error: %s\n",::dux::errcdnm(::dux::geterr()));}
+ ::dux::dbglog("dux.abrt :: Abort\n");
+ if (::dux::haserr()) {::dux::dbglog("dux.abrt :: Last error: %s\n",::dux::errcdnm(::dux::geterr()));}
::dux::setsighandl(::dux::sig::abrt,::dux::sighandl::dfl());
::dux::raise(::dux::sig::abrt); /* Raise SIGABRT to call the default signal handler. */
::dux::trap(); /* The default signal handler returned, so we will trap as we can't return. */
diff --git a/dux/src/crtfile.cc b/dux/src/crtfile.cc
new file mode 100644
index 0000000..2d1d48b
--- /dev/null
+++ b/dux/src/crtfile.cc
@@ -0,0 +1,67 @@
+/*
+ Copyright 2021, 2022 Gabriel Jensen.
+
+ This file is part of dux.
+
+ dux is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with dux. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+# include <dux/priv>
+
+# include <dux/io>
+
+# include <dux/str>
+
+# include <fcntl.h>
+# if defined(dux_os_freebsd)
+# include <errno.h>
+# elif defined(dux_os_linux)
+# include <linux/errno.h>
+# endif
+
+auto ::dux::crtfile(char const * _path,::dux::uint16 const _acs) noexcept -> ::dux::file {
+ dux_ass("",_path != nullptr);
+ ::dux::file file;
+ ::dux::dbglog("dux.crtfile :: Create \"%s\"\n",_path);
+ auto const sysdat {static_cast<::dux::priv::filesysdat *>(file._sysdat)};
+# if defined(dux_os_posix)
+open:;
+ auto const openatret {::dux_priv_posix_openat(AT_FDCWD,_path,O_CREAT | O_TRUNC | O_WRONLY,static_cast<::mode_t>(_acs))};
+ if (openatret == -0x1) [[unlikely]] {
+ switch (dux_priv_errno) {
+ default:
+ ::dux::seterr(::dux::errcd::runerr);
+ break;
+ case EACCES:
+ [[fallthrough]];
+ case EROFS:
+ ::dux::seterr(::dux::errcd::badacs);
+ break;
+ case EINTR:
+ goto open;
+ case ENOTDIR:
+ ::dux::seterr(::dux::errcd::nodir);
+ break;
+ }
+ ::dux::dbglog("dux.\x1B[91mcrtfile\x1B[0m :: Error!\n");
+ return file;
+ }
+ sysdat->fd = openatret;
+# endif
+ file._path.ptr = _path;
+ file._path.sz = ::dux::strlen(_path);
+ file._typ = ::dux::iotyp::w;
+ file._isopen = true;
+ return file;
+}
diff --git a/dux/src/exit.cc b/dux/src/exit.cc
index 526d3bb..e1eb4f8 100644
--- a/dux/src/exit.cc
+++ b/dux/src/exit.cc
@@ -30,7 +30,7 @@
auto ::dux::exit(::dux::stat const _stat) noexcept -> void {
if (::dux::ismainthrd()) [[unlikely]] { /* Check if the calling thread is also the main thread. Only thread exit and quick exit may be invoked outside the main thread. */
- ::dux::dbglog("dux :: \x1B[91mexit\x1B[0m :: Standard exit invoked outside main thread!\n");
+ ::dux::dbglog("dux.\x1B[91mexit\x1B[0m :: Standard exit invoked outside main thread!\n");
::dux::abrt();
}
::dux::priv::exitlock.store(true);
diff --git a/dux/src/file.cc b/dux/src/file.cc
new file mode 100644
index 0000000..094b310
--- /dev/null
+++ b/dux/src/file.cc
@@ -0,0 +1,197 @@
+/*
+ Copyright 2021, 2022 Gabriel Jensen.
+
+ This file is part of dux.
+
+ dux is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with dux. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+# include <dux/priv>
+
+# include <dux/io>
+
+# include <dux/str>
+
+# include <fcntl.h>
+# if defined(dux_os_freebsd)
+# include <errno.h>
+# elif defined(dux_os_linux)
+# include <linux/errno.h>
+# endif
+
+namespace dux::local {
+ [[nodiscard]] constexpr static auto iotypstr(::dux::iotyp const _typ) noexcept -> ::dux::str {
+ switch (_typ) {
+ case ::dux::iotyp::r:
+ return ::dux::priv::strlittoduxstr("R");
+ case ::dux::iotyp::rw:
+ return ::dux::priv::strlittoduxstr("R/W");
+ case ::dux::iotyp::w:
+ return ::dux::priv::strlittoduxstr("W");
+ }
+ ::dux::unreach();
+ }
+}
+
+::dux::file::file() noexcept : _isopen(false) {this->_sysdat = ::dux::alloc<::dux::priv::filesysdat>();}
+
+::dux::file::~file() noexcept {
+ if (this->isopen()) [[unlikely]] {
+ ::dux::dbglog("dux.\x1B[91mfile\x1B[0m :: Pipe wasn't closed!\n");
+ ::dux::abrt();
+ }
+ auto const sysdat {static_cast<::dux::priv::filesysdat *>(this->_sysdat)};
+ ::dux::free(sysdat);
+}
+
+auto ::dux::file::close() noexcept -> void {
+ if (!this->isopen()) [[unlikely]] {return;}
+ ::dux::dbglog("dux.file.close :: Close \"%s\"\n",this->path().ptr);
+ auto const sysdat {static_cast<::dux::priv::filesysdat *>(this->_sysdat)};
+# if defined(dux_os_posix)
+close:;
+ auto const closeret {::dux_priv_posix_close(sysdat->fd)};
+ if (closeret == -0x1) [[unlikely]] {
+ switch (dux_priv_errno) {
+ default:
+ ::dux::seterr(::dux::errcd::runerr);
+ break;
+ case EINTR:
+ goto close;
+ }
+ ::dux::dbglog("dux.file.open :: Error!\n");
+ return;
+ }
+# endif
+ this->_isopen = false;
+}
+
+auto ::dux::file::isopen() noexcept -> bool {return this->_isopen;}
+
+# if false /* Base for dux.pipe.mv (for future implementation): */
+auto ::dux::file::mv(char const * const _newpath) noexcept -> ::dux::str {
+ auto const oldpath {this->path()};
+ auto const newpath {[&_newpath] {
+ ::dux::str newpath;
+ newpath.ptr = _newpath;
+ newpath.sz = ::dux::strlen(_newpath);
+ return newpath;
+ }()};
+ if (newpath.sz != oldpath.sz || !::dux::memeq(newpath.ptr,newpath.sz,oldpath.ptr)) [[unlikely]] {goto retold;}
+retold:;
+ return oldpath;
+}
+# endif
+
+auto ::dux::file::open(char const * const _path,::dux::iotyp const _typ) noexcept -> void {
+ dux_ass("",_path != nullptr);
+ if (this->isopen()) [[unlikely]] {this->close();}
+ ::dux::dbglog("dux.file.open :: Open %s:\"%s\"\n",::dux::local::iotypstr(_typ).ptr,_path);
+ auto const sysdat {static_cast<::dux::priv::filesysdat *>(this->_sysdat)};
+# if defined(dux_os_posix)
+ auto const openatflags {[&_typ] {
+ switch (_typ) {
+ case ::dux::iotyp::r:
+ return O_RDONLY;
+ case ::dux::iotyp::rw:
+ return O_RDWR;
+ case ::dux::iotyp::w:
+ return O_WRONLY;
+ }
+ ::dux::unreach();
+ }()};
+open:;
+ auto const openatret {::dux_priv_posix_openat(AT_FDCWD,_path,openatflags,static_cast<::mode_t>(0x0))};
+ if (openatret == -0x1) [[unlikely]] {
+ switch (dux_priv_errno) {
+ default:
+ ::dux::seterr(::dux::errcd::runerr);
+ break;
+ case EACCES:
+ [[fallthrough]];
+ case EROFS:
+ ::dux::seterr(::dux::errcd::badacs);
+ break;
+ case EINTR:
+ goto open;
+ case ENOENT:
+ ::dux::seterr(::dux::errcd::nofile);
+ break;
+ case ENOTDIR:
+ ::dux::seterr(::dux::errcd::nodir);
+ break;
+ }
+ ::dux::dbglog("dux.file.\x1B[91mopen\x1B[0m :: Error!\n");
+ return;
+ }
+ sysdat->fd = openatret;
+# endif
+ this->_path.ptr = _path;
+ this->_path.sz = ::dux::strlen(_path);
+ this->_typ = _typ;
+ this->_isopen = true;
+}
+
+auto ::dux::file::path() const noexcept -> ::dux::str {return this->_path;}
+
+auto ::dux::file::read(::dux::uwrd const _num) noexcept -> ::dux::arr<::dux::uint8> {
+ if (!this->isopen()) [[unlikely]] {
+ ::dux::dbglog("dux.file.\x1B[91mread\x1B[0m :: Pipe not open!\n");
+ ::dux::abrt();
+ }
+ if (this->typ() != ::dux::iotyp::r && this->typ() != ::dux::iotyp::rw) [[unlikely]] {
+ ::dux::dbglog("dux.file.\x1B[91mread\x1B[0m :: I/O type (%s) does not support reading!\n",::dux::local::iotypstr(_typ).ptr);
+ ::dux::abrt();
+ }
+ ::dux::dbglog("dux.file.read :: Read %zu @ \"%s\"\n",_num,this->path());
+ auto const sysdat {static_cast<::dux::priv::filesysdat *>(this->_sysdat)};
+ ::dux::arr<::dux::uint8> buf;
+ buf.alloc(_num);
+# if defined(dux_os_posix)
+read:;
+ auto const readret {::dux_priv_posix_read(sysdat->fd,buf.raw(),_num)};
+ if (readret == dux_swrdl(-0x1)) [[unlikely]] {
+ switch (dux_priv_errno) {
+ case EINTR:
+ goto read;
+ }
+ ::dux::dbglog("dux.file.\x1B[91mread\x1B[0m :: Unable to read file!\n");
+ ::dux::seterr(::dux::errcd::ioerr);
+ buf.free();
+ return buf;
+ }
+# endif
+ return buf;
+}
+
+auto ::dux::file::typ() const noexcept -> ::dux::iotyp {return this->_typ;}
+
+auto ::dux::file::write(void const * const _buf,::dux::uwrd const _sz) noexcept -> void {
+ dux_ass("",_buf != nullptr);
+ dux_ass("",_sz != dux_uwrdl(0x0));
+ if (!this->isopen()) [[unlikely]] {
+ ::dux::dbglog("dux.file.\x1B[91mwrite\x1B[0m :: Pipe not open!\n");
+ ::dux::abrt();
+ }
+ if (this->typ() != ::dux::iotyp::rw && this->typ() != ::dux::iotyp::w) [[unlikely]] {
+ ::dux::dbglog("dux.file.\x1B[91mwrite\x1B[0m :: I/O type (%s) does not support writting!\n",::dux::local::iotypstr(_typ));
+ ::dux::abrt();
+ }
+ auto const sysdat {static_cast<::dux::priv::filesysdat *>(this->_sysdat)};
+ ::dux::dbglog("dux.file.write :: Write %zu @ %p -> \"%s\"\n",_sz,_buf,this->path().ptr);
+# if defined(dux_os_posix)
+ ::dux_priv_posix_write(sysdat->fd,_buf,_sz);
+ ::dux_priv_posix_fsync(sysdat->fd);
+# endif
+}
diff --git a/dux/src/free.cc b/dux/src/free.cc
index 90cade5..4ec9864 100644
--- a/dux/src/free.cc
+++ b/dux/src/free.cc
@@ -24,7 +24,7 @@
# include <dux/sig>
auto ::dux::free(::dux::nullptrtyp) noexcept -> void {
- ::dux::dbglog("dux :: free :: Address 0x0 is not freeable!\n");
+ ::dux::dbglog("dux.free :: Address 0x0 is not freeable!\n");
::dux::raise(::dux::sig::segv);
::dux::unreach(); /* SIGSEGV handlers may not return, so we can guarantee that this function also never returns. */
}
diff --git a/dux/src/getenv.cc b/dux/src/getenv.cc
index 06a21e8..5bb2ad4 100644
--- a/dux/src/getenv.cc
+++ b/dux/src/getenv.cc
@@ -40,13 +40,13 @@ auto ::dux::getenv(char const * const restrict _envvarname) noexcept -> ::dux::s
if (::dux::streq(envvarname,_envvarname)) [[unlikely]] {
str.ptr = envvar + eqpos + dux_uwrdl(0x1);
str.sz = eqpos;
- ::dux::dbglog("dux :: getenv :: Got value of environment variable %s: \"%s\"\n",_envvarname,str.ptr);
+ ::dux::dbglog("dux.getenv :: Got value of environment variable %s: \"%s\"\n",_envvarname,str.ptr);
return str;
}
}
str.ptr = "";
str.sz = dux_uwrdl(0x0);
- ::dux::dbglog("dux :: getenv :: Environment variable %s did not exist!\n",_envvarname);
+ ::dux::dbglog("dux.getenv :: Environment variable %s did not exist!\n",_envvarname);
return str;
}
diff --git a/dux/src/memeq.cc b/dux/src/memeq.cc
new file mode 100644
index 0000000..bcf3e88
--- /dev/null
+++ b/dux/src/memeq.cc
@@ -0,0 +1,36 @@
+/*
+ Copyright 2021, 2022 Gabriel Jensen.
+
+ This file is part of dux.
+
+ dux is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with dux. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+# include <dux/priv>
+
+# include <dux/mem>
+
+# include <dux/sig>
+
+auto ::dux::memeq(void const * const restrict _lptr,::dux::uwrd const _num,void const * const restrict _rptr) noexcept -> bool {
+ auto lptr {static_cast<::dux::uint8 const *>(_lptr)};
+ auto rptr {static_cast<::dux::uint8 const *>(_rptr)};
+ auto const maxlptr {lptr + _num - dux_uwrdl(0x1)};
+ for (;lptr <= maxlptr;++lptr,++rptr) {if (*lptr != *rptr) [[unlikely]] {return false;}}
+ return true;
+}
+
+# pragma GCC diagnostic ignored "-Wmissing-declarations"
+
+extern "C" auto dux_memeq(void const * const restrict _lptr,::dux::uwrd const _num,void const * const restrict _rptr) noexcept -> bool {return ::dux::memeq(_lptr,_num,_rptr);}
diff --git a/dux/src/onexit.cc b/dux/src/onexit.cc
index e42261a..cde37f2 100644
--- a/dux/src/onexit.cc
+++ b/dux/src/onexit.cc
@@ -23,7 +23,7 @@
auto ::dux::onexit(::dux::priv::onexitfn const _fn) noexcept -> void {
if (::dux::priv::exitlock.load()) [[unlikely]] {
- ::dux::dbglog("dux :: \x1B[91monexit\x1B[0m :: Invoked after exit!\n");
+ ::dux::dbglog("dux.\x1B[91monexit\x1B[0m :: Invoked after exit!\n");
::dux::seterr(::dux::errcd::illcallseq);
return;
}
@@ -34,15 +34,15 @@ auto ::dux::onexit(::dux::priv::onexitfn const _fn) noexcept -> void {
using ::dux::priv::onexitfns;
using ::dux::priv::numonexitfns;
for (auto n {dux_uwrdl(0x0)};n < numonexitfns;++n) {if (onexitfns[n] == _fn) [[unlikely]] {
- ::dux::dbglog("dux :: onexit :: Function at %p has already been registered!\n",reinterpret_cast<void *>(_fn));
+ ::dux::dbglog("dux.onexit :: Function at %p has already been registered!\n",reinterpret_cast<void *>(_fn));
goto ret;
}}
if (numonexitfns == ::dux::priv::maxnumonexitfns) [[unlikely]] {
- ::dux::dbglog("dux :: \x1B[91monexit\x1B[0m :: Function at %p cannot be registered as limit (%zu) has been reached!\n",reinterpret_cast<void *>(_fn),::dux::priv::maxnumonexitfns);
+ ::dux::dbglog("dux.\x1B[91monexit\x1B[0m :: Function at %p cannot be registered as limit (%zu) has been reached!\n",reinterpret_cast<void *>(_fn),::dux::priv::maxnumonexitfns);
::dux::seterr(::dux::errcd::nospc);
goto ret;
}
- ::dux::dbglog("dux :: onexit :: Registering function at %p!\n",reinterpret_cast<void *>(_fn));
+ ::dux::dbglog("dux.onexit :: Register %p!\n",reinterpret_cast<void *>(_fn));
++numonexitfns;
onexitfns[numonexitfns - 0x1] = _fn;
}
diff --git a/dux/src/priv/dbgunreach.c b/dux/src/priv/dbgunreach.c
index de56e8c..f2f80a2 100644
--- a/dux/src/priv/dbgunreach.c
+++ b/dux/src/priv/dbgunreach.c
@@ -22,7 +22,7 @@
# include <dux/str>
void dux_priv_dbgunreach(char const * const restrict _file,long const _line) {
- dux_dbglog("dux :: Unreachable point reached");
+ dux_dbglog("dux.Unreachable point reached");
if (!dux_streq(_file,"") && _line != 0x0l) {
dux_dbglog(" at \"%s\":%li",_file,_line);
}
diff --git a/dux/src/priv/posix/fsync.c b/dux/src/priv/posix/fsync.c
new file mode 100644
index 0000000..f5a2840
--- /dev/null
+++ b/dux/src/priv/posix/fsync.c
@@ -0,0 +1,34 @@
+/*
+ Copyright 2021, 2022 Gabriel Jensen.
+
+ This file is part of dux.
+
+ dux is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with dux. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+# include <dux/priv>
+
+# if defined(dux_os_freebsd)
+# include <sys/syscall.h>
+# elif defined(dux_os_linux)
+# include <linux/unistd.h>
+# endif
+
+int dux_priv_posix_fsync(int const fd) {
+# if defined(dux_os_freebsd)
+ return (int)dux_syscall(SYS_fsync,fd);
+# elif defined(dux_os_linux)
+ return (int)dux_syscall(__NR_fsync,fd);
+# endif
+}
diff --git a/dux/src/priv/posix/openat.c b/dux/src/priv/posix/openat.c
index 2ae2a13..1069c1e 100644
--- a/dux/src/priv/posix/openat.c
+++ b/dux/src/priv/posix/openat.c
@@ -19,16 +19,17 @@
# include <dux/priv>
+# include <fcntl.h>
# if defined(dux_os_freebsd)
# include <sys/syscall.h>
# elif defined(dux_os_linux)
# include <linux/unistd.h>
# endif
-int dux_priv_posix_openat(int const fd,char const * const pathname,int const flags) {
+int dux_priv_posix_openat(int const fd,char const * const pathname,int const flags,mode_t const mode) {
# if defined(dux_os_freebsd)
- return (int)dux_syscall(SYS_open,fd,pathname,flags);
+ return (int)dux_syscall(SYS_open,fd,pathname,flags,mode);
# elif defined(dux_os_linux)
- return (int)dux_syscall(__NR_open,fd,pathname,flags);
+ return (int)dux_syscall(__NR_openat,fd,pathname,flags,mode);
# endif
}
diff --git a/dux/src/priv/posix/read.c b/dux/src/priv/posix/read.c
new file mode 100644
index 0000000..e0781ad
--- /dev/null
+++ b/dux/src/priv/posix/read.c
@@ -0,0 +1,34 @@
+/*
+ Copyright 2021, 2022 Gabriel Jensen.
+
+ This file is part of dux.
+
+ dux is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with dux. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+# include <dux/priv>
+
+# if defined(dux_os_freebsd)
+# include <sys/syscall.h>
+# elif defined(dux_os_linux)
+# include <linux/unistd.h>
+# endif
+
+dux_swrd dux_priv_posix_read(int const fd,void * const buf,dux_uwrd const count) {
+# if defined(dux_os_freebsd)
+ return (dux_swrd)dux_syscall(SYS_read,fd,buf,count);
+# elif defined(dux_os_linux)
+ return (dux_swrd)dux_syscall(__NR_read,fd,buf,count);
+# endif
+}
diff --git a/dux/src/priv/posix/sigaction.c b/dux/src/priv/posix/sigaction.c
index 807d44c..8a0e259 100644
--- a/dux/src/priv/posix/sigaction.c
+++ b/dux/src/priv/posix/sigaction.c
@@ -19,8 +19,6 @@
# include <dux/priv>
-# include <dux/seq>
-
# include <signal.h>
# if defined(dux_os_freebsd)
# include <sys/syscall.h>
diff --git a/dux/src/priv/start.cc b/dux/src/priv/start.cc
index 29f2a95..f72aba0 100644
--- a/dux/src/priv/start.cc
+++ b/dux/src/priv/start.cc
@@ -29,18 +29,18 @@ auto main(int const argc,char const * const * const argv) -> int {return ::dux_p
extern "C" auto dux_main(::dux::mainparams const *) -> ::dux::stat;
extern "C" auto dux_priv_start(int const argc,char const * const * const argv) -> int {
- ::dux::dbglog("dux :: priv.start :: Bootstrapping!\n");
+ ::dux::dbglog("dux.priv.start :: Bootstrapping!\n");
::dux::mainparams mainparams;
mainparams.fromstd(argc,argv);
::dux::stat volatile stat;
if (setjmp(::dux::priv::exitjmp) == 0x0) {
try {stat = ::dux_main(&mainparams);}
catch (...) {
- ::dux::dbglog("dux :: \x1B[91mpriv.start\x1B[0m :: Exception was not caught!\n");
+ ::dux::dbglog("dux.\x1B[91mpriv.start\x1B[0m :: Exception was not caught!\n");
::dux::abrt();
}
::dux::priv::exitlock.store(true); /* Disable all future exits. */
- ::dux::dbglog("dux :: priv.start :: Program returned!\n");
+ ::dux::dbglog("dux.priv.start :: Program returned!\n");
}
else {stat = ::dux::priv::exitstat;}
while (::dux::priv::onexitlock.load()) {} /* Wait for the remaining onexit function to be registered, if any. */
@@ -48,18 +48,18 @@ extern "C" auto dux_priv_start(int const argc,char const * const * const argv) -
using ::dux::priv::onexitfns;
for (::dux::uwrd n {::dux::priv::numonexitfns};n > 0x0;--n) {
auto const fn {onexitfns[n - dux_uwrdl(0x1)]};
- ::dux::dbglog("dux :: exit :: Calling registered function #%zu at %p!\n",n - dux_uwrdl(0x1),reinterpret_cast<void *>(fn));
+ ::dux::dbglog("dux.exit :: Calling registered function #%zu at %p!\n",n - dux_uwrdl(0x1),reinterpret_cast<void *>(fn));
if (fn == nullptr) [[unlikely]] {
- ::dux::dbglog("dux :: exit :: Registered function is invalid (address is null)!\n");
+ ::dux::dbglog("dux.exit :: Registered function is invalid (address is null)!\n");
::dux::raise(::dux::sig::segv);
}
try {fn(stat);} /* Registered functions may not throw exceptions. */
catch (...) {
- ::dux_priv_logstderr("dux :: exit :: Registered function threw an exception!\n");
+ ::dux_priv_logstderr("dux.exit :: Registered function threw an exception!\n");
::dux::abrt();
}
}
}
- ::dux::dbglog("dux :: exit :: Exiting with system code (%i)!\n",static_cast<int>(stat));
+ ::dux::dbglog("dux.exit :: Exiting with system code (%i)!\n",static_cast<int>(stat));
return static_cast<int>(stat);
}
diff --git a/dux/src/raise.cc b/dux/src/raise.cc
index 687eada..43057f3 100644
--- a/dux/src/raise.cc
+++ b/dux/src/raise.cc
@@ -25,13 +25,13 @@
auto ::dux::raise(::dux::sig const _sig) noexcept -> void {
auto const syssig = static_cast<int>(_sig);
- ::dux::dbglog("dux :: raise :: Raising signal #%i!\n",syssig);
+ ::dux::dbglog("dux.raise :: Raise #%i\n",syssig);
# if defined(dux_priv_nosigtrap)
switch (_sig) {
[[likely]] default:
break;
case ::dux::sig::term:
- ::dux_priv_dbglog("dux :: raise :: Terminated!\n");
+ ::dux_priv_dbglog("dux.raise :: Terminated!\n");
::dux::exit(::dux::stat::err);
case ::dux::sig::trap:
::dux::trap();
diff --git a/dux/src/realloc.cc b/dux/src/realloc.cc
index 0e65b3a..68fe284 100644
--- a/dux/src/realloc.cc
+++ b/dux/src/realloc.cc
@@ -27,7 +27,7 @@
auto ::dux::priv::realloc(void * const restrict _ptr,::dux::uwrd const _newsz) noexcept -> void * {
if (reinterpret_cast<::dux::uwrd>(_ptr) % alignof (::std::max_align_t) != dux_uwrdl(0x0)) [[unlikely]] {
- ::dux::dbglog("dux :: realloc :: Address %p is not default-aligned and cannot be reallocated in the current version of dux!\n",_ptr);
+ ::dux::dbglog("dux.realloc :: Address %p is not default-aligned and cannot be reallocated in the current version of dux!\n",_ptr);
::dux::raise(::dux::sig::segv);
}
auto const newptr {::std::realloc(const_cast<void *>(_ptr),_newsz)};
diff --git a/dux/src/setsighandl.cc b/dux/src/setsighandl.cc
index 064743b..a4131f6 100644
--- a/dux/src/setsighandl.cc
+++ b/dux/src/setsighandl.cc
@@ -42,7 +42,7 @@ auto ::dux::setsighandl(::dux::sig const _sig,::dux::sighandl const _handl) noex
[[fallthrough]];
case ::dux::sig::trap:
if (!_handl._isdfl) [[unlikely]] {
- ::dux::dbglog("dux :: \x1B[91msetsighandl\x1B[0m :: Attempted setting custom signal handler for SIGABRT, SIGKILL or SIGTRAP (not allowed)!\n");
+ ::dux::dbglog("dux.\x1B[91msetsighandl\x1B[0m :: Attempted setting custom signal handler for SIGABRT, SIGKILL or SIGTRAP (not allowed)!\n");
::dux::seterr(::dux::errcd::badperms);
return;
}
@@ -50,7 +50,7 @@ auto ::dux::setsighandl(::dux::sig const _sig,::dux::sighandl const _handl) noex
if constexpr (::dux::dbg) {
if (!_handl._isdfl) {
if (_handl.handl == nullptr) [[unlikely]] {
- ::dux::dbglog("dux :: \x1B[91msetsighandl\x1B[0m :: Handler invalid (address is null)!\n");
+ ::dux::dbglog("dux.\x1B[91msetsighandl\x1B[0m :: Handler invalid (address is null)!\n");
::dux::seterr(::dux::errcd::illparam);
return;
}
@@ -64,7 +64,7 @@ auto ::dux::setsighandl(::dux::sig const _sig,::dux::sighandl const _handl) noex
auto const handlret {handl.handl(static_cast<::dux::sig>(_sig))};
auto const handlptr {reinterpret_cast<void *>(handl.handl)};
if (handlret) [[unlikely]] {
- ::dux::dbglog("dux :: \x1B[91mraise\x1B[0m :: Signal handler for #%i (at %p) indicated error!\n",_sig,handlptr);
+ ::dux::dbglog("dux.\x1B[91mraise\x1B[0m :: Signal handler for #%i (at %p) indicated error!\n",_sig,handlptr);
::dux::abrt();
}
switch (_sig) {
@@ -75,17 +75,17 @@ auto ::dux::setsighandl(::dux::sig const _sig,::dux::sighandl const _handl) noex
case SIGILL:
[[fallthrough]];
case SIGSEGV:
- ::dux::dbglog("dux :: \x1B[91mraise\x1B[0m :: Signal handler for SIGFPE, SIGILL or SIGSEGV (at %p) returned and did not indicate error (not allowed)!\n",handlptr);
+ ::dux::dbglog("dux.\x1B[91mraise\x1B[0m :: Signal handler for SIGFPE, SIGILL or SIGSEGV (at %p) returned and did not indicate error (not allowed)!\n",handlptr);
::dux::abrt();
}
}};
struct ::sigaction sigact {};
if (_handl == ::dux::sighandl::dfl()) {
- ::dux::dbglog("dux :: setsighandl :: Setting default signal handler for signal #%i!\n",sig);
+ ::dux::dbglog("dux.setsighandl :: Set (default) -> #%i\n",sig);
sigact.sa_handler = SIG_DFL;
}
else {
- ::dux::dbglog("dux :: setsighandl :: Setting signal handler (at %p) for signal #%i!\n",_handl.handl,sig);
+ ::dux::dbglog("dux.setsighandl :: Set %p -> #%i\n",_handl.handl,sig);
sigact.sa_handler = handlwrap;
}
::sigemptyset(&sigact.sa_mask);
diff --git a/dux/src/sleep.cc b/dux/src/sleep.cc
index 63bde80..512ecb4 100644
--- a/dux/src/sleep.cc
+++ b/dux/src/sleep.cc
@@ -34,14 +34,14 @@ auto ::dux::sleep(::dux::uint64 const _sec) noexcept -> void {
struct timespec timespec {};
timespec.tv_sec = static_cast<::time_t>(_sec);
timespec.tv_nsec = 0x0l;
- ::dux::dbglog("dux :: sleep :: Initiating sleep for (" dux_printfuint64 ") %s!\n",_sec,timespec.tv_sec == ::time_t {0x1} ? "second" : "seconds");
+ ::dux::dbglog("dux.sleep :: Sleep " dux_printfuint64 "s\n",_sec);
while (timespec.tv_sec > static_cast<::time_t>(0x0)) { /* In case the sleep was interrupted, we must sleep the remaining time away. */
if (::dux_priv_posix_nanosleep(&timespec,&timespec) == -0x1) [[unlikely]] {
if (dux_priv_errno == EINTR) {
- ::dux::dbglog("dux :: sleep :: Sleep was interrupted! Slept for " dux_printfuint64 " %s.\n",static_cast<::dux::uint64>(timespec.tv_sec),timespec.tv_sec == ::time_t {0x1} ? "second" : "seconds");
+ ::dux::dbglog("dux.sleep :: Sleep was interrupted! Slept for " dux_printfuint64 " %s.\n",static_cast<::dux::uint64>(timespec.tv_sec),timespec.tv_sec == ::time_t {0x1} ? "second" : "seconds");
continue;
}
- ::dux::dbglog("dux :: \x1B[91msleep\x1B[0m :: Sleep failed!\n");
+ ::dux::dbglog("dux.\x1B[91msleep\x1B[0m :: Sleep failed!\n");
::dux::seterr(::dux::errcd::runerr);
return;
}
diff --git a/update-checklist.txt b/update-checklist.txt
index 8a0ec82..53cec11 100644
--- a/update-checklist.txt
+++ b/update-checklist.txt
@@ -5,3 +5,5 @@
- Add a new version entry in the changelog
- Check all TO-DOs and complete any that can quickly be completed
+
+- Make sure the new changelog entry reflects the new changes;