From d341059aaef966f3d9a34519802f451347f679eb Mon Sep 17 00:00:00 2001 From: Michael Bishop Date: Mon, 23 Sep 2013 19:22:37 -0400 Subject: Added FileSystem tracking Support. --- src/library_fs.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/library_fs.js b/src/library_fs.js index d53210f9..e7e194cf 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -26,7 +26,13 @@ mergeInto(LibraryManager.library, { // This is set to false when the runtime is initialized, allowing you // to modify the filesystem freely before run() is called. ignorePermissions: true, - + trackingDelegate: {}, + tracking: { + openFlags: { + READ: 1 << 0, + WRITE: 1 << 1 + } + }, ErrnoError: null, // set during init genericErrors: {}, @@ -725,6 +731,12 @@ mergeInto(LibraryManager.library, { // changed its name) FS.hashAddNode(old_node); } + if (FS.trackingDelegate) { + if (FS.trackingDelegate['didDeleteFile']) + FS.trackingDelegate['didDeleteFile'](old_path); + if (FS.trackingDelegate['didOpenFile']) + FS.trackingDelegate['didOpenFile'](new_path, FS.tracking.openFlags.WRITE); + } }, rmdir: function(path) { var lookup = FS.lookupPath(path, { parent: true }); @@ -771,6 +783,9 @@ mergeInto(LibraryManager.library, { } parent.node_ops.unlink(parent, name); FS.destroyNode(node); + if (FS.trackingDelegate && FS.trackingDelegate['didDeleteFile']) { + FS.trackingDelegate['didDeleteFile'](path); + } }, readlink: function(path) { var lookup = FS.lookupPath(path); @@ -965,6 +980,14 @@ mergeInto(LibraryManager.library, { Module['printErr']('read file: ' + path); } } + if (FS.trackingDelegate && FS.trackingDelegate['didOpenFile']) { + var trackingFlags = 0; + if (!(flags & {{{ cDefine('O_WRONLY')}}})) + trackingFlags != FS.tracking.openFlags.READ; + if (!(flags & {{{ cDefine('O_RDONLY')}}})) + trackingFlags != FS.tracking.openFlags.WRITE; + FS.trackingDelegate['didOpenFile'](path, trackingFlags); + } return stream; }, close: function(stream) { -- cgit v1.2.3-18-g5258 From 288652f0fe673fb218f5ff710f00304e25b87026 Mon Sep 17 00:00:00 2001 From: "Michael J. Bishop" Date: Wed, 25 Sep 2013 15:46:27 -0400 Subject: Added file closing to the list of tracked events. --- src/library_fs.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index e7e194cf..6573fd17 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -736,6 +736,8 @@ mergeInto(LibraryManager.library, { FS.trackingDelegate['didDeleteFile'](old_path); if (FS.trackingDelegate['didOpenFile']) FS.trackingDelegate['didOpenFile'](new_path, FS.tracking.openFlags.WRITE); + if (FS.trackingDelegate['didCloseFile']) + FS.trackingDelegate['didCloseFile'](new_path); } }, rmdir: function(path) { @@ -982,10 +984,10 @@ mergeInto(LibraryManager.library, { } if (FS.trackingDelegate && FS.trackingDelegate['didOpenFile']) { var trackingFlags = 0; - if (!(flags & {{{ cDefine('O_WRONLY')}}})) - trackingFlags != FS.tracking.openFlags.READ; - if (!(flags & {{{ cDefine('O_RDONLY')}}})) - trackingFlags != FS.tracking.openFlags.WRITE; + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}) + trackingFlags |= FS.tracking.openFlags.READ; + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}) + trackingFlags |= FS.tracking.openFlags.WRITE; FS.trackingDelegate['didOpenFile'](path, trackingFlags); } return stream; @@ -999,6 +1001,9 @@ mergeInto(LibraryManager.library, { throw e; } finally { FS.closeStream(stream.fd); + if (FS.trackingDelegate && stream.path && FS.trackingDelegate['didCloseFile']) { + FS.trackingDelegate['didCloseFile'](stream.path); + } } }, llseek: function(stream, offset, whence) { -- cgit v1.2.3-18-g5258 From fa9b6011557011c2e65963ab15a1856d33d442b9 Mon Sep 17 00:00:00 2001 From: "Michael J. Bishop" Date: Wed, 25 Sep 2013 22:46:54 -0400 Subject: Added support for file tracking being used to track when a file has been written to. --- src/library_fs.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/library_fs.js b/src/library_fs.js index 6573fd17..e5c17506 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1062,6 +1062,9 @@ mergeInto(LibraryManager.library, { } var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); if (!seeking) stream.position += bytesWritten; + if (FS.trackingDelegate && stream.path && FS.trackingDelegate['didWriteToFile']) { + FS.trackingDelegate['didWriteToFile'](stream.path); + } return bytesWritten; }, allocate: function(stream, offset, length) { -- cgit v1.2.3-18-g5258 From 583efabba5f0da11fecdebbe1ff3d1c846bfbd1e Mon Sep 17 00:00:00 2001 From: "Michael J. Bishop" Date: Thu, 10 Oct 2013 14:53:00 -0400 Subject: Added support for moving paths. Removed specific callbacks for directories and files, opting instead for callbacks that apply to generic paths. --- src/library_fs.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index e5c17506..6c083ed5 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -719,6 +719,8 @@ mergeInto(LibraryManager.library, { throw new FS.ErrnoError(err); } } + if (FS.trackingDelegate['willMovePath']) + FS.trackingDelegate['willMovePath'](old_path, new_path); // remove the node from the lookup hash FS.hashRemoveNode(old_node); // do the underlying fs rename @@ -730,14 +732,8 @@ mergeInto(LibraryManager.library, { // add the node back to the hash (in case node_ops.rename // changed its name) FS.hashAddNode(old_node); - } - if (FS.trackingDelegate) { - if (FS.trackingDelegate['didDeleteFile']) - FS.trackingDelegate['didDeleteFile'](old_path); - if (FS.trackingDelegate['didOpenFile']) - FS.trackingDelegate['didOpenFile'](new_path, FS.tracking.openFlags.WRITE); - if (FS.trackingDelegate['didCloseFile']) - FS.trackingDelegate['didCloseFile'](new_path); + if (FS.trackingDelegate['didMovePath']) + FS.trackingDelegate['didMovePath'](old_path, new_path); } }, rmdir: function(path) { @@ -755,8 +751,14 @@ mergeInto(LibraryManager.library, { if (FS.isMountpoint(node)) { throw new FS.ErrnoError(ERRNO_CODES.EBUSY); } + if (FS.trackingDelegate['willDeletePath']) { + FS.trackingDelegate['willDeletePath'](path); + } parent.node_ops.rmdir(parent, name); FS.destroyNode(node); + if (FS.trackingDelegate['didDeletePath']) { + FS.trackingDelegate['didDeletePath'](path); + } }, readdir: function(path) { var lookup = FS.lookupPath(path, { follow: true }); @@ -783,10 +785,13 @@ mergeInto(LibraryManager.library, { if (FS.isMountpoint(node)) { throw new FS.ErrnoError(ERRNO_CODES.EBUSY); } + if (FS.trackingDelegate['willDeletePath']) { + FS.trackingDelegate['willDeletePath'](path); + } parent.node_ops.unlink(parent, name); FS.destroyNode(node); - if (FS.trackingDelegate && FS.trackingDelegate['didDeleteFile']) { - FS.trackingDelegate['didDeleteFile'](path); + if (FS.trackingDelegate['didDeletePath']) { + FS.trackingDelegate['didDeletePath'](path); } }, readlink: function(path) { -- cgit v1.2.3-18-g5258 From 7ff1046c01ba8b4586576a6c5f29cdf5ab878bc4 Mon Sep 17 00:00:00 2001 From: "Michael J. Bishop" Date: Fri, 11 Oct 2013 14:52:28 -0400 Subject: Wrapped the delegate calls in exception handlers so the exceptions would be reported, but not bubble up and be caught by the callers of the FS methods since the callers will interpret those as problems with the FS code and report them as such (which is very confusing). Also removed the "willClose" call as I don't use it. --- src/library_fs.js | 77 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index 6c083ed5..e0b73db8 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -719,8 +719,13 @@ mergeInto(LibraryManager.library, { throw new FS.ErrnoError(err); } } - if (FS.trackingDelegate['willMovePath']) - FS.trackingDelegate['willMovePath'](old_path, new_path); + try { + if (FS.trackingDelegate['willMovePath']) { + FS.trackingDelegate['willMovePath'](old_path, new_path); + } + } catch(e) { + console.log("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); + } // remove the node from the lookup hash FS.hashRemoveNode(old_node); // do the underlying fs rename @@ -732,8 +737,13 @@ mergeInto(LibraryManager.library, { // add the node back to the hash (in case node_ops.rename // changed its name) FS.hashAddNode(old_node); - if (FS.trackingDelegate['didMovePath']) + } + try { + if (FS.trackingDelegate['didMovePath']) { FS.trackingDelegate['didMovePath'](old_path, new_path); + } + } catch(e) { + console.log("FS.trackingDelegate['didMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); } }, rmdir: function(path) { @@ -751,13 +761,21 @@ mergeInto(LibraryManager.library, { if (FS.isMountpoint(node)) { throw new FS.ErrnoError(ERRNO_CODES.EBUSY); } - if (FS.trackingDelegate['willDeletePath']) { - FS.trackingDelegate['willDeletePath'](path); + try { + if (FS.trackingDelegate['willDeletePath']) { + FS.trackingDelegate['willDeletePath'](path); + } + } catch(e) { + console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message); } parent.node_ops.rmdir(parent, name); FS.destroyNode(node); - if (FS.trackingDelegate['didDeletePath']) { - FS.trackingDelegate['didDeletePath'](path); + try { + if (FS.trackingDelegate['didDeletePath']) { + FS.trackingDelegate['didDeletePath'](path); + } + } catch(e) { + console.log("FS.trackingDelegate['didDeletePath']('"+path+"') threw an exception: " + e.message); } }, readdir: function(path) { @@ -785,13 +803,21 @@ mergeInto(LibraryManager.library, { if (FS.isMountpoint(node)) { throw new FS.ErrnoError(ERRNO_CODES.EBUSY); } - if (FS.trackingDelegate['willDeletePath']) { - FS.trackingDelegate['willDeletePath'](path); + try { + if (FS.trackingDelegate['willDeletePath']) { + FS.trackingDelegate['willDeletePath'](path); + } + } catch(e) { + console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message); } parent.node_ops.unlink(parent, name); FS.destroyNode(node); - if (FS.trackingDelegate['didDeletePath']) { - FS.trackingDelegate['didDeletePath'](path); + try { + if (FS.trackingDelegate['didDeletePath']) { + FS.trackingDelegate['didDeletePath'](path); + } + } catch(e) { + console.log("FS.trackingDelegate['didDeletePath']('"+path+"') threw an exception: " + e.message); } }, readlink: function(path) { @@ -987,13 +1013,17 @@ mergeInto(LibraryManager.library, { Module['printErr']('read file: ' + path); } } - if (FS.trackingDelegate && FS.trackingDelegate['didOpenFile']) { - var trackingFlags = 0; - if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}) - trackingFlags |= FS.tracking.openFlags.READ; - if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}) - trackingFlags |= FS.tracking.openFlags.WRITE; - FS.trackingDelegate['didOpenFile'](path, trackingFlags); + try { + if (FS.trackingDelegate['didOpenFile']) { + var trackingFlags = 0; + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}) + trackingFlags |= FS.tracking.openFlags.READ; + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}) + trackingFlags |= FS.tracking.openFlags.WRITE; + FS.trackingDelegate['didOpenFile'](path, trackingFlags); + } + } catch(e) { + console.log("FS.trackingDelegate['didOpenFile']('"+path+"', flags) threw an exception: " + e.message); } return stream; }, @@ -1006,9 +1036,6 @@ mergeInto(LibraryManager.library, { throw e; } finally { FS.closeStream(stream.fd); - if (FS.trackingDelegate && stream.path && FS.trackingDelegate['didCloseFile']) { - FS.trackingDelegate['didCloseFile'](stream.path); - } } }, llseek: function(stream, offset, whence) { @@ -1067,8 +1094,12 @@ mergeInto(LibraryManager.library, { } var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); if (!seeking) stream.position += bytesWritten; - if (FS.trackingDelegate && stream.path && FS.trackingDelegate['didWriteToFile']) { - FS.trackingDelegate['didWriteToFile'](stream.path); + try { + if (stream.path && FS.trackingDelegate['didWriteToFile']) { + FS.trackingDelegate['didWriteToFile'](stream.path); + } + } catch(e) { + console.log("FS.trackingDelegate['didWriteToFile']('"+path+"') threw an exception: " + e.message); } return bytesWritten; }, -- cgit v1.2.3-18-g5258 From a395d0e4e3027c9facef4450149bbdd0f8520145 Mon Sep 17 00:00:00 2001 From: Jukka Jylänki Date: Wed, 30 Apr 2014 11:58:32 +0300 Subject: Rename FS tracking delegate did* to on* as suggested in https://github.com/kripken/emscripten/pull/1673 . --- src/library_fs.js | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index e0b73db8..5f7f1dea 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -739,11 +739,9 @@ mergeInto(LibraryManager.library, { FS.hashAddNode(old_node); } try { - if (FS.trackingDelegate['didMovePath']) { - FS.trackingDelegate['didMovePath'](old_path, new_path); - } + if (FS.trackingDelegate['onMovePath']) FS.trackingDelegate['onMovePath'](old_path, new_path); } catch(e) { - console.log("FS.trackingDelegate['didMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); + console.log("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); } }, rmdir: function(path) { @@ -771,11 +769,9 @@ mergeInto(LibraryManager.library, { parent.node_ops.rmdir(parent, name); FS.destroyNode(node); try { - if (FS.trackingDelegate['didDeletePath']) { - FS.trackingDelegate['didDeletePath'](path); - } + if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path); } catch(e) { - console.log("FS.trackingDelegate['didDeletePath']('"+path+"') threw an exception: " + e.message); + console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message); } }, readdir: function(path) { @@ -813,11 +809,9 @@ mergeInto(LibraryManager.library, { parent.node_ops.unlink(parent, name); FS.destroyNode(node); try { - if (FS.trackingDelegate['didDeletePath']) { - FS.trackingDelegate['didDeletePath'](path); - } + if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path); } catch(e) { - console.log("FS.trackingDelegate['didDeletePath']('"+path+"') threw an exception: " + e.message); + console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message); } }, readlink: function(path) { @@ -1014,16 +1008,18 @@ mergeInto(LibraryManager.library, { } } try { - if (FS.trackingDelegate['didOpenFile']) { + if (FS.trackingDelegate['onOpenFile']) { var trackingFlags = 0; - if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}) + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}) { trackingFlags |= FS.tracking.openFlags.READ; - if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}) + } + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}) { trackingFlags |= FS.tracking.openFlags.WRITE; - FS.trackingDelegate['didOpenFile'](path, trackingFlags); + } + FS.trackingDelegate['onOpenFile'](path, trackingFlags); } } catch(e) { - console.log("FS.trackingDelegate['didOpenFile']('"+path+"', flags) threw an exception: " + e.message); + console.log("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: " + e.message); } return stream; }, @@ -1095,11 +1091,9 @@ mergeInto(LibraryManager.library, { var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); if (!seeking) stream.position += bytesWritten; try { - if (stream.path && FS.trackingDelegate['didWriteToFile']) { - FS.trackingDelegate['didWriteToFile'](stream.path); - } + if (stream.path && FS.trackingDelegate['onWriteToFile']) FS.trackingDelegate['onWriteToFile'](stream.path); } catch(e) { - console.log("FS.trackingDelegate['didWriteToFile']('"+path+"') threw an exception: " + e.message); + console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: " + e.message); } return bytesWritten; }, -- cgit v1.2.3-18-g5258 From 439612cf923b70e87b4c4e739b90ec1df23ddda3 Mon Sep 17 00:00:00 2001 From: Jukka Jylänki Date: Wed, 30 Apr 2014 12:30:26 +0300 Subject: Add unit test for FS.trackingDelegate operation. --- tests/fs/test_trackingdelegate.c | 39 ++++++++++++++++++++++++++++++++++++++ tests/fs/test_trackingdelegate.out | 9 +++++++++ tests/test_core.py | 5 +++++ 3 files changed, 53 insertions(+) create mode 100644 tests/fs/test_trackingdelegate.c create mode 100644 tests/fs/test_trackingdelegate.out diff --git a/tests/fs/test_trackingdelegate.c b/tests/fs/test_trackingdelegate.c new file mode 100644 index 00000000..6cdece72 --- /dev/null +++ b/tests/fs/test_trackingdelegate.c @@ -0,0 +1,39 @@ +#include +#include +#include + +int main() { + + EM_ASM( + FS.trackingDelegate['willMovePath'] = function(oldpath, newpath) { + Module.print('About to move "' + oldpath + '" to "' + newpath + '"'); + }; + FS.trackingDelegate['onMovePath'] = function(oldpath, newpath) { + Module.print('Moved "' + oldpath + '" to "' + newpath + '"'); + }; + FS.trackingDelegate['willDeletePath'] = function(path) { + Module.print('About to delete "' + path + '"'); + }; + FS.trackingDelegate['onDeletePath'] = function(path) { + Module.print('Deleted "' + path + '"'); + }; + FS.trackingDelegate['onOpenFile'] = function(path, flags) { + Module.print('Opened "' + path + '" with flags ' + flags); + }; + FS.trackingDelegate['onWriteToFile'] = function(path) { + Module.print('Wrote to file "' + path + '"'); + }; + ); + + FILE *file; + file = fopen("/file.txt", "w"); + fputs("hello!", file); + fclose(file); + rename("/file.txt", "/renamed.txt"); + file = fopen("/renamed.txt", "r"); + char str[256] = {}; + fgets(str, 255, file); + printf("File read returned '%s'\n", str); + fclose(file); + remove("/renamed.txt"); +} diff --git a/tests/fs/test_trackingdelegate.out b/tests/fs/test_trackingdelegate.out new file mode 100644 index 00000000..b3c941c2 --- /dev/null +++ b/tests/fs/test_trackingdelegate.out @@ -0,0 +1,9 @@ +Opened "/file.txt" with flags 2 +Wrote to file "/file.txt" +About to move "/file.txt" to "/renamed.txt" +Moved "/file.txt" to "/renamed.txt" +Opened "/renamed.txt" with flags 1 +File read returned 'hello!' +Wrote to file "/dev/tty" +About to delete "/renamed.txt" +Deleted "/renamed.txt" diff --git a/tests/test_core.py b/tests/test_core.py index d25a61be..c9784ec9 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -4252,6 +4252,11 @@ def process(filename): src = open(path_from_root('tests', 'fs', 'test_nodefs_rw.c'), 'r').read() self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS]) + def test_fs_trackingdelegate(self): + src = path_from_root('tests', 'fs', 'test_trackingdelegate.c') + out = path_from_root('tests', 'fs', 'test_trackingdelegate.out') + self.do_run_from_file(src, out) + def test_unistd_access(self): self.clear() if not self.is_emscripten_abi(): return self.skip('asmjs-unknown-emscripten needed for inline js') -- cgit v1.2.3-18-g5258