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