60 lines
1.0 KiB
C
60 lines
1.0 KiB
C
|
|
#include <sys/stat.h>
|
|
#include <sys/mman.h>
|
|
#include <fcntl.h>
|
|
#include <stddef.h>
|
|
#include <unistd.h>
|
|
#include "s8slice.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
enum {
|
|
OS_READ = 1<<0,
|
|
OS_WRITE = 1<<1,
|
|
OS_ALLFLAGS = (1<<2)-1
|
|
};
|
|
typedef unsigned int os_open_flags;
|
|
|
|
S8Slice os_open_file(S8Slice path, os_open_flags flags)
|
|
{
|
|
int oflag = 0;
|
|
switch (flags & (OS_ALLFLAGS)) {
|
|
case OS_READ:
|
|
oflag = O_RDONLY;
|
|
break;
|
|
case OS_WRITE:
|
|
oflag = O_WRONLY;
|
|
break;
|
|
case OS_READ | OS_WRITE:
|
|
oflag = O_RDWR;
|
|
}
|
|
int fd = open((const char*)path.data, oflag);
|
|
if (fd == -1) {
|
|
goto open_fail;
|
|
}
|
|
|
|
struct stat st;
|
|
int ok = fstat(fd, &st);
|
|
if (ok == -1) {
|
|
goto fstat_fail;
|
|
}
|
|
|
|
int prot = 0;
|
|
if (flags & OS_READ) prot |= PROT_READ;
|
|
if (flags & OS_WRITE) prot |= PROT_WRITE;
|
|
void *x = mmap(NULL, st.st_size, prot, MAP_SHARED, fd, 0);
|
|
if (x == MAP_FAILED) {
|
|
goto mmap_fail;
|
|
}
|
|
|
|
close(fd);
|
|
|
|
return (S8Slice){.data = x, .len = (int64_t)st.st_size};
|
|
|
|
mmap_fail:
|
|
fstat_fail:
|
|
close(fd);
|
|
open_fail:
|
|
return (S8Slice){.len = -1, .data = (uint8_t*)"<open_file error type>"};
|
|
}
|