Replaced auto_temp_file with temp_file, which handles creation as well as deletion.
authorBen Hutchings <ben@decadent.org.uk>
Sun, 27 Nov 2005 20:52:08 +0000 (20:52 +0000)
committerBen Hutchings <ben@decadent.org.uk>
Sun, 2 Nov 2008 23:19:45 +0000 (23:19 +0000)
auto_temp_file.hpp [deleted file]
framebuffer.cpp
framebuffer.hpp
temp_file.cpp [new file with mode: 0644]
temp_file.hpp [new file with mode: 0644]

diff --git a/auto_temp_file.hpp b/auto_temp_file.hpp
deleted file mode 100644 (file)
index 5aa3961..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#ifndef INC_AUTO_TEMP_FILE_HPP
-#define INC_AUTO_TEMP_FILE_HPP
-
-#include "auto_handle.hpp"
-
-#include <string>
-
-#include <unistd.h>
-
-struct auto_temp_file_closer
-{
-    void operator()(const std::string & name) const
-       {
-           if (!name.empty())
-               unlink(name.c_str());
-       }
-};
-struct auto_temp_file_factory
-{
-    std::string operator()() const { return std::string(); }
-};
-typedef auto_handle<std::string, auto_temp_file_closer, auto_temp_file_factory>
-    auto_temp_file;
-
-#endif // !INC_AUTO_TEMP_FILE_HPP
index eab879a..c9dc31f 100644 (file)
@@ -1,6 +1,8 @@
 // Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
 // See the file "COPYING" for licence details.
 
+#include "framebuffer.hpp"
+
 #include <cassert>
 #include <cstdio>
 #include <cstring>
@@ -15,8 +17,8 @@
 #include <unistd.h>
 #include <wait.h>
 
-#include "framebuffer.hpp"
 #include "auto_fd.hpp"
+#include "temp_file.hpp"
 
 namespace
 {
@@ -56,18 +58,9 @@ namespace
            throw std::runtime_error(std::strerror(errno));
     }
 
-    auto_temp_file create_temp_auth_file(int display_num)
+    std::auto_ptr<temp_file> create_temp_auth_file(int display_num)
     {
-       char auth_file_name[] = "/tmp/Xvfb-auth-XXXXXX";
-       auto_fd auth_file_fd(mkstemp(auth_file_name));
-       if (auth_file_fd.get() == -1)
-           throw std::runtime_error(std::strerror(errno));
-       auto_temp_file auth_file(auth_file_name);
-
-       // mkstemp may use lax permissions, so fix that before writing
-       // the auth data to it.
-       fchmod(auth_file_fd.get(), S_IREAD|S_IWRITE);
-       ftruncate(auth_file_fd.get(), 0);
+       std::auto_ptr<temp_file> auth_file(new temp_file("Xvfb-auth-"));
 
        // An xauth entry consists of the following fields.  All u16 fields
        // are big-endian and unaligned.  Character arrays are not null-
@@ -82,27 +75,27 @@ namespace
        // u16     length of auth data (= 16)
        // char[]  auth data (= random bytes)
        uint16_t family = htons(0x100);
-       write(auth_file_fd.get(), &family, sizeof(family));
+       write(auth_file->get_fd(), &family, sizeof(family));
        utsname my_uname;
        uname(&my_uname);
        uint16_t len = htons(strlen(my_uname.nodename));
-       write(auth_file_fd.get(), &len, sizeof(len));
-       write(auth_file_fd.get(),
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(),
              my_uname.nodename, strlen(my_uname.nodename));
        char display[15];
        std::sprintf(display, "%d", display_num);
        len = htons(strlen(display));
-       write(auth_file_fd.get(), &len, sizeof(len));
-       write(auth_file_fd.get(), display, strlen(display));
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(), display, strlen(display));
        static const char auth_type[] = "MIT-MAGIC-COOKIE-1";
        len = htons(sizeof(auth_type) - 1);
-       write(auth_file_fd.get(), &len, sizeof(len));
-       write(auth_file_fd.get(), auth_type, sizeof(auth_type) - 1);
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(), auth_type, sizeof(auth_type) - 1);
        unsigned char auth_key[16];
        get_random_bytes(auth_key, sizeof(auth_key));
        len = htons(sizeof(auth_key));
-       write(auth_file_fd.get(), &len, sizeof(len));
-       write(auth_file_fd.get(), auth_key, sizeof(auth_key));
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(), auth_key, sizeof(auth_key));
 
        return auth_file;
     }
@@ -167,7 +160,7 @@ FrameBuffer::FrameBuffer(int width, int height, int depth)
 
 std::string FrameBuffer::get_x_authority() const
 {
-    return auth_file_.get();
+    return auth_file_->get_name();
 }
 
 std::string FrameBuffer::get_x_display() const
index daf7659..ee2557b 100644 (file)
@@ -4,10 +4,11 @@
 #ifndef INC_FRAMEBUFFER_HPP
 #define INC_FRAMEBUFFER_HPP
 
+#include <memory>
 #include <string>
 
 #include "auto_proc.hpp"
-#include "auto_temp_file.hpp"
+#include "temp_file.hpp"
 
 // Run Xvfb with a frame buffer of the given dimensions.
 class FrameBuffer
@@ -19,7 +20,7 @@ public:
 
 private:
     int display_num_;
-    auto_temp_file auth_file_;
+    std::auto_ptr<temp_file> auth_file_;
     auto_kill_proc server_proc_;
 };
 
diff --git a/temp_file.cpp b/temp_file.cpp
new file mode 100644 (file)
index 0000000..6b8165c
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#include "temp_file.hpp"
+
+#include <cassert>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <stdexcept>
+#include <vector>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <glibmm/fileutils.h>
+
+temp_file::temp_file(const std::string & base_name)
+{
+    fd_ = Glib::file_open_tmp(name_, base_name);
+    assert(fd_ >= 0);
+
+    // Workaround bug in glibc <2.2 that may cause the file to be
+    // created with lax permissions.
+#   ifdef __GLIBC__
+#   if !__GLIBC_PREREQ(2, 2)
+    if (fchmod(fd_, S_IREAD|S_IWRITE) != 0 || ftruncate(fd_, 0) != 0)
+    {
+       close(fd_);
+       throw std::runtime_error(std::strerror(errno));
+    }
+#   endif
+#   endif
+}
+
+temp_file::~temp_file()
+{
+    close();
+
+    // Don't assert that this is successful.  The file could have
+    // been removed by another process.
+    unlink(name_.c_str());
+}
+
+void temp_file::close()
+{
+    if (fd_ >= 0)
+    {
+       int result = ::close(fd_);
+       assert(result == 0);
+       fd_ = -1;
+    }
+}
diff --git a/temp_file.hpp b/temp_file.hpp
new file mode 100644 (file)
index 0000000..7402fe9
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#ifndef INC_TEMP_FILE_HPP
+#define INC_TEMP_FILE_HPP
+
+#include <string>
+
+class temp_file
+{
+public:
+    explicit temp_file(const std::string & base_name);
+    ~temp_file();
+
+    void close();
+
+    int get_fd() const { return fd_; }
+    const std::string & get_name() const { return name_; }
+
+private:
+    int fd_;
+    std::string name_;
+};
+
+#endif // !INC_TEMP_FILE_HPP