| |
| |
| |
| |
| |
| |
|
|
| #include <emscripten/emscripten.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <sys/stat.h> |
| #include <assert.h> |
| #include <fcntl.h> |
|
|
| EM_JS(void, test_fs_open, (), { |
| FS.writeFile('testfile', 'a=1\nb=2\n'); |
| var readStream = FS.open('testfile', 'r'); |
| var writeStream = FS.open('testfile', 'w'); |
| var writePlusStream = FS.open('testfile', 'w+'); |
| var appendStream = FS.open('testfile', 'a'); |
|
|
| assert(readStream && readStream.fd >= 0); |
| assert(writeStream && writeStream.fd >= 0); |
| assert(writePlusStream && writePlusStream.fd >= 0); |
| assert(appendStream && appendStream.fd >= 0); |
|
|
| var ex; |
| try { |
| FS.open('filenothere', 'r'); |
| } catch(err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 44 ); |
|
|
| var createFileNotHere = FS.open('filenothere', 'w+'); |
|
|
| assert(createFileNotHere && createFileNotHere.fd >= 0); |
| }); |
|
|
| EM_JS(void, test_fs_readFile, (), { |
| |
| |
| var ex; |
| try { |
| var output = FS.readFile("root/no-exist", {encoding : 'utf8'}); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 44 ); |
| }); |
|
|
| |
| EM_JS(void, test_fs_createPath, (), { |
| FS.createPath('/', 'home', true, true); |
| FS.createPath('/', 'home', true, true); |
| FS.createPath('/home', 'nested1', true, true); |
| FS.createPath('/home', 'nested2', true, true); |
| FS.writeFile('/home/nested1/test.txt', 'a=1\nb=2\n'); |
| FS.writeFile('/home/nested2/test.txt', 'a=2\nb=4\n'); |
| var read1 = FS.readFile('/home/nested1/test.txt', {encoding:'utf8'}); |
| var read2 = FS.readFile('/home/nested2/test.txt', {encoding:'utf8'}); |
| console.log("r1",read1); |
| console.log("r2",read2); |
| assert(read1 == 'a=1\nb=2\n'); |
| assert(read2 == 'a=2\nb=4\n'); |
| }); |
|
|
| EM_JS(void, test_fs_rename, (), { |
| FS.mkdir('renamedir'); |
| FS.writeFile('renamedir/renametestfile', ""); |
|
|
| FS.rename('renamedir/renametestfile', 'renamedir/newname'); |
| var newnameStream = FS.open('renamedir/newname', 'r'); |
| assert(newnameStream); |
|
|
| var ex; |
| try { |
| FS.open('renamedir/renametestfile', 'r'); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 44 ); |
|
|
| try { |
| FS.rename('renamedir', 'renamedir/newdirname'); |
| } catch (err) { |
| ex = err; |
| } |
| |
| assert(ex.name === "ErrnoError" && ex.errno === 28 ); |
|
|
| FS.writeFile('toplevelfile', ""); |
| try { |
| FS.rename('renamedir', 'toplevelfile'); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 54 ); |
| }); |
|
|
| EM_JS(void, test_fs_readlink,(), { |
| FS.writeFile('/readlinktestfile', ""); |
| FS.symlink('/readlinktestfile', '/readlinksymlink'); |
|
|
| var symlinkString = FS.readlink('readlinksymlink'); |
| assert(symlinkString === '/readlinktestfile'); |
|
|
| var ex; |
| try { |
| FS.readlink('nonexistent'); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 44 ); |
|
|
| try { |
| FS.readlink('readlinktestfile'); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 28 ); |
| }); |
|
|
| EM_JS(void, test_fs_read, (), { |
| FS.writeFile("readtestfile", 'a=1_b=2_'); |
|
|
| |
| var buf = new Uint8Array(8); |
| var stream = FS.open("readtestfile", "r"); |
| var numRead = FS.read(stream, buf, 0, 4); |
| assert(numRead == 4); |
| assert((new TextDecoder().decode(buf.subarray(0, 4))) === "a=1_"); |
| numRead = FS.read(stream, buf, 4, 4); |
| assert(numRead == 4); |
| assert((new TextDecoder().decode(buf)) == 'a=1_b=2_'); |
|
|
| |
| stream = FS.open("readtestfile", "r"); |
| var extraBuf = new Uint8Array(8); |
| numRead = FS.read(stream, extraBuf, 0, 4, 0); |
| assert(numRead == 4); |
| assert((new TextDecoder().decode(extraBuf.subarray(0, 4))) == 'a=1_'); |
|
|
| |
| var doubleBuf = new Uint8Array(8); |
| var firstNumRead = FS.read(stream, doubleBuf, 0, 4); |
| var secondNumRead = FS.read(stream, doubleBuf, 4, 4); |
| assert(firstNumRead == 4 && secondNumRead == 4); |
| assert((new TextDecoder().decode(doubleBuf)) == 'a=1_b=2_'); |
|
|
| |
| stream = FS.open("readtestfile", "r"); |
| var fullBuf = new Uint8Array(8); |
| numRead = FS.read(stream, fullBuf, 0, 8); |
| assert(numRead == 8); |
| assert((new TextDecoder().decode(fullBuf)) == 'a=1_b=2_'); |
|
|
| FS.close(stream); |
| var ex; |
| try { |
| FS.read(stream, buf, 4, 4); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === 'ErrnoError' && ex.errno == 8 ); |
| }); |
|
|
| void test_fs_rmdir() { |
| EM_ASM( |
| |
| FS.mkdir('/dir1'); |
| FS.mkdir('/dir2'); |
| ); |
|
|
| struct stat s; |
| stat("/dir1", &s); |
| assert(S_ISDIR(s.st_mode)); |
| stat("/dir2", &s); |
| assert(S_ISDIR(s.st_mode)); |
|
|
| EM_ASM( |
| |
| FS.rmdir('/dir1'); |
| FS.rmdir('/dir2'); |
| ); |
|
|
| int err = open("/dir1", O_RDWR); |
| assert(err); |
| err = open("/dir2", O_RDWR); |
| assert(err); |
|
|
| EM_ASM( |
| |
| FS.mkdir('/test_dir'); |
| FS.writeFile('/test_dir/file.txt', 'Hello World!'); |
|
|
| |
| var ex; |
| try { |
| FS.rmdir('/test_dir'); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 55 ); |
|
|
| |
| FS.unlink('/test_dir/file.txt'); |
| FS.rmdir('/test_dir'); |
|
|
| |
| try { |
| FS.rmdir('/non_existent_dir'); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 44 ); |
| ); |
| } |
|
|
| EM_JS(void, test_fs_close, (), { |
| FS.writeFile("closetestfile", 'a=1\nb=2\n'); |
| FS.mkdir("/testdir"); |
| var file = FS.open("closetestfile", "r"); |
| var error = FS.close(file); |
| assert(!error); |
|
|
| file = FS.open("/testdir", "r"); |
| error = FS.close(file); |
| assert(!error); |
|
|
| var ex; |
| try { |
| FS.close(file); |
| } catch(err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 8 ); |
| }); |
|
|
| void test_fs_mknod() { |
| EM_ASM( |
| FS.mknod("mknodtest", 0o100000 | 0o777 ); |
|
|
| FS.create("createtest", 0o400 ); |
| ); |
| struct stat s; |
| stat("mknodtest", &s); |
|
|
| assert(S_ISREG(s.st_mode)); |
| assert(s.st_mode & 0o777); |
|
|
| stat("createtest", &s); |
| assert(S_ISREG(s.st_mode)); |
| assert(s.st_mode & 0o400); |
|
|
| remove("mknodtest"); |
| remove("createtest"); |
| } |
|
|
| void test_fs_truncate() { |
| EM_ASM( |
| FS.writeFile('truncatetest', 'a=1\nb=2\n'); |
| ); |
|
|
| struct stat s; |
| stat("truncatetest", &s); |
| assert(s.st_size == 8); |
|
|
| EM_ASM( |
| FS.truncate('truncatetest', 2); |
| ); |
| stat("truncatetest", &s); |
| assert(s.st_size == 2); |
|
|
| EM_ASM( |
| FS.truncate('truncatetest', 10); |
| ); |
| stat("truncatetest", &s); |
| assert(s.st_size == 10); |
|
|
| EM_ASM( |
| var truncateStream = FS.open('truncatetest', 'w'); |
| FS.ftruncate(truncateStream.fd, 4); |
| ); |
| stat("truncatetest", &s); |
| assert(s.st_size == 4); |
|
|
| EM_ASM( |
| var ex; |
| try { |
| FS.truncate('truncatetest', -10); |
| } catch(err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 28 ); |
|
|
| try { |
| var truncateStream = FS.open('truncatetest', 'w'); |
| FS.ftruncate(truncateStream.fd, -10); |
| } catch(err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 28 ); |
|
|
| try { |
| FS.truncate('nonexistent', 10); |
| } catch(err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 44 ); |
|
|
| var ex; |
| try { |
| FS.ftruncate(99, 10); |
| } catch(err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 8 ); |
| ); |
|
|
| remove("truncatetest"); |
| } |
|
|
| void test_fs_mmap() { |
| EM_ASM( |
| FS.writeFile('mmaptest', 'a=1_b=2_'); |
|
|
| var stream = FS.open('mmaptest', 'r+'); |
| assert(stream); |
|
|
| var mapped = FS.mmap(stream, 12, 0, 1 | 2 , 1 ); |
| var ret = new Uint8Array(HEAPU8.subarray(mapped.ptr, mapped.ptr + 12)); |
| var fileContents = ""; |
| for (var i = 0; i < 12; i++) { |
| fileContents += String.fromCharCode(ret[i]); |
| } |
| assert(fileContents === 'a=1_b=2_\0\0\0\0'); |
|
|
| ret[8] = ':'.charCodeAt(0); |
| ret[9] = 'x'.charCodeAt(0); |
| ret[10] = 'y'.charCodeAt(0); |
| ret[11] = 'z'.charCodeAt(0); |
| HEAPU8.set(ret, mapped.ptr); |
|
|
| |
| |
| #if WASMFS |
| FS.msync(stream, mapped.ptr, 0, 12, 1 ); |
|
|
| var ex; |
| try { |
| FS.munmap(mapped.ptr, 4); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 28 ); |
|
|
| FS.munmap(mapped.ptr, 12); |
|
|
| |
| try { |
| FS.msync(stream, mapped.ptr, 0, 12, 1 ); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 28 ); |
| #else |
| FS.msync(stream, new Uint8Array(ret), 0, 12, 1 ); |
| FS.munmap(stream); |
| #endif |
| ); |
|
|
| FILE *fptr = fopen("mmaptest", "r"); |
| char res[13]; |
| fgets(res, 13, fptr); |
| assert(strcmp(res, "a=1_b=2_:xyz") == 0); |
|
|
| remove("mmaptest"); |
| } |
|
|
| void test_fs_mkdirTree() { |
| EM_ASM( |
| FS.mkdirTree("/test1/test2/test3"); |
| FS.mkdirTree("/readable", 0o400 ); |
| ); |
|
|
| struct stat s; |
| assert(stat("/test1", &s) == 0); |
| assert(S_ISDIR(s.st_mode)); |
| assert(stat("/test1/test2", &s) == 0); |
| assert(S_ISDIR(s.st_mode)); |
| assert(stat("/test1/test2/test3", &s) == 0); |
| assert(S_ISDIR(s.st_mode)); |
|
|
| assert(stat("/readable", &s) == 0); |
| assert(s.st_mode & 0o400 ); |
|
|
| EM_ASM( |
| var ex; |
| try { |
| FS.mkdirTree("/readable/forbidden"); |
| } catch (err) { |
| ex = err; |
| } |
| assert(ex.name === "ErrnoError" && ex.errno === 2 ); |
| ); |
|
|
| chdir("/test1"); |
| EM_ASM( |
| FS.mkdirTree("foo/bar"); |
| ); |
| chdir("/"); |
|
|
| assert(stat("/test1/foo", &s) == 0); |
| assert(S_ISDIR(s.st_mode)); |
|
|
| assert(stat("/test1/foo/bar", &s) == 0); |
| assert(S_ISDIR(s.st_mode)); |
|
|
| remove("/test1/test2/test3"); |
| remove("/test1/test2"); |
| remove("/test1/foo/bar"); |
| remove("/test1/foo"); |
| remove("/test1"); |
| remove("/readable"); |
| } |
|
|
| void test_fs_utime() { |
| EM_ASM( |
| FS.writeFile('utimetest', 'a=1\nb=2\n'); |
| ); |
|
|
| EM_ASM( |
| FS.utime('utimetest', 10500, 8000); |
| ); |
| struct stat utimeStats; |
| stat("utimetest", &utimeStats); |
|
|
| assert(utimeStats.st_atime == 10); |
| assert(utimeStats.st_atim.tv_sec == 10); |
|
|
| assert(utimeStats.st_atim.tv_nsec == 500000000); |
|
|
| assert(utimeStats.st_mtime == 8); |
| assert(utimeStats.st_mtim.tv_sec == 8); |
|
|
| remove("utimetest"); |
| } |
|
|
| #if !defined(NODERAWFS) |
| |
| |
| |
| |
| |
| |
| |
| |
| #define ABS_PATH_OK |
| #endif |
|
|
| int main() { |
| #ifdef ABS_PATH_OK |
| test_fs_createPath(); |
| test_fs_mkdirTree(); |
| test_fs_close(); |
| test_fs_readlink(); |
| test_fs_rmdir(); |
| #endif |
| test_fs_open(); |
| test_fs_readFile(); |
| test_fs_rename(); |
| test_fs_read(); |
| test_fs_mknod(); |
| test_fs_truncate(); |
| #if WASMFS |
| |
| test_fs_mmap(); |
| #endif |
|
|
| test_fs_utime(); |
|
|
| puts("success"); |
| } |
|
|