/// // Copyright (C) 2003, 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "tempfile.h" #include "warning.h" #include "filesys.h" #include "os.h" #include #include namespace { std::string get_tmplate(std::string base) { base += "XXXXXX"; if(base[0] != '/') { const std::string tmpdir(os::get_env("TMPDIR")); if(tmpdir != "") { base = tmpdir + '/' + base; } else { base = "/tmp/" + base; } } /// \todo verbose is not initialized when the constructor is executed verbose << "Temp file base is " << base << std::endl; return base; } } std::string Tempfile::tmplate; // Note: This method creates the temp file with suitable permissions, but then // it closes it for anything to reopen rather than using the actual fd where // the file is open. /// \todo Create and use a new version // tmpfile() is said to be more portable std::string Tempfile::find_new_name() { // in case the tmplate has not been initialized: if(tmplate.empty()) tmplate = get_tmplate("foo"); char* templ = strdup(tmplate.c_str()); /// \todo possible security problem - change umask int fd = mkstemp(templ); if(fd == -1) throw std::runtime_error("Failed to create temp file."); close(fd); std::string result(templ); free(templ); return result; } void Tempfile::set_prefix(const std::string &prefix) { tmplate = get_tmplate(prefix); } Tempfile::Tempfile(): filename(find_new_name()) {} Tempfile::~Tempfile() { // delete the temp file try { unlink(filename); } catch(std::exception& err) { warning << "Failed to delete " << filename << ", " << err.what() << std::endl; } }