add mmap_file
[libjh.git] / io.c
diff --git a/io.c b/io.c
index d5f9fa5..a7696f9 100644 (file)
--- a/io.c
+++ b/io.c
@@ -9,6 +9,8 @@ HEADER #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <string.h>
+#include <assert.h>
+#include <sys/mman.h>
 
 // Wrapper for `read` that retries on partial reads.
 // If last_res is non-NULL, it will be filled with the
 
 // Wrapper for `read` that retries on partial reads.
 // If last_res is non-NULL, it will be filled with the
@@ -112,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) {
 }
 
 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;
   if (fd == -1) return NULL;
   char *res = slurp_fd(fd, len_out, flags);
   int errno_ = errno;
@@ -126,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);
   
 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;
   if (fd == -1) return 1;
   ssize_t write_res = write_nointr(fd, buf, len, NULL);
   int write_errno = errno;
@@ -138,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;
 }
   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;
+}