diff options
-rw-r--r-- | src/library.js | 35 | ||||
-rw-r--r-- | tests/runner.py | 44 |
2 files changed, 78 insertions, 1 deletions
diff --git a/src/library.js b/src/library.js index 6b30f466..3e15cd73 100644 --- a/src/library.js +++ b/src/library.js @@ -86,7 +86,7 @@ var Library = { current = current.contents[target]; if (current.link) { current = FS.findObject(current.link); - if (++linksVisited > 64) { + if (++linksVisited > 40) { // Usual Linux SYMLOOP_MAX. ___setErrNo(ERRNO_CODES.ELOOP); return null; } @@ -321,6 +321,39 @@ var Library = { // TODO: Check if we need to link any aliases. // ========================================================================== + // utime.h + // ========================================================================== + + // TODO: Switch to dynamically calculated layout. + //__utimbuf_struct_layout: Runtime.generateStructInfo('utimbuf'), + __utimbuf_struct_layout: { + __size__: 8, + actime: 0, + modtime: 4 + }, + utime__deps: ['$FS', '__setErrNo', '__utimbuf_struct_layout'], + utime: function(path, times) { + // int utime(const char *path, const struct utimbuf *times); + // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/utime.h.html + var time; + if (times) { + // NOTE: We don't keep track of access timestamps. + time = {{{ makeGetValue('times', '___utimbuf_struct_layout.modtime', 'i32') }}} + time = new Date(time * 1000); + } else { + time = new Date(); + } + var file = FS.findObject(Pointer_stringify(path)); + if (file === null) return -1; + if (!file.write) { + ___setErrNo(ERRNO_CODES.EPERM); + return -1; + } + file.timestamp = time; + return 0; + }, + + // ========================================================================== // libgen.h // ========================================================================== diff --git a/tests/runner.py b/tests/runner.py index 879c7022..1891c4bb 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -2211,6 +2211,50 @@ if 'benchmark' not in sys.argv: ''' self.do_test(src, re.sub('(^|\n)\s+', '\\1', expected)) + def test_utime(self): + def addPreRunAndChecks(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + ''' + var TEST_F1 = FS.createFolder('/', 'writeable', true, true); + var TEST_F2 = FS.createFolder('/', 'unwriteable', true, false); + ''' + ).replace( + '// {{POST_RUN_ADDITIONS}}', + ''' + print('first changed: ' + (TEST_F1.timestamp.getTime() == 1200000000000)); + print('second changed: ' + (TEST_F2.timestamp.getTime() == 1200000000000)); + ''' + ) + open(filename, 'w').write(src) + + src = r''' + #include <stdio.h> + #include <errno.h> + #include <utime.h> + + int main() { + struct utimbuf t = {1000000000, 1200000000}; + char* writeable = "/writeable"; + char* unwriteable = "/unwriteable"; + + utime(writeable, &t); + printf("writeable errno: %d\n", errno); + + utime(unwriteable, &t); + printf("unwriteable errno: %d\n", errno); + + return 0; + } + ''' + expected = ''' + writeable errno: 0 + unwriteable errno: 1 + first changed: true + second changed: false + ''' + self.do_test(src, re.sub('(^|\n)\s+', '\\1', expected), post_build=addPreRunAndChecks) + ### 'Big' tests def test_fannkuch(self): |