blob: 549bdf91f22c50d38c337d7b3bd15a312f6ef284 [file] [edit]
#include <assert.h>
#include <dirent.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <emscripten/console.h>
#include <emscripten/wasmfs.h>
// Define WASMFS_SETUP then WASMFS_RESUME to run the test as two separate
// programs to test persistence. Alternatively, define neither and run the full
// test as a single program.
void cleanup(void);
int main(int argc, char* argv[]) {
int err, fd;
const char* msg = "Hello, OPFS!";
emscripten_console_log("starting main");
backend_t opfs = wasmfs_create_opfs_backend();
emscripten_console_log("created OPFS backend");
err = wasmfs_create_directory("/opfs", 0777, opfs);
assert(err == 0);
emscripten_console_log("mounted OPFS root directory");
#ifdef WASMFS_RESUME
fd = open("/opfs/working/foo.txt", O_RDWR);
assert(fd > 0);
emscripten_console_log("opened existing OPFS file");
#else // !WASMFS_RESUME
// Remove old files if they exist.
cleanup();
err = mkdir("/opfs/working", 0777);
assert(err == 0);
emscripten_console_log("created OPFS directory");
fd = open("/opfs/working/foo.txt", O_RDWR | O_CREAT | O_EXCL, 0777);
assert(fd > 0);
emscripten_console_log("created OPFS file");
int nwritten = write(fd, msg, strlen(msg));
assert(nwritten == strlen(msg));
emscripten_console_logf("wrote message: %s (%d)", msg, nwritten);
int off = lseek(fd, 0, SEEK_SET);
assert(off == 0);
emscripten_console_log("seeked");
#endif // !WASMFS_RESUME
char buf[100] = {};
int nread = read(fd, buf, 100);
assert(nread == strlen(msg));
assert(strcmp(buf, msg) == 0);
emscripten_console_logf("read message: %s (%d)", buf, nread);
fdatasync(fd);
emscripten_console_log("flushed");
struct stat stat_buf;
err = fstat(fd, &stat_buf);
assert(err == 0);
assert(stat_buf.st_size == strlen(msg));
emscripten_console_log("statted");
#ifndef WASMFS_SETUP
err = ftruncate(fd, 100);
assert(err == 0);
err = fstat(fd, &stat_buf);
assert(err == 0);
assert(stat_buf.st_size == 100);
emscripten_console_log("truncated to 100");
err = ftruncate(fd, 1);
assert(err == 0);
err = fstat(fd, &stat_buf);
assert(err == 0);
assert(stat_buf.st_size == 1);
emscripten_console_log("truncated to 1");
struct dirent** entries;
int nentries = scandir("/opfs/working", &entries, NULL, alphasort);
assert(nentries == 3);
assert(strcmp(entries[0]->d_name, ".") == 0);
assert(strcmp(entries[1]->d_name, "..") == 0);
assert(strcmp(entries[2]->d_name, "foo.txt") == 0);
assert(entries[2]->d_type == DT_REG);
for (int i = 0; i < nentries; i++) {
free(entries[i]);
}
free(entries);
emscripten_console_log("read /opfs/working entries");
nentries = scandir("/opfs", &entries, NULL, alphasort);
assert(nentries == 3);
assert(strcmp(entries[2]->d_name, "working") == 0);
assert(entries[2]->d_type == DT_DIR);
for (int i = 0; i < nentries; i++) {
free(entries[i]);
}
free(entries);
emscripten_console_log("read /opfs entries");
err = close(fd);
assert(err == 0);
emscripten_console_log("closed file");
err = stat("/opfs/working/foo.txt", &stat_buf);
assert(err == 0);
assert(stat_buf.st_size == 1);
emscripten_console_log("statted");
err = rename("/opfs/working/foo.txt", "/opfs/foo.txt");
assert(err == 0);
err = access("/opfs/working/foo.txt", F_OK);
assert(err == -1);
err = access("/opfs/foo.txt", F_OK);
assert(err == 0);
emscripten_console_log("moved file");
err = unlink("/opfs/foo.txt");
assert(err == 0);
err = access("/opfs/foo.txt", F_OK);
assert(err == -1);
emscripten_console_log("removed OPFS file");
err = rmdir("/opfs/working");
assert(err == 0);
err = access("/opfs/working", F_OK);
assert(err == -1);
emscripten_console_log("removed OPFS directory");
emscripten_console_log("done");
#endif // !WASMFS_SETUP
}
void cleanup(void) {
printf("cleaning up\n");
unlink("/opfs/working/foo.txt");
rmdir("/opfs/working");
unlink("/opfs/foo.txt");
assert(access("/opfs/working/foo.txt", F_OK) != 0);
assert(access("/opfs/working", F_OK) != 0);
assert(access("/opfs/foo.txt", F_OK) != 0);
}