diff options
author | mattkae <mattkae@protonmail.com> | 2022-05-11 09:23:58 -0400 |
---|---|---|
committer | mattkae <mattkae@protonmail.com> | 2022-05-11 09:23:58 -0400 |
commit | 3f4a0d5370ae6c34afe180df96add3b8522f4af1 (patch) | |
tree | ae901409e02bde8ee278475f8cf6818f8f680a60 /elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp |
initial commit
Diffstat (limited to 'elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp')
-rw-r--r-- | elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp b/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp new file mode 100644 index 0000000..e7393e1 --- /dev/null +++ b/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp @@ -0,0 +1,74 @@ +/** + * \file + * \author Guillaume Papin <guillaume.papin@epitech.eu> + * + * This file is distributed under the GNU General Public License. See + * COPYING for details. + */ + +#include "TemporaryFile.h" + +#include <algorithm> +#include <cstdio> +#include <cstdlib> +#include <fstream> +#include <iostream> +#include <random> + +static std::string getTemporaryFileDirectory() { + const char *temporaryDirEnvVars[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; + + for (const char *envVar : temporaryDirEnvVars) { + if (const char *dir = std::getenv(envVar)) + return dir; + } + + return "/tmp"; +} + +TemporaryFile::TemporaryFile(const std::string &prefix, + const std::string &suffix) + : pathOrPattern_(prefix + "-%%%%%%" + suffix) { +} + +TemporaryFile::~TemporaryFile() { + if (openedFile_) { + openedFile_.reset(); + std::remove(pathOrPattern_.c_str()); + } +} + +const std::string &TemporaryFile::getPath() { + if (!openedFile_) { + openedFile_.reset(new std::fstream); + + std::random_device rd; + std::default_random_engine e(rd()); + std::uniform_int_distribution<int> dist(0, 15); + std::string pattern = pathOrPattern_; + std::string tmpDir = getTemporaryFileDirectory() + "/"; + int i = 0; + + do { + // exiting is better than infinite loop + if (++i > TemporaryFile::MAX_ATTEMPS) { + std::cerr << "error: couldn't create temporary file, please check your " + "temporary file directory (" << tmpDir << ")\n"; + exit(EXIT_FAILURE); + } + + // make the filename based on the pattern + std::transform(pattern.begin(), + pattern.end(), + pathOrPattern_.begin(), + [&e, &dist](char ch) { + return ch == '%' ? "0123456789abcdef"[dist(e)] : ch; + }); + // create the file + openedFile_->open(tmpDir + pathOrPattern_, std::ios_base::out); + } while (!openedFile_->is_open()); + pathOrPattern_ = tmpDir + pathOrPattern_; + } + + return pathOrPattern_; +} |