]> git.ozlabs.org Git - ccan/blob - tools/grab_file.c
using string.h
[ccan] / tools / grab_file.c
1 #include "tools.h"
2 #include "talloc/talloc.h"
3 #include "string/string.h"
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <errno.h>
9
10 static int close_no_errno(int fd)
11 {
12         int ret = 0, serrno = errno;
13         if (close(fd) < 0)
14                 ret = errno;
15         errno = serrno;
16         return ret;
17 }
18
19 void *grab_fd(const void *ctx, int fd)
20 {
21         int ret;
22         unsigned int max = 16384, size = 0;
23         char *buffer;
24
25         buffer = talloc_array(ctx, char, max+1);
26         while ((ret = read(fd, buffer + size, max - size)) > 0) {
27                 size += ret;
28                 if (size == max)
29                         buffer = talloc_realloc(ctx, buffer, char, max*=2 + 1);
30         }
31         if (ret < 0) {
32                 talloc_free(buffer);
33                 buffer = NULL;
34         } else
35                 buffer[size] = '\0';
36
37         return buffer;
38 }
39
40 /* This version adds one byte (for nul term) */
41 void *grab_file(const void *ctx, const char *filename)
42 {
43         int fd;
44         char *buffer;
45
46         if (streq(filename, "-"))
47                 fd = dup(STDIN_FILENO);
48         else
49                 fd = open(filename, O_RDONLY, 0);
50
51         if (fd < 0)
52                 return NULL;
53
54         buffer = grab_fd(ctx, fd);
55         close_no_errno(fd);
56         return buffer;
57 }
58