// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
// See the file "COPYING" for licence details.
+#include "framebuffer.hpp"
+
#include <cassert>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <wait.h>
-#include "framebuffer.hpp"
#include "auto_fd.hpp"
+#include "temp_file.hpp"
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-
// 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;
}
std::string FrameBuffer::get_x_authority() const
{
- return auth_file_.get();
+ return auth_file_->get_name();
}
std::string FrameBuffer::get_x_display() const
--- /dev/null
+// 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;
+ }
+}