blob: 39aae619f524a69d913c33305a33a79295c56dea [file]
/*
* Copyright 2026 Rive
*/
// Nintendo's musl derived libc declares these but nnSdk exports no
// definitions, so WAMR's shared posix layer fails to link. The directory
// relative calls back the WASI filesystem, which this platform has no
// equivalent for, so they report ENOSYS; the vectored reads and writes are
// real because they are just loops over the byte oriented calls.
#include <errno.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
extern "C"
{
static int notSupported()
{
errno = ENOSYS;
return -1;
}
int openat(int, const char*, int, ...) { return notSupported(); }
int fstatat(int, const char*, struct stat*, int) { return notSupported(); }
int mkdirat(int, const char*, mode_t) { return notSupported(); }
int renameat(int, const char*, int, const char*) { return notSupported(); }
int unlinkat(int, const char*, int) { return notSupported(); }
// Both report success by errno convention rather than -1, and neither has
// a meaning here: one preallocates, one advises.
int posix_fallocate(int, off_t, off_t) { return ENOSYS; }
int posix_fadvise(int, off_t, off_t, int) { return 0; }
// Named semaphores. nnSdk has the unnamed sem_* family only.
sem_t* sem_open(const char*, int, ...)
{
notSupported();
return SEM_FAILED;
}
int sem_close(sem_t*) { return notSupported(); }
int sem_unlink(const char*) { return notSupported(); }
static ssize_t vectored(int fd,
const struct iovec* iov,
int count,
off_t offset,
bool positional,
bool writing)
{
ssize_t total = 0;
for (int i = 0; i < count; ++i)
{
if (iov[i].iov_len == 0)
{
continue;
}
ssize_t n;
if (writing)
{
n = positional ? pwrite(fd,
iov[i].iov_base,
iov[i].iov_len,
offset + total)
: write(fd, iov[i].iov_base, iov[i].iov_len);
}
else
{
n = positional ? pread(fd,
iov[i].iov_base,
iov[i].iov_len,
offset + total)
: read(fd, iov[i].iov_base, iov[i].iov_len);
}
if (n < 0)
{
return total > 0 ? total : -1;
}
total += n;
// A short transfer ends the whole call, same as the real thing.
if ((size_t)n < iov[i].iov_len)
{
break;
}
}
return total;
}
ssize_t readv(int fd, const struct iovec* iov, int count)
{
return vectored(fd, iov, count, 0, false, false);
}
ssize_t writev(int fd, const struct iovec* iov, int count)
{
return vectored(fd, iov, count, 0, false, true);
}
ssize_t preadv(int fd, const struct iovec* iov, int count, off_t offset)
{
return vectored(fd, iov, count, offset, true, false);
}
ssize_t pwritev(int fd, const struct iovec* iov, int count, off_t offset)
{
return vectored(fd, iov, count, offset, true, true);
}
}