Annotation of /trunk/mkinitrd-magellan/klibc/usr/kinit/readfile.c
Parent Directory | Revision Log
Revision 815 -
(hide annotations)
(download)
Fri Apr 24 18:32:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 1492 byte(s)
Fri Apr 24 18:32:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 1492 byte(s)
-updated to klibc-1.5.15
1 | niro | 532 | /* |
2 | * Read the entire contents of a file into malloc'd storage. This | ||
3 | * is mostly useful for things like /proc files where we can't just | ||
4 | * fstat() to get the length and then mmap(). | ||
5 | * | ||
6 | * Returns the number of bytes read, or -1 on error. | ||
7 | */ | ||
8 | |||
9 | #include <stdlib.h> | ||
10 | #include <stdio.h> | ||
11 | #include <errno.h> | ||
12 | #include <sys/stat.h> | ||
13 | |||
14 | niro | 815 | #include "kinit.h" |
15 | |||
16 | niro | 532 | ssize_t freadfile(FILE *f, char **pp) |
17 | { | ||
18 | size_t bs; /* Decent starting point... */ | ||
19 | size_t bf; /* Bytes free */ | ||
20 | size_t bu = 0; /* Bytes used */ | ||
21 | char *buffer, *nb; | ||
22 | size_t rv; | ||
23 | int old_errno = errno; | ||
24 | |||
25 | bs = BUFSIZ; /* A guess as good as any */ | ||
26 | bf = bs; | ||
27 | buffer = malloc(bs); | ||
28 | |||
29 | if (!buffer) | ||
30 | return -1; | ||
31 | |||
32 | for (;;) { | ||
33 | errno = 0; | ||
34 | |||
35 | while (bf && (rv = _fread(buffer + bu, bf, f))) { | ||
36 | bu += rv; | ||
37 | bf -= rv; | ||
38 | } | ||
39 | |||
40 | if (errno && errno != EINTR && errno != EAGAIN) { | ||
41 | /* error */ | ||
42 | free(buffer); | ||
43 | return -1; | ||
44 | } | ||
45 | |||
46 | if (bf) { | ||
47 | /* Hit EOF, no error */ | ||
48 | |||
49 | /* Try to free superfluous memory */ | ||
50 | if ((nb = realloc(buffer, bu + 1))) | ||
51 | buffer = nb; | ||
52 | |||
53 | /* Null-terminate result for good measure */ | ||
54 | buffer[bu] = '\0'; | ||
55 | |||
56 | *pp = buffer; | ||
57 | errno = old_errno; | ||
58 | return bu; | ||
59 | } | ||
60 | |||
61 | /* Double the size of the buffer */ | ||
62 | bf += bs; | ||
63 | bs += bs; | ||
64 | if (!(nb = realloc(buffer, bs))) { | ||
65 | /* out of memory error */ | ||
66 | free(buffer); | ||
67 | return -1; | ||
68 | } | ||
69 | buffer = nb; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | ssize_t readfile(const char *filename, char **pp) | ||
74 | { | ||
75 | FILE *f = fopen(filename, "r"); | ||
76 | ssize_t rv; | ||
77 | |||
78 | if (!f) | ||
79 | return -1; | ||
80 | |||
81 | rv = freadfile(f, pp); | ||
82 | |||
83 | fclose(f); | ||
84 | |||
85 | return rv; | ||
86 | } |