]> git.decadent.org.uk Git - videolink.git/blobdiff - temp_file.cpp
Release versions 1.2.11 and 1.2.11-1
[videolink.git] / temp_file.cpp
index fc4106c27bc658e3377afae4caf9ea8ebcdb0e75..e1c139e12d3e510c998dd01cefd2ab2578b4bbc7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2005 Ben Hutchings <ben@decadent.org.uk>.
+// Copyright 2005-6 Ben Hutchings <ben@decadent.org.uk>.
 // See the file "COPYING" for licence details.
 
 #include "temp_file.hpp"
@@ -7,6 +7,8 @@
 #include <cerrno>
 #include <cstdlib>
 #include <cstring>
+#include <iostream>
+#include <ostream>
 #include <stdexcept>
 #include <vector>
 
 #include <unistd.h>
 
 #include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+
+namespace
+{
+    bool try_rmdir_recursive(const std::string & dir_name)
+    {
+       Glib::Dir dir(dir_name);
+       bool empty = true;
+
+       for (Glib::Dir::iterator it = dir.begin(), end = dir.end();
+            it != end;
+            ++it)
+       {
+           std::string full_name(Glib::build_filename(dir_name, *it));
+           if (!(Glib::file_test(full_name, Glib::FILE_TEST_IS_DIR)
+                 ? try_rmdir_recursive(full_name)
+                 : (unlink(full_name.c_str()) == 0 || errno == ENOENT)))
+               empty = false;
+       }
+
+       return empty && (rmdir(dir_name.c_str()) == 0 || errno == ENOENT);
+    }
+
+    bool do_keep_all = false;
+}
 
 temp_file::temp_file(const std::string & base_name)
 {
@@ -37,7 +64,7 @@ temp_file::~temp_file()
 {
     close();
 
-    if (!keep_)
+    if (!do_keep_all)
     {
        // Don't assert that this is successful.  The file could have
        // been removed by another process.
@@ -55,9 +82,33 @@ void temp_file::close()
     }
 }
 
-bool temp_file::keep_ = false;
-
 void temp_file::keep_all(bool keep)
 {
-    keep_ = keep;
+    do_keep_all = keep;
+}
+
+temp_dir::temp_dir(const std::string & base_name)
+{
+    std::string tmp_dir_name(Glib::get_tmp_dir());
+    std::vector<char> template_name;
+    template_name.reserve(tmp_dir_name.size() + 1 + base_name.size() + 6 + 1);
+    name_.reserve(tmp_dir_name.size() + 1 + base_name.size() + 6);
+    template_name.assign(tmp_dir_name.begin(), tmp_dir_name.end());
+    template_name.insert(template_name.end(), '/');
+    template_name.insert(template_name.end(),
+                        base_name.begin(), base_name.end());
+    template_name.insert(template_name.end(), 6, 'X');
+    template_name.insert(template_name.end(), '\0');
+    if (mkdtemp(&template_name[0]))
+       name_.assign(template_name.begin(), template_name.end() - 1);
+    else
+       throw std::runtime_error(
+           std::string("mkdtemp: ").append(std::strerror(errno)));
+}
+
+temp_dir::~temp_dir()
+{
+    if (!do_keep_all && !try_rmdir_recursive(name_))
+       std::cerr << "WARN: Failed to remove temporary directory "
+                 << name_ << "\n";
 }