#include "io.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
static bool file_read(int fd, char*& buf, size_t& len) {
struct stat ss;
if (fstat(fd, &ss) == -1) {
LOG_ERRNO("fstat()");
close(fd);
return false;
}
len = ss.st_size;
buf = (char*)malloc(len + 1);
if (read(fd, buf, len) != (ssize_t)len) {
LOG("read()");
close(fd);
free(buf);
return false;
}
buf[len] = '\0';
return true;
}
bool file_read(const char* fn, char*& buf, size_t& len) {
int fd = open(fn, O_RDONLY);
if (fd == -1) {
LOG_ERRNO("open(%s)", fn);
return false;
}
bool rv = file_read(fd, buf, len);
close(fd);
return rv;
}
bool file_read_at(const char* dn, unsigned pos, char*& buf, size_t& len) {
DIR* dirp = opendir(dn);
if (!dirp) {
LOG_ERRNO("opendir(%s)", dn);
return false;
}
unsigned num = 0;
struct dirent* dp;
while ((dp = readdir(dirp)) != NULL) {
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue;
++num;
}
rewinddir(dirp);
if (!num) return false;
num = pos % num;
while ((dp = readdir(dirp)) != NULL) {
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue;
if (!num) {
int fd = openat(dirfd(dirp), dp->d_name, O_RDONLY);
if (fd == -1) {
LOG_ERRNO("openat(%s, %s)", dn, dp->d_name);
closedir(dirp);
return false;
}
closedir(dirp);
bool rv = file_read(fd, buf, len);
close(fd);
return rv;
}
--num;
}
closedir(dirp);
return false;
}