From 9afe5355e90bbb6b6c636f871b6eb461a957b0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Fri, 18 Oct 2019 00:00:02 +0000 Subject: [PATCH] userland: add some random filesystem and random stuff Some moved from C++, some moved from SO, some I just made up. --- README.adoc | 4 ++ path_properties.py | 3 ++ userland/cpp/file_write_read.cpp | 2 +- userland/cpp/random.cpp | 22 ++++++++++ userland/cpp/temporary_directory.cpp | 61 ++++++++++++++++++++++++++++ userland/linux/open_o_tmpfile.c | 39 ++++++++++++++++++ 6 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 userland/cpp/random.cpp create mode 100644 userland/cpp/temporary_directory.cpp create mode 100644 userland/linux/open_o_tmpfile.c diff --git a/README.adoc b/README.adoc index 51e7864..7fa688f 100644 --- a/README.adoc +++ b/README.adoc @@ -13386,6 +13386,7 @@ Good sanity check for user mode: <> *** link:userland/c/stderr.c[] *** File IO **** link:userland/c/file_write_read.c[] +**** link:userland/linux/open_o_tmpfile.c[]: https://stackoverflow.com/questions/4508998/what-is-an-anonymous-inode-in-linux/44388030#44388030 * Fun ** link:userland/c/loop.c[] @@ -13542,6 +13543,9 @@ Programs under link:userland/cpp/[] are examples of https://en.wikipedia.org/wik ** link:userland/cpp/if_constexpr.cpp[]: C++17 `if constexpr` * fstream ** link:userland/cpp/file_write_read.cpp[] +** link:userland/cpp/temporary_directory.cpp[]: https://stackoverflow.com/questions/3379956/how-to-create-a-temporary-directory-in-c/58454949#58454949 +* random +** link:userland/cpp/random.cpp[] [[cpp-multithreading]] ==== C++ multithreading diff --git a/path_properties.py b/path_properties.py index 82aaf85..7815ab5 100644 --- a/path_properties.py +++ b/path_properties.py @@ -508,6 +508,9 @@ path_properties_tuples = ( 'gem5_unimplemented_instruction': True, }, 'count.cpp': {'more_than_1s': True}, + # Need to pass -lstdc++fs but we don't have a mechanism + # to test the GCC version and only pass if >= 7. + 'temporary_directory.cpp': {'no_build': True}, 'sleep_for.cpp': { 'more_than_1s': True, }, diff --git a/userland/cpp/file_write_read.cpp b/userland/cpp/file_write_read.cpp index b67733e..c18337f 100644 --- a/userland/cpp/file_write_read.cpp +++ b/userland/cpp/file_write_read.cpp @@ -1,4 +1,4 @@ -/* https://cirosantilli.com/linux-kernel-module-cheat#cpp */ +// https://cirosantilli.com/linux-kernel-module-cheat#cpp #include diff --git a/userland/cpp/random.cpp b/userland/cpp/random.cpp new file mode 100644 index 0000000..742d582 --- /dev/null +++ b/userland/cpp/random.cpp @@ -0,0 +1,22 @@ +// https://cirosantilli.com/linux-kernel-module-cheat#cpp + +#include +#include + +int main(int argc, char **argv) { + // Potentially expensive /dev/urandom read that waits for entropy. + std::random_device dev; + std::mt19937 prng(dev()); + std::uniform_int_distribution zero_ull_max(0); + std::uniform_int_distribution one_to_six(1, 6); + + unsigned long long loops = 1; + if (argc > 1) { + loops = std::stoull(argv[1], NULL, 0); + } + + for (auto i = 0U; i < loops; ++i) { + std::cout << "zero_to_ull_max 0x" << std::hex << zero_ull_max(prng) << std::endl; + std::cout << "one_to_six " << std::dec << one_to_six(prng) << std::endl; + } +} diff --git a/userland/cpp/temporary_directory.cpp b/userland/cpp/temporary_directory.cpp new file mode 100644 index 0000000..7e11f2f --- /dev/null +++ b/userland/cpp/temporary_directory.cpp @@ -0,0 +1,61 @@ +// https://cirosantilli.com/linux-kernel-module-cheat#cpp +// +// ./build disabled for now because of GCC std::filesystem mess. +// Compile manually with: +// g++-8 -std=c++17 -o temporary_directory.out temporary_directory.cpp -lstdc++fs + +#if __cplusplus >= 201703L +#include +#include +#include +#include +#include + +#include + +std::filesystem::path create_temporary_directory(unsigned long long max_tries = 100) { + auto tmp_dir = std::filesystem::temp_directory_path(); + unsigned long long i = 0; + std::random_device dev; + std::mt19937 prng(dev()); + std::uniform_int_distribution rand(0); + std::filesystem::path path; + while (true) { + std::stringstream ss; + ss << std::hex << rand(prng); + path = tmp_dir / ss.str(); + // true if the directory was created. + if (std::filesystem::create_directory(path)) { + break; + } + if (i == max_tries) { + throw std::runtime_error("could not find non-existing directory"); + } + i++; + } + return path; +} + +#endif + +int main() { +#if __cplusplus >= 201703L + std::cout << "temp_directory_path() = " + << std::filesystem::temp_directory_path() + << std::endl; + + auto tmpdir = create_temporary_directory(); + std::cout << "create_temporary_directory() = " + << tmpdir + << std::endl; + + + // Use our temporary directory. + std::ofstream ofs(tmpdir / "myfile"); + ofs << "asdf\nqwer\n"; + ofs.close(); + + // Remove the directory and its contents. + std::filesystem::remove_all(tmpdir); +#endif +} diff --git a/userland/linux/open_o_tmpfile.c b/userland/linux/open_o_tmpfile.c new file mode 100644 index 0000000..47a4cc0 --- /dev/null +++ b/userland/linux/open_o_tmpfile.c @@ -0,0 +1,39 @@ +/* https://cirosantilli.com/linux-kernel-module-cheat#c */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +int main(void) { + char buf[] = { 'a', 'b', 'c', 'd' }; + char buf2[] = { 'e', 'f', 'g', 'h' }; + int f, ret; + size_t off; + + /* Create the temporary file and write to it. */ + f = open(".", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); + ret = write(f, buf, sizeof(buf)); + + /* Interactivelly check if anything changed on directory. It hasn't. */ + /*puts("hit enter to continue");*/ + /*getchar();*/ + + /* Read from the temporary file, and assert that + * we read the same as we wrote. */ + lseek(f, 0, SEEK_SET); + off = 0; + while ((ret = read(f, buf2 + off, sizeof(buf) - off))) { + off += ret; + } + close(f); + assert(!memcmp(buf, buf2, sizeof(buf))); + + /* Assert that the file is gone now that we removed it. */ + + return EXIT_SUCCESS; +}