X-Git-Url: http://git.thejh.net/?p=libjh.git;a=blobdiff_plain;f=io.c;h=a7696f9f7fd74c277b7914483d81c8ad8b7213b8;hp=d3b9a6d5599dfbe170a3d0047a7f44bad41a014c;hb=483ad7514b32f4557c8866bbde2091aed69e98b4;hpb=e3a7f339e843d1424aef577e5634ac70343ec49c diff --git a/io.c b/io.c index d3b9a6d..a7696f9 100644 --- a/io.c +++ b/io.c @@ -1,3 +1,6 @@ +// Copyright (2013) Jann Horn +// This code is licensed under the AGPLv3. + HEADER #include #include #include @@ -6,6 +9,8 @@ HEADER #include #include #include #include +#include +#include // Wrapper for `read` that retries on partial reads. // If last_res is non-NULL, it will be filled with the @@ -109,7 +114,7 @@ PUBLIC_FN char *slurp_fd(int fd, size_t *len_out, int flags) { } PUBLIC_FN char *slurp_file(char *path, size_t *len_out, int flags) { - int fd = open(path, O_RDONLY); + int fd = open(path, O_RDONLY|O_CLOEXEC); if (fd == -1) return NULL; char *res = slurp_fd(fd, len_out, flags); int errno_ = errno; @@ -123,7 +128,7 @@ PUBLIC_FN char *slurp_file(char *path, size_t *len_out, int flags) { PUBLIC_FN int write_file(char *path, char *buf, ssize_t len, int open_flags) { if (len == -1) len = strlen(buf); - int fd = open(path, open_flags, 0777); + int fd = open(path, open_flags|O_CLOEXEC, 0777); if (fd == -1) return 1; ssize_t write_res = write_nointr(fd, buf, len, NULL); int write_errno = errno; @@ -135,3 +140,19 @@ PUBLIC_FN int write_file(char *path, char *buf, ssize_t len, int open_flags) { if (close_res) return 1; return 0; } + +PUBLIC_FN void *mmap_file(void *addr, size_t length, int prot, int flags, char *path, off_t offset) { + assert((flags&MAP_ANONYMOUS) == 0); + assert(prot&(PROT_EXEC|PROT_READ|PROT_WRITE)); + int open_flags = O_CLOEXEC; + if ((prot & (PROT_READ|PROT_EXEC)) && !(prot&PROT_WRITE)) open_flags |= O_RDONLY; + else if ((prot & (PROT_READ|PROT_EXEC))) open_flags |= O_RDWR; + else open_flags |= O_WRONLY; + int fd = open(path, open_flags); + if (fd == -1) return NULL; + void *r = mmap(addr, length, prot, flags, fd, offset); + int errno_ = errno; + close(fd); + errno = errno_; + return (r==MAP_FAILED) ? NULL : r; +}