]> git.tdb.fi Git - ext/subsurface.git/blob - file.c
Split up file reading from 'parse-xml.c' into 'file.c'
[ext/subsurface.git] / file.c
1 #include <unistd.h>
2 #include <fcntl.h>
3 #include <sys/stat.h>
4 #include <stdlib.h>
5 #include <errno.h>
6
7 #include "dive.h"
8
9 struct memblock {
10         void *buffer;
11         size_t size;
12 };
13
14 static int readfile(const char *filename, struct memblock *mem)
15 {
16         int ret, fd = open(filename, O_RDONLY);
17         struct stat st;
18
19         mem->buffer = NULL;
20         mem->size = 0;
21
22         fd = open(filename, O_RDONLY);
23         if (fd < 0)
24                 return fd;
25         ret = fstat(fd, &st);
26         if (ret < 0)
27                 goto out;
28         ret = -EINVAL;
29         if (!S_ISREG(st.st_mode))
30                 goto out;
31         ret = 0;
32         if (!st.st_size)
33                 goto out;
34         mem->buffer = malloc(st.st_size);
35         ret = -1;
36         errno = ENOMEM;
37         if (!mem->buffer)
38                 goto out;
39         mem->size = st.st_size;
40         ret = read(fd, mem->buffer, mem->size);
41         if (ret < 0)
42                 goto free;
43         if (ret == mem->size)
44                 goto out;
45         errno = EIO;
46         ret = -1;
47 free:
48         free(mem->buffer);
49         mem->buffer = NULL;
50         mem->size = 0;
51 out:
52         close(fd);
53         return ret;
54 }
55
56 void parse_file(const char *filename, GError **error)
57 {
58         struct memblock mem;
59
60         if (readfile(filename, &mem) < 0) {
61                 fprintf(stderr, "Failed to read '%s'.\n", filename);
62                 if (error) {
63                         *error = g_error_new(g_quark_from_string("subsurface"),
64                                              DIVE_ERROR_PARSE,
65                                              "Failed to read '%s'",
66                                              filename);
67                 }
68                 return;
69         }
70
71         parse_xml_buffer(filename, mem.buffer, mem.size, error);
72         free(mem.buffer);
73 }