Merge branch 'master' of /srv/git.sesse.net/www/cubemap
[cubemap] / util.cpp
1 #include <errno.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6
7 #include "log.h"
8 #include "util.h"
9
10 using namespace std;
11
12 int make_tempfile(const std::string &contents)
13 {
14         char filename[] = "/tmp/cubemap.XXXXXX";
15         int fd = mkstemp(filename);
16         if (fd == -1) {
17                 log_perror("mkstemp");
18                 return -1;
19         }
20
21         if (unlink(filename) == -1) {
22                 log_perror("unlink");
23                 // Can still continue;
24         }
25
26         const char *ptr = contents.data();
27         size_t to_write = contents.size();
28         while (to_write > 0) {
29                 ssize_t ret = write(fd, ptr, to_write);
30                 if (ret == -1) {
31                         log_perror("write");
32                         close(fd);
33                         return -1;
34                 }
35
36                 ptr += ret;
37                 to_write -= ret;
38         }
39
40         return fd;
41 }
42
43 bool read_tempfile(int fd, std::string *contents)
44 {
45         bool ok = true;
46         ssize_t ret, has_read;
47
48         off_t len = lseek(fd, 0, SEEK_END);
49         if (len == -1) {
50                 log_perror("lseek");
51                 ok = false;
52                 goto done;
53         }
54
55         contents->resize(len);
56
57         if (lseek(fd, 0, SEEK_SET) == -1) {
58                 log_perror("lseek");
59                 ok = false;
60                 goto done;
61         }
62
63         has_read = 0;
64         while (has_read < len) {
65                 ret = read(fd, &((*contents)[has_read]), len - has_read);
66                 if (ret == -1) {
67                         log_perror("read");
68                         ok = false;
69                         goto done;
70                 }
71                 if (ret == 0) {
72                         log(ERROR, "Unexpected EOF!");
73                         ok = false;
74                         goto done;
75                 }
76                 has_read += ret;
77         }
78
79 done:
80         do {
81                 ret = close(fd);  // Implicitly deletes the files.
82         } while (ret == -1 && errno == EINTR);
83         
84         if (ret == -1) {
85                 log_perror("close");
86                 // Can still continue.
87         }
88
89         return ok;
90 }