diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2016-10-05 14:44:36 +0200 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2016-10-05 14:44:36 +0200 |
commit | b4a8090f75c90ec26133344b00a085025da212aa (patch) | |
tree | 9cc00368c48542853cf22621450009582b76ec51 /slurp.c | |
parent | 0b2e4880f5c80a97a8c4577591210185669ddb4a (diff) | |
download | mblaze-b4a8090f75c90ec26133344b00a085025da212aa.tar.gz mblaze-b4a8090f75c90ec26133344b00a085025da212aa.tar.xz mblaze-b4a8090f75c90ec26133344b00a085025da212aa.zip |
seq: slurp the file instead of mmap
mmap is not robust when there are writes possible.
Diffstat (limited to 'slurp.c')
-rw-r--r-- | slurp.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/slurp.c b/slurp.c new file mode 100644 index 0000000..6366e6f --- /dev/null +++ b/slurp.c @@ -0,0 +1,56 @@ +#include <sys/stat.h> +#include <sys/types.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +int +slurp(char *filename, char **bufo, off_t *leno) +{ + int fd; + struct stat st; + ssize_t nread = 0; + ssize_t n; + int r = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + r = errno; + goto out; + } + if (fstat(fd, &st) < 0) { + r = errno; + goto out; + } + if (st.st_size == 0) { + *bufo = ""; + *leno = 0; + return 0; + } + *bufo = malloc(st.st_size); + if (!*bufo) { + r = ENOMEM; + goto out; + } + + do { + if ((n = read(fd, *bufo + nread, st.st_size - nread)) < 0) { + if (errno == EINTR) { + continue; + } else { + r = errno; + goto out; + } + } + if (!n) + break; + nread += n; + } while (nread < st.st_size); + *leno = nread; + +out: + close(fd); + return r; +} |