]> git.ozlabs.org Git - ccan/blob - ccan/grab_file/grab_file.c
tdb2: don't cancel transactions on lock failures in tdb1 backend.
[ccan] / ccan / grab_file / grab_file.c
1 /* Licensed under LGPLv2+ - see LICENSE file for details */
2 #include "grab_file.h"
3 #include <ccan/talloc/talloc.h>
4 #include <ccan/noerr/noerr.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9
10 void *grab_fd(const void *ctx, int fd, size_t *size)
11 {
12         int ret;
13         size_t max, s;
14         char *buffer;
15         struct stat st;
16
17         if (!size)
18                 size = &s;
19         *size = 0;
20
21         if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode))
22                 max = st.st_size;
23         else
24                 max = 16384;
25
26         buffer = talloc_array(ctx, char, max+1);
27         while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
28                 *size += ret;
29                 if (*size == max) {
30                         buffer = talloc_realloc(ctx, buffer, char, max*2+1);
31                         if (!buffer) {
32                                 buffer = talloc_realloc(ctx, buffer, char,
33                                                         max + 1024*1024 + 1);
34                                 if (!buffer)
35                                         return NULL;
36                                 max += 1024*1024;
37                         } else
38                                 max *= 2;
39                 }
40         }
41         if (ret < 0) {
42                 talloc_free(buffer);
43                 buffer = NULL;
44         } else
45                 buffer[*size] = '\0';
46
47         return buffer;
48 }
49
50 void *grab_file(const void *ctx, const char *filename, size_t *size)
51 {
52         int fd;
53         char *buffer;
54
55         if (!filename)
56                 fd = dup(STDIN_FILENO);
57         else
58                 fd = open(filename, O_RDONLY, 0);
59
60         if (fd < 0)
61                 return NULL;
62
63         buffer = grab_fd(ctx, fd, size);
64         close_noerr(fd);
65         return buffer;
66 }