]> git.sesse.net Git - cubemap/blobdiff - util.cpp
Add suppor for raw (non-Metacube) inputs over HTTP. Only really useful for TS.
[cubemap] / util.cpp
index a5d6378fd6817ac5921f7009e7a1b9166794dd43..a85de446a87f9451610f90c401f716e2fab86e5e 100644 (file)
--- a/util.cpp
+++ b/util.cpp
@@ -2,24 +2,37 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
+#include "log.h"
 #include "util.h"
 
+#ifndef O_TMPFILE
+#define __O_TMPFILE 020000000
+#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+#endif
+
 using namespace std;
 
-int make_tempfile(const std::string &contents)
+int make_tempfile(const string &contents)
 {
-       char filename[] = "/tmp/cubemap.XXXXXX";
-       int fd = mkstemp(filename);
+       int fd = open("/tmp", O_RDWR | O_TMPFILE, 0600);
        if (fd == -1) {
-               perror("mkstemp");
-               return -1;
-       }
+               char filename[] = "/tmp/cubemap.XXXXXX";
+               mode_t old_umask = umask(077);
+               fd = mkstemp(filename);
+               if (fd == -1) {
+                       log_perror("mkstemp");
+                       return -1;
+               }
+               umask(old_umask);
 
-       if (unlink(filename) == -1) {
-               perror("unlink");
-               // Can still continue;
+               if (unlink(filename) == -1) {
+                       log_perror("unlink");
+                       // Can still continue.
+               }
        }
 
        const char *ptr = contents.data();
@@ -27,8 +40,8 @@ int make_tempfile(const std::string &contents)
        while (to_write > 0) {
                ssize_t ret = write(fd, ptr, to_write);
                if (ret == -1) {
-                       perror("write");
-                       close(fd);
+                       log_perror("write");
+                       safe_close(fd);
                        return -1;
                }
 
@@ -39,37 +52,57 @@ int make_tempfile(const std::string &contents)
        return fd;
 }
 
-bool read_tempfile(int fd, std::string *contents)
+bool read_tempfile_and_close(int fd, string *contents)
 {
+       bool ok = read_tempfile(fd, contents);
+       safe_close(fd);  // Implicitly deletes the file.
+       return ok;
+}
+
+bool read_tempfile(int fd, string *contents)
+{
+       ssize_t ret, has_read;
+
+       off_t len = lseek(fd, 0, SEEK_END);
+       if (len == -1) {
+               log_perror("lseek");
+               return false;
+       }
+
+       contents->resize(len);
+
        if (lseek(fd, 0, SEEK_SET) == -1) {
-               perror("lseek");
+               log_perror("lseek");
                return false;
        }
 
-       char buf[4096];
-       for ( ;; ) {
-               ssize_t ret = read(fd, buf, sizeof(buf));
+       has_read = 0;
+       while (has_read < len) {
+               ret = read(fd, &((*contents)[has_read]), len - has_read);
                if (ret == -1) {
-                       perror("read");
+                       log_perror("read");
                        return false;
                }
                if (ret == 0) {
-                       // EOF.
-                       break;
+                       log(ERROR, "Unexpected EOF!");
+                       return false;
                }
-
-               contents->append(string(buf, buf + ret));
+               has_read += ret;
        }
 
+       return true;
+}
+
+int safe_close(int fd)
+{
        int ret;
        do {
-               ret = close(fd);  // Implicitly deletes the files.
+               ret = close(fd);
        } while (ret == -1 && errno == EINTR);
-       
+
        if (ret == -1) {
-               perror("close");
-               // Can still continue.
+               log_perror("close()");
        }
 
-       return true;
+       return ret;
 }