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