diff options
44 files changed, 2470 insertions, 144 deletions
diff --git a/src/library.js b/src/library.js index 748fda43..51fb6ce5 100644 --- a/src/library.js +++ b/src/library.js @@ -934,15 +934,15 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/chdir.html // NOTE: The path argument may be a string, to simplify fchdir(). if (typeof path !== 'string') path = Pointer_stringify(path); - path = FS.absolutePath(path); - // TODO: Resolve path so that no element of it is a link. - var target = FS.findObject(path); - if (target === null) return -1; - if (!target.isFolder) { + path = FS.analyzePath(path); + if (!path.exists) { + ___setErrNo(path.error); + return -1; + } else if (!path.object.isFolder) { ___setErrNo(ERRNO_CODES.ENOTDIR); return -1; } else { - FS.currentPath = path; + FS.currentPath = path.path; return 0; } }, @@ -952,7 +952,7 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/chown.html // We don't support multiple users, so changing ownership makes no sense. // NOTE: The path argument may be a string, to simplify fchown(). - // NOTE: dontResolveLastLink is a shortcut for lstat(). It should never be + // NOTE: dontResolveLastLink is a shortcut for lchown(). It should never be // used in client code. if (typeof path !== 'string') path = Pointer_stringify(path); var target = FS.findObject(path, dontResolveLastLink); @@ -978,17 +978,17 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/dup.html return _fcntl(fildes, 0, 0); // F_DUPFD. }, - dup2__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'fcntl'], + dup2__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'fcntl', 'close'], dup2: function(fildes, fildes2) { // int dup2(int fildes, int fildes2); // http://pubs.opengroup.org/onlinepubs/000095399/functions/dup.html - // TODO: Verify: Duplicate FD to FD2, closing FD2 and making it open on the same file. if (fildes2 < 0) { ___setErrNo(ERRNO_CODES.EBADF); return -1; } else if (fildes === fildes2 && FS.streams[fildes]) { return fildes; } else { + _close(fildes2); return _fcntl(fildes, 0, fildes2); // F_DUPFD. } }, @@ -1027,14 +1027,14 @@ LibraryManager.library = { crypt: function(key, salt) { // char *(const char *, const char *); // http://pubs.opengroup.org/onlinepubs/000095399/functions/crypt.html - // TODO: Implement (compile from source?). + // TODO: Implement (probably compile from C). ___setErrNo(ERRNO_CODES.ENOSYS); return 0; }, - encrypt: function(key, salt) { + encrypt: function(block, edflag) { // void encrypt(char block[64], int edflag); // http://pubs.opengroup.org/onlinepubs/000095399/functions/encrypt.html - // TODO: Implement (compile from source?). + // TODO: Implement (probably compile from C). ___setErrNo(ERRNO_CODES.ENOSYS); }, fpathconf__deps: ['__setErrNo', '$ERRNO_CODES'], @@ -1072,16 +1072,13 @@ LibraryManager.library = { return -1; case 13: // _PC_FILESIZEBITS. return 64; - defult: - ___setErrNo(ERRNO_CODES.EINVAL); - return -1; } - // Should never be reached. Only to silence strict warnings. + ___setErrNo(ERRNO_CODES.EINVAL); return -1; }, pathconf: 'fpathconf', fsync__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], - fsync: function(fildes, owner, group) { + fsync: function(fildes) { // int fsync(int fildes); // http://pubs.opengroup.org/onlinepubs/000095399/functions/fsync.html if (FS.streams[fildes]) { @@ -1111,6 +1108,9 @@ LibraryManager.library = { } else if (target.isDevice) { ___setErrNo(ERRNO_CODES.EINVAL); return -1; + } else if (!target.write) { + ___setErrNo(ERRNO_CODES.EACCES); + return -1; } else { var contents = target.contents; if (length < contents.length) contents.length = length; @@ -1126,6 +1126,9 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/ftruncate.html if (FS.streams[fildes] && FS.streams[fildes].isWrite) { return _truncate(FS.streams[fildes].path, length); + } else if (FS.streams[fildes]) { + ___setErrNo(ERRNO_CODES.EINVAL); + return -1; } else { ___setErrNo(ERRNO_CODES.EBADF); return -1; @@ -1143,7 +1146,7 @@ LibraryManager.library = { return 0; } else { for (var i = 0; i < FS.currentPath.length; i++) { - {{{ makeSetValue('buf', 'i', 'FS.currentPath[i]', 'i8') }}} + {{{ makeSetValue('buf', 'i', 'FS.currentPath.charCodeAt(i)', 'i8') }}} } {{{ makeSetValue('buf', 'i', '0', 'i8') }}} return buf; @@ -1193,8 +1196,8 @@ LibraryManager.library = { // int lockf(int fildes, int function, off_t size); // http://pubs.opengroup.org/onlinepubs/000095399/functions/lockf.html if (FS.streams[fildes]) { - // Pretend whatever locking or unlocking operation succeeded. Lokcing does - // not make sense since we have a single process/thread. + // Pretend whatever locking or unlocking operation succeeded. Locking does + // not make much sense, since we have a single process/thread. return 0; } else { ___setErrNo(ERRNO_CODES.EBADF); @@ -1211,10 +1214,15 @@ LibraryManager.library = { if (whence === 1) { // SEEK_CUR. position += stream.position; } else if (whence === 2) { // SEEK_END. - position += stream.contents.length; + position += stream.object.contents.length; + } + if (position < 0) { + ___setErrNo(ERRNO_CODES.EINVAL); + return -1; + } else { + stream.position = position; + return position; } - stream.position = position; - return position; } else { ___setErrNo(ERRNO_CODES.EBADF); return -1; @@ -1234,13 +1242,13 @@ LibraryManager.library = { // ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); // http://pubs.opengroup.org/onlinepubs/000095399/functions/read.html var stream = FS.streams[fildes]; - if (!stream || stream.isDevice) { + if (!stream || stream.object.isDevice) { ___setErrNo(ERRNO_CODES.EBADF); return -1; } else if (!stream.isRead) { ___setErrNo(ERRNO_CODES.EACCES); return -1; - } else if (stream.isFolder) { + } else if (stream.object.isFolder) { ___setErrNo(ERRNO_CODES.EISDIR); return -1; } else if (nbyte < 0 || offset < 0) { @@ -1270,11 +1278,11 @@ LibraryManager.library = { ___setErrNo(ERRNO_CODES.EINVAL); return -1; } else { - if (stream.isDevice) { - if (stream.input) { + if (stream.object.isDevice) { + if (stream.object.input) { for (var i = 0; i < nbyte; i++) { try { - var result = stream.input(); + var result = stream.object.input(); } catch (e) { ___setErrNo(ERRNO_CODES.EIO); return -1; @@ -1299,66 +1307,50 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/sync.html // All our writing is already synchronized. This is a no-op. }, - rmdir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', - 'dirname', 'basename', 'strcpy', 'strlen'], + rmdir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], rmdir: function(path) { // int rmdir(const char *path); // http://pubs.opengroup.org/onlinepubs/000095399/functions/rmdir.html - var buffer = _malloc(_strlen(path) + 1); - var parent = Pointer_stringify(_dirname(_strcpy(buffer, path))); - var name = Pointer_stringify(_basename(_strcpy(buffer, path))); - var absolutePath = FS.absolutePath(Pointer_stringify(path)); - _free(buffer); - parent = FS.findObject(parent); - if (parent === null) return -1; - if (!parent.read) { - ___setErrNo(ERRNO_CODES.EACCES); - return -1; - } else if (!parent.contents.hasOwnProperty(name)) { - ___setErrNo(ERRNO_CODES.ENOENT); - return -1; - } else if (!parent.contents[name].isFolder) { - ___setErrNo(ERRNO_CODES.ENOTDIR); + path = FS.analyzePath(Pointer_stringify(path)); + if (!path.parentExists || !path.exists) { + ___setErrNo(path.error); return -1; - } else if (!parent.contents[name].write) { + } else if (!path.object.write || path.isRoot) { ___setErrNo(ERRNO_CODES.EACCES); return -1; - } else if (!parent.contents[name].contents.length != 0) { - ___setErrNo(ERRNO_CODES.ENOTEMPTY); - return -1; - } else if (absolutePath == FS.currentPath) { - ___setErrNo(ERRNO_CODES.EBUSY); + } else if (!path.object.isFolder) { + ___setErrNo(ERRNO_CODES.ENOTDIR); return -1; } else { - delete parent.contents[name]; - return 0; + for (var i in path.object.contents) { + ___setErrNo(ERRNO_CODES.ENOTEMPTY); + return -1; + } + if (path.path == FS.currentPath) { + ___setErrNo(ERRNO_CODES.EBUSY); + return -1; + } else { + delete path.parentObject.contents[path.name]; + return 0; + } } }, - unlink__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', - 'dirname', 'basename', 'strcpy', 'strlen'], + unlink__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], unlink: function(path) { // int unlink(const char *path); // http://pubs.opengroup.org/onlinepubs/000095399/functions/unlink.html - var buffer = _malloc(_strlen(path) + 1); - var parent = Pointer_stringify(_dirname(_strcpy(buffer, path))); - var name = Pointer_stringify(_basename(_strcpy(buffer, path))); - _free(buffer); - parent = FS.findObject(parent); - if (parent === null) return -1; - if (!parent.read) { - ___setErrNo(ERRNO_CODES.EACCES); - return -1; - } else if (!parent.contents.hasOwnProperty(name)) { - ___setErrNo(ERRNO_CODES.ENOENT); + path = FS.analyzePath(Pointer_stringify(path)); + if (!path.parentExists || !path.exists) { + ___setErrNo(path.error); return -1; - } else if (parent.contents[name].isFolder) { + } else if (path.object.isFolder) { ___setErrNo(ERRNO_CODES.EISDIR); return -1; - } else if (!parent.contents[name].write) { + } else if (!path.object.write) { ___setErrNo(ERRNO_CODES.EACCES); return -1; } else { - delete parent.contents[name]; + delete path.parentObject.contents[path.name]; return 0; } }, @@ -1367,7 +1359,7 @@ LibraryManager.library = { // char *ttyname(int fildes); // http://pubs.opengroup.org/onlinepubs/000095399/functions/ttyname.html if (!_ttyname.ret) _ttyname.ret = _malloc(256); - return _ttyname_r(fildes, _ttyname.ret, 256); + return _ttyname_r(fildes, _ttyname.ret, 256) ? 0 : _ttyname.ret; }, ttyname_r__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], ttyname_r: function(fildes, name, namesize) { @@ -1375,37 +1367,40 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/ttyname.html var stream = FS.streams[fildes]; if (!stream) { - ___setErrNo(ERRNO_CODES.EBADF); - return 0; - } else if (!stream.isDevice || !stream.input || !stream.output) { - ___setErrNo(ERRNO_CODES.ENOTTY); - return 0; + return ___setErrNo(ERRNO_CODES.EBADF); } else { - var ret = stream.path; - if (namesize < ret.length + 1) { - ___setErrNo(ERRNO_CODES.ERANGE); - return 0; + var object = stream.object; + if (!object.isDevice || !object.input || !object.output) { + return ___setErrNo(ERRNO_CODES.ENOTTY); } else { - for (var i = 0; i < ret.length; i++) { - {{{ makeSetValue('name', 'i', 'ret.charCodeAt(i)', 'i8') }}} + var ret = stream.path; + if (namesize < ret.length + 1) { + return ___setErrNo(ERRNO_CODES.ERANGE); + } else { + for (var i = 0; i < ret.length; i++) { + {{{ makeSetValue('name', 'i', 'ret.charCodeAt(i)', 'i8') }}} + } + {{{ makeSetValue('name', 'i', '0', 'i8') }}} + return 0; } - {{{ makeSetValue('name', 'i', '0', 'i8') }}} - return name; } } }, - symlink__deps: ['$FS', 'mknod'], + symlink__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], symlink: function(path1, path2) { // int symlink(const char *path1, const char *path2); // http://pubs.opengroup.org/onlinepubs/000095399/functions/symlink.html - var result = _mknod(path2, 0x10000 | 0x1C0, 0); // S_IFREG, S_IRUSR | S_IWUSR | S_IXUSR. - if (result == 0) { - var target = FS.findObject(Pointer_stringify(path2)); - delete target.contents; - target.link = Pointer_stringify(path1); - return 0; + var path = FS.analyzePath(Pointer_stringify(path2), true); + if (!path.parentExists) { + ___setErrNo(path.error); + return -1; + } else if (path.exists) { + ___setErrNo(ERRNO_CODES.EEXIST); + return -1; } else { - return result; + FS.createLink(path.parentPath, path.name, + Pointer_stringify(path1), true, true); + return 0; } }, readlink__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], @@ -1415,11 +1410,11 @@ LibraryManager.library = { var target = FS.findObject(Pointer_stringify(path), true); if (target === null) return -1; if (target.link !== undefined) { - var length = Math.min(bufsize, target.link.length); + var length = Math.min(bufsize - 1, target.link.length); for (var i = 0; i < length; i++) { - {{{ makeSetValue('name', 'i', 'target.link.charCodeAt(i)', 'i8') }}} + {{{ makeSetValue('buf', 'i', 'target.link.charCodeAt(i)', 'i8') }}} } - if (length > bufsize) {{{ makeSetValue('name', 'i++', '0', 'i8') }}} + if (bufsize - 1 > length) {{{ makeSetValue('buf', 'i', '0', 'i8') }}} return i; } else { ___setErrNo(ERRNO_CODES.EINVAL); @@ -1431,13 +1426,13 @@ LibraryManager.library = { // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset); // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html var stream = FS.streams[fildes]; - if (!stream || stream.isDevice) { + if (!stream || stream.object.isDevice) { ___setErrNo(ERRNO_CODES.EBADF); return -1; } else if (!stream.isWrite) { ___setErrNo(ERRNO_CODES.EACCES); return -1; - } else if (stream.isFolder) { + } else if (stream.object.isFolder) { ___setErrNo(ERRNO_CODES.EISDIR); return -1; } else if (nbyte < 0 || offset < 0) { @@ -1467,11 +1462,11 @@ LibraryManager.library = { ___setErrNo(ERRNO_CODES.EINVAL); return -1; } else { - if (stream.isDevice) { - if (stream.output) { + if (stream.object.isDevice) { + if (stream.object.output) { for (var i = 0; i < nbyte; i++) { try { - stream.output({{{ makeGetValue('buf', 'i', 'i8') }}}); + stream.object.output({{{ makeGetValue('buf', 'i', 'i8') }}}); } catch (e) { ___setErrNo(ERRNO_CODES.EIO); return -1; @@ -1548,7 +1543,7 @@ LibraryManager.library = { for (var i = 0; i < length; i++) { {{{ makeSetValue('buf', 'i', 'value.charCodeAt(i)', 'i8') }}} } - if (length > len) {{{ makeSetValue('buf', 'i++', '0', 'i8') }}} + if (len > length) {{{ makeSetValue('buf', 'i++', '0', 'i8') }}} return i; } }, @@ -1601,7 +1596,7 @@ LibraryManager.library = { ___setErrNo(ERRNO_CODES.EINVAL); return -1; } else { - {{{ makeSetValue('grouplist', '0', '0', 'i8') }}} + {{{ makeSetValue('grouplist', '0', '0', 'i32') }}} return 1; } }, @@ -1610,6 +1605,7 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/gethostid.html return 42; }, + gethostname__deps: ['__setErrNo', '$ERRNO_CODES'], gethostname: function(name, namelen) { // int gethostname(char *name, size_t namelen); // http://pubs.opengroup.org/onlinepubs/000095399/functions/gethostname.html @@ -1621,26 +1617,35 @@ LibraryManager.library = { for (var i = 0; i < length; i++) { {{{ makeSetValue('name', 'i', 'host.charCodeAt(i)', 'i8') }}} } - if (length > namelen) {{{ makeSetValue('name', 'i', '0', 'i8') }}} - return 0; + if (namelen > length) { + {{{ makeSetValue('name', 'i', '0', 'i8') }}} + return 0; + } else { + ___setErrNo(ERRNO_CODES.ENAMETOOLONG); + return -1; + } }, getlogin: ['getlogin_r'], getlogin: function() { // char *getlogin(void); // http://pubs.opengroup.org/onlinepubs/000095399/functions/getlogin.html if (!_getlogin.ret) _getlogin.ret = _malloc(8); - return _getlogin_r(_getlogin.ret, 8); + return _getlogin_r(_getlogin.ret, 8) ? 0 : _getlogin.ret; }, getlogin_r__deps: ['__setErrNo', '$ERRNO_CODES'], getlogin_r: function(name, namesize) { // int getlogin_r(char *name, size_t namesize); // http://pubs.opengroup.org/onlinepubs/000095399/functions/getlogin.html var ret = 'root'; - for (var i = 0; i < ret.length; i++) { - {{{ makeSetValue('name', 'i', 'ret.charCodeAt(i)', 'i8') }}} + if (namesize < ret.length + 1) { + return ___setErrNo(ERRNO_CODES.ERANGE); + } else { + for (var i = 0; i < ret.length; i++) { + {{{ makeSetValue('name', 'i', 'ret.charCodeAt(i)', 'i8') }}} + } + {{{ makeSetValue('name', 'i', '0', 'i8') }}} + return 0; } - {{{ makeSetValue('name', 'i', '0', 'i8') }}} - return name; }, getopt: function(argc, argv, optstring) { // int getopt(int argc, char * const argv[], const char *optstring); @@ -1694,7 +1699,7 @@ LibraryManager.library = { }, setregid: 'setpgid', setreuid: 'setpgid', - setpgid__deps: ['usleep'], + sleep__deps: ['usleep'], sleep: function(seconds) { // unsigned sleep(unsigned seconds); // http://pubs.opengroup.org/onlinepubs/000095399/functions/sleep.html @@ -1704,8 +1709,9 @@ LibraryManager.library = { // int usleep(useconds_t useconds); // http://pubs.opengroup.org/onlinepubs/000095399/functions/usleep.html // We're single-threaded, so use a busy loop. Super-ugly. + var msec = useconds / 1000; var start = new Date().getTime(); - while (new Date().getTime() - start < useconds); + while (new Date().getTime() - start < msec); return 0; }, swab: function(src, dest, nbytes) { @@ -1734,14 +1740,169 @@ LibraryManager.library = { ___setErrNo(ERRNO_CODES.EINVAL); return -1; }, - sysconf: function(name_) { - // TODO: Implement. - // XXX we only handle _SC_PAGE_SIZE/PAGESIZE for now, 30 on linux, 29 on OS X... be careful here! - switch(name_) { - case 29: case 30: return PAGE_SIZE; - case 2: return 1000000; // _SC_CLK_TCK - default: throw 'unknown sysconf param: ' + name_; + sysconf__deps: ['__setErrNo', '$ERRNO_CODES'], + sysconf: function(name) { + // long sysconf(int name); + // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html + // WARNING: Except for PAGE_SIZE, this is generated by a C program using + // glibc. All the constants depend on values provided by glibc, and + // code compiled with other C libraries is not guaranteed to work. + switch(name) { + case 30: return PAGE_SIZE; // _SC_PAGE_SIZE / _SC_PAGESIZE + case 132: // _SC_ADVISORY_INFO + case 133: // _SC_BARRIERS + case 12: // _SC_ASYNCHRONOUS_IO + case 137: // _SC_CLOCK_SELECTION + case 138: // _SC_CPUTIME + case 15: // _SC_FSYNC + case 235: // _SC_IPV6 + case 16: // _SC_MAPPED_FILES + case 17: // _SC_MEMLOCK + case 18: // _SC_MEMLOCK_RANGE + case 19: // _SC_MEMORY_PROTECTION + case 20: // _SC_MESSAGE_PASSING + case 149: // _SC_MONOTONIC_CLOCK + case 13: // _SC_PRIORITIZED_IO + case 10: // _SC_PRIORITY_SCHEDULING + case 236: // _SC_RAW_SOCKETS + case 153: // _SC_READER_WRITER_LOCKS + case 9: // _SC_REALTIME_SIGNALS + case 21: // _SC_SEMAPHORES + case 22: // _SC_SHARED_MEMORY_OBJECTS + case 159: // _SC_SPAWN + case 154: // _SC_SPIN_LOCKS + case 14: // _SC_SYNCHRONIZED_IO + case 77: // _SC_THREAD_ATTR_STACKADDR + case 78: // _SC_THREAD_ATTR_STACKSIZE + case 139: // _SC_THREAD_CPUTIME + case 80: // _SC_THREAD_PRIO_INHERIT + case 81: // _SC_THREAD_PRIO_PROTECT + case 79: // _SC_THREAD_PRIORITY_SCHEDULING + case 82: // _SC_THREAD_PROCESS_SHARED + case 68: // _SC_THREAD_SAFE_FUNCTIONS + case 67: // _SC_THREADS + case 164: // _SC_TIMEOUTS + case 11: // _SC_TIMERS + case 29: // _SC_VERSION + case 47: // _SC_2_C_BIND + case 48: // _SC_2_C_DEV + case 95: // _SC_2_CHAR_TERM + case 52: // _SC_2_LOCALEDEF + case 51: // _SC_2_SW_DEV + case 46: // _SC_2_VERSION + return 200809; + case 27: // _SC_MQ_OPEN_MAX + case 246: // _SC_XOPEN_STREAMS + case 127: // _SC_XBS5_LP64_OFF64 + case 128: // _SC_XBS5_LPBIG_OFFBIG + case 23: // _SC_AIO_LISTIO_MAX + case 24: // _SC_AIO_MAX + case 160: // _SC_SPORADIC_SERVER + case 161: // _SC_THREAD_SPORADIC_SERVER + case 181: // _SC_TRACE + case 182: // _SC_TRACE_EVENT_FILTER + case 242: // _SC_TRACE_EVENT_NAME_MAX + case 183: // _SC_TRACE_INHERIT + case 184: // _SC_TRACE_LOG + case 243: // _SC_TRACE_NAME_MAX + case 244: // _SC_TRACE_SYS_MAX + case 245: // _SC_TRACE_USER_EVENT_MAX + case 165: // _SC_TYPED_MEMORY_OBJECTS + case 178: // _SC_V6_LP64_OFF64 + case 179: // _SC_V6_LPBIG_OFFBIG + case 49: // _SC_2_FORT_DEV + case 50: // _SC_2_FORT_RUN + case 168: // _SC_2_PBS + case 169: // _SC_2_PBS_ACCOUNTING + case 175: // _SC_2_PBS_CHECKPOINT + case 170: // _SC_2_PBS_LOCATE + case 171: // _SC_2_PBS_MESSAGE + case 172: // _SC_2_PBS_TRACK + case 97: // _SC_2_UPE + case 76: // _SC_THREAD_THREADS_MAX + case 32: // _SC_SEM_NSEMS_MAX + case 173: // _SC_SYMLOOP_MAX + case 35: // _SC_TIMER_MAX + return -1; + case 176: // _SC_V6_ILP32_OFF32 + case 177: // _SC_V6_ILP32_OFFBIG + case 7: // _SC_JOB_CONTROL + case 155: // _SC_REGEXP + case 8: // _SC_SAVED_IDS + case 157: // _SC_SHELL + case 125: // _SC_XBS5_ILP32_OFF32 + case 126: // _SC_XBS5_ILP32_OFFBIG + case 92: // _SC_XOPEN_CRYPT + case 93: // _SC_XOPEN_ENH_I18N + case 129: // _SC_XOPEN_LEGACY + case 130: // _SC_XOPEN_REALTIME + case 131: // _SC_XOPEN_REALTIME_THREADS + case 94: // _SC_XOPEN_SHM + case 91: // _SC_XOPEN_UNIX + return 1; + case 74: // _SC_THREAD_KEYS_MAX + case 60: // _SC_IOV_MAX + case 69: // _SC_GETGR_R_SIZE_MAX + case 70: // _SC_GETPW_R_SIZE_MAX + case 4: // _SC_OPEN_MAX + return 1024; + case 31: // _SC_RTSIG_MAX + case 42: // _SC_EXPR_NEST_MAX + case 72: // _SC_TTY_NAME_MAX + return 32; + case 87: // _SC_ATEXIT_MAX + case 26: // _SC_DELAYTIMER_MAX + case 33: // _SC_SEM_VALUE_MAX + return 2147483647; + case 34: // _SC_SIGQUEUE_MAX + case 1: // _SC_CHILD_MAX + return 47839; + case 38: // _SC_BC_SCALE_MAX + case 36: // _SC_BC_BASE_MAX + return 99; + case 43: // _SC_LINE_MAX + case 37: // _SC_BC_DIM_MAX + return 2048; + case 0: return 2097152; // _SC_ARG_MAX + case 3: return 65536; // _SC_NGROUPS_MAX + case 28: return 32768; // _SC_MQ_PRIO_MAX + case 44: return 32767; // _SC_RE_DUP_MAX + case 75: return 16384; // _SC_THREAD_STACK_MIN + case 39: return 1000; // _SC_BC_STRING_MAX + case 89: return 700; // _SC_XOPEN_VERSION + case 71: return 256; // _SC_LOGIN_NAME_MAX + case 40: return 255; // _SC_COLL_WEIGHTS_MAX + case 2: return 100; // _SC_CLK_TCK + case 180: return 64; // _SC_HOST_NAME_MAX + case 25: return 20; // _SC_AIO_PRIO_DELTA_MAX + case 5: return 16; // _SC_STREAM_MAX + case 6: return 6; // _SC_TZNAME_MAX + case 73: return 4; // _SC_THREAD_DESTRUCTOR_ITERATIONS + } + ___setErrNo(ERRNO_CODES.EINVAL); + return -1; + }, + sbrk: function(bytes) { + // Implement a Linux-like 'memory area' for our 'process'. + // Changes the size of the memory area by |bytes|; returns the + // address of the previous top ('break') of the memory area + + // We need to make sure no one else allocates unfreeable memory! + // We must control this entirely. So we don't even need to do + // unfreeable allocations - the HEAP is ours, from STATICTOP up. + // TODO: We could in theory slice off the top of the HEAP when + // sbrk gets a negative increment in |bytes|... + var self = _sbrk; + if (!self.STATICTOP) { + STATICTOP = alignMemoryPage(STATICTOP); + self.STATICTOP = STATICTOP; + self.DATASIZE = 0; + } else { + assert(self.STATICTOP == STATICTOP, "No one should touch the heap!"); } + var ret = STATICTOP + self.DATASIZE; + self.DATASIZE += alignMemoryPage(bytes); + return ret; // Previous break location. }, // TODO: Check if these aliases are correct and if any others are needed. __01open64_: 'open', @@ -3362,33 +3523,6 @@ LibraryManager.library = { }, // ========================================================================== - // System calls - // ========================================================================== - - sbrk: function(bytes) { - // Implement a Linux-like 'memory area' for our 'process'. - // Changes the size of the memory area by |bytes|; returns the - // address of the previous top ('break') of the memory area - - // We need to make sure no one else allocates unfreeable memory! - // We must control this entirely. So we don't even need to do - // unfreeable allocations - the HEAP is ours, from STATICTOP up. - // TODO: We could in theory slice off the top of the HEAP when - // sbrk gets a negative increment in |bytes|... - var self = _sbrk; - if (!self.STATICTOP) { - STATICTOP = alignMemoryPage(STATICTOP); - self.STATICTOP = STATICTOP; - self.DATASIZE = 0; - } else { - assert(self.STATICTOP == STATICTOP, "Noone should touch the heap!"); - } - var ret = STATICTOP + self.DATASIZE; - self.DATASIZE += alignMemoryPage(bytes); - return ret; // previous break location - }, - - // ========================================================================== // pwd.h // ========================================================================== diff --git a/tests/runner.py b/tests/runner.py index b673b45c..3ccbb7d8 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -2415,6 +2415,139 @@ if 'benchmark' not in sys.argv: expected = open(path_from_root('tests', 'filesystem', 'output.txt'), 'r').read() self.do_test(src, expected, post_build=addJS) + def test_unistd_access(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'access.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'access.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_curdir(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'curdir.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'curdir.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'curdir.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_close(self): + src = open(path_from_root('tests', 'unistd', 'close.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'close.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_confstr(self): + src = open(path_from_root('tests', 'unistd', 'confstr.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'confstr.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_ttyname(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'ttyname.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'ttyname.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'ttyname.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_dup(self): + src = open(path_from_root('tests', 'unistd', 'dup.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'dup.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_pathconf(self): + src = open(path_from_root('tests', 'unistd', 'pathconf.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'pathconf.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_truncate(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'truncate.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'truncate.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_swab(self): + src = open(path_from_root('tests', 'unistd', 'swab.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'swab.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_isatty(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'isatty.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'isatty.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'isatty.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_sysconf(self): + src = open(path_from_root('tests', 'unistd', 'sysconf.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'sysconf.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_login(self): + src = open(path_from_root('tests', 'unistd', 'login.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'login.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_unlink(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'unlink.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'unlink.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_links(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'links.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'links.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_sleep(self): + src = open(path_from_root('tests', 'unistd', 'sleep.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'sleep.out'), 'r').read() + self.do_test(src, expected) + + def test_unistd_io(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + open(path_from_root('tests', 'unistd', 'io.js'), 'r').read() + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_unistd_misc(self): + src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read() + expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read() + self.do_test(src, expected) + ### 'Big' tests def test_fannkuch(self): diff --git a/tests/unistd/access.c b/tests/unistd/access.c new file mode 100644 index 00000000..89428610 --- /dev/null +++ b/tests/unistd/access.c @@ -0,0 +1,24 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> + +int main() { + char* files[] = {"/readable", "/writeable", + "/allaccess", "/forbidden", "/nonexistent"}; + for (int i = 0; i < sizeof files / sizeof files[0]; i++) { + printf("F_OK(%s): %d\n", files[i], access(files[i], F_OK)); + printf("errno: %d\n", errno); + errno = 0; + printf("R_OK(%s): %d\n", files[i], access(files[i], R_OK)); + printf("errno: %d\n", errno); + errno = 0; + printf("X_OK(%s): %d\n", files[i], access(files[i], X_OK)); + printf("errno: %d\n", errno); + errno = 0; + printf("W_OK(%s): %d\n", files[i], access(files[i], W_OK)); + printf("errno: %d\n", errno); + errno = 0; + printf("\n"); + } + return 0; +} diff --git a/tests/unistd/access.js b/tests/unistd/access.js new file mode 100644 index 00000000..ea9e6359 --- /dev/null +++ b/tests/unistd/access.js @@ -0,0 +1,4 @@ +FS.createDataFile('/', 'forbidden', '', false, false); +FS.createDataFile('/', 'readable', '', true, false); +FS.createDataFile('/', 'writeable', '', false, true); +FS.createDataFile('/', 'allaccess', '', true, true); diff --git a/tests/unistd/access.out b/tests/unistd/access.out new file mode 100644 index 00000000..dffe0b9e --- /dev/null +++ b/tests/unistd/access.out @@ -0,0 +1,45 @@ +F_OK(/readable): 0 +errno: 0 +R_OK(/readable): 0 +errno: 0 +X_OK(/readable): 0 +errno: 0 +W_OK(/readable): -1 +errno: 13 + +F_OK(/writeable): 0 +errno: 0 +R_OK(/writeable): -1 +errno: 13 +X_OK(/writeable): -1 +errno: 13 +W_OK(/writeable): 0 +errno: 0 + +F_OK(/allaccess): 0 +errno: 0 +R_OK(/allaccess): 0 +errno: 0 +X_OK(/allaccess): 0 +errno: 0 +W_OK(/allaccess): 0 +errno: 0 + +F_OK(/forbidden): 0 +errno: 0 +R_OK(/forbidden): -1 +errno: 13 +X_OK(/forbidden): -1 +errno: 13 +W_OK(/forbidden): -1 +errno: 13 + +F_OK(/nonexistent): -1 +errno: 2 +R_OK(/nonexistent): -1 +errno: 2 +X_OK(/nonexistent): -1 +errno: 2 +W_OK(/nonexistent): -1 +errno: 2 + diff --git a/tests/unistd/close.c b/tests/unistd/close.c new file mode 100644 index 00000000..7110d18a --- /dev/null +++ b/tests/unistd/close.c @@ -0,0 +1,26 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +int main() { + int f = open("/", O_RDONLY); + + printf("fsync(opened): %d\n", fsync(f)); + printf("errno: %d\n", errno); + errno = 0; + + printf("close(opened): %d\n", close(f)); + printf("errno: %d\n", errno); + errno = 0; + + printf("fsync(closed): %d\n", fsync(f)); + printf("errno: %d\n", errno); + errno = 0; + + printf("close(closed): %d\n", close(f)); + printf("errno: %d\n", errno); + errno = 0; + + return 0; +} diff --git a/tests/unistd/close.out b/tests/unistd/close.out new file mode 100644 index 00000000..66e47927 --- /dev/null +++ b/tests/unistd/close.out @@ -0,0 +1,8 @@ +fsync(opened): 0 +errno: 0 +close(opened): 0 +errno: 0 +fsync(closed): -1 +errno: 9 +close(closed): -1 +errno: 9 diff --git a/tests/unistd/confstr.c b/tests/unistd/confstr.c new file mode 100644 index 00000000..5c96c89c --- /dev/null +++ b/tests/unistd/confstr.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> + +int main() { + int vals[] = { + _CS_PATH, + _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS, + _CS_GNU_LIBC_VERSION, + _CS_GNU_LIBPTHREAD_VERSION, + _CS_POSIX_V6_ILP32_OFF32_LIBS, + _CS_POSIX_V6_ILP32_OFFBIG_LIBS, + _CS_POSIX_V6_LP64_OFF64_CFLAGS, + _CS_POSIX_V6_LP64_OFF64_LDFLAGS, + _CS_POSIX_V6_LP64_OFF64_LIBS, + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS, + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS, + _CS_POSIX_V6_ILP32_OFF32_CFLAGS, + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS, + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS, + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS + }; + char* names[] = { + "_CS_PATH", + "_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS", + "_CS_GNU_LIBC_VERSION", + "_CS_GNU_LIBPTHREAD_VERSION", + "_CS_POSIX_V6_ILP32_OFF32_LIBS", + "_CS_POSIX_V6_ILP32_OFFBIG_LIBS", + "_CS_POSIX_V6_LP64_OFF64_CFLAGS", + "_CS_POSIX_V6_LP64_OFF64_LDFLAGS", + "_CS_POSIX_V6_LP64_OFF64_LIBS", + "_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS", + "_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS", + "_CS_POSIX_V6_LPBIG_OFFBIG_LIBS", + "_CS_POSIX_V6_ILP32_OFF32_CFLAGS", + "_CS_POSIX_V6_ILP32_OFF32_LDFLAGS", + "_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS", + "_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS" + }; + char buffer[256]; + + for (int i = 0; i < sizeof vals / sizeof vals[0]; i++) { + printf("ret: %d\n", confstr(vals[i], buffer, 256)); + printf("%s: %s\n", names[i], buffer); + printf("errno: %d\n\n", errno); + errno = 0; + } + + printf("(invalid) ret: %d\n", confstr(-123, buffer, 256)); + printf("errno: %d\n", errno); + + return 0; +} diff --git a/tests/unistd/confstr.out b/tests/unistd/confstr.out new file mode 100644 index 00000000..c6019319 --- /dev/null +++ b/tests/unistd/confstr.out @@ -0,0 +1,67 @@ +ret: 2 +_CS_PATH: / +errno: 0 + +ret: 43 +_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS: POSIX_V6_ILP32_OFF32 +POSIX_V6_ILP32_OFFBIG +errno: 0 + +ret: 11 +_CS_GNU_LIBC_VERSION: glibc 2.14 +errno: 0 + +ret: 1 +_CS_GNU_LIBPTHREAD_VERSION: +errno: 0 + +ret: 1 +_CS_POSIX_V6_ILP32_OFF32_LIBS: +errno: 0 + +ret: 1 +_CS_POSIX_V6_ILP32_OFFBIG_LIBS: +errno: 0 + +ret: 1 +_CS_POSIX_V6_LP64_OFF64_CFLAGS: +errno: 0 + +ret: 1 +_CS_POSIX_V6_LP64_OFF64_LDFLAGS: +errno: 0 + +ret: 1 +_CS_POSIX_V6_LP64_OFF64_LIBS: +errno: 0 + +ret: 1 +_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS: +errno: 0 + +ret: 1 +_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS: +errno: 0 + +ret: 1 +_CS_POSIX_V6_LPBIG_OFFBIG_LIBS: +errno: 0 + +ret: 5 +_CS_POSIX_V6_ILP32_OFF32_CFLAGS: -m32 +errno: 0 + +ret: 5 +_CS_POSIX_V6_ILP32_OFF32_LDFLAGS: -m32 +errno: 0 + +ret: 5 +_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS: -m32 +errno: 0 + +ret: 48 +_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS: -m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 +errno: 0 + +(invalid) ret: 0 +errno: 22 diff --git a/tests/unistd/curdir.c b/tests/unistd/curdir.c new file mode 100644 index 00000000..63b9c7fe --- /dev/null +++ b/tests/unistd/curdir.c @@ -0,0 +1,95 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +int main() { + char buffer[256]; + printf("getwd: %s\n", getwd(buffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("getcwd: %s\n", getcwd(buffer, 256)); + printf("errno: %d\n", errno); + errno = 0; + printf("\n"); + + printf("chdir(file): %d\n", chdir("/file")); + printf("errno: %d\n", errno); + if (!errno) { + errno = 0; + printf("getwd: %s\n", getwd(buffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("getcwd: %s\n", getcwd(buffer, 256)); + printf("errno: %d\n", errno); + } + errno = 0; + printf("\n"); + + printf("chdir(device): %d\n", chdir("/device")); + printf("errno: %d\n", errno); + if (!errno) { + errno = 0; + printf("getwd: %s\n", getwd(buffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("getcwd: %s\n", getcwd(buffer, 256)); + printf("errno: %d\n", errno); + } + errno = 0; + printf("\n"); + + printf("chdir(folder): %d\n", chdir("/folder")); + printf("errno: %d\n", errno); + if (!errno) { + errno = 0; + printf("getwd: %s\n", getwd(buffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("getcwd: %s\n", getcwd(buffer, 256)); + printf("errno: %d\n", errno); + } + errno = 0; + printf("\n"); + + printf("chdir(nonexistent): %d\n", chdir("/nonexistent")); + printf("errno: %d\n", errno); + if (!errno) { + errno = 0; + printf("getwd: %s\n", getwd(buffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("getcwd: %s\n", getcwd(buffer, 256)); + printf("errno: %d\n", errno); + } + errno = 0; + printf("\n"); + + printf("chdir(link): %d\n", chdir("/link")); + printf("errno: %d\n", errno); + if (!errno) { + errno = 0; + printf("getwd: %s\n", getwd(buffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("getcwd: %s\n", getcwd(buffer, 256)); + printf("errno: %d\n", errno); + } + errno = 0; + printf("\n"); + + errno = 0; + printf("fchdir(/): %d\n", fchdir(open("/", O_RDONLY, 0777))); + printf("errno: %d\n", errno); + if (!errno) { + errno = 0; + printf("getwd: %s\n", getwd(buffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("getcwd: %s\n", getcwd(buffer, 256)); + printf("errno: %d\n", errno); + errno = 0; + } + + return 0; +} diff --git a/tests/unistd/curdir.js b/tests/unistd/curdir.js new file mode 100644 index 00000000..e271b9da --- /dev/null +++ b/tests/unistd/curdir.js @@ -0,0 +1,4 @@ +FS.createDataFile('/', 'file', '', true, true); +FS.createFolder('/', 'folder', true, true); +FS.createDevice('/', 'device', function() {}, function() {}); +FS.createLink('/', 'link', 'folder', true, true); diff --git a/tests/unistd/curdir.out b/tests/unistd/curdir.out new file mode 100644 index 00000000..e353f1c4 --- /dev/null +++ b/tests/unistd/curdir.out @@ -0,0 +1,34 @@ +getwd: / +errno: 0 +getcwd: / +errno: 0 + +chdir(file): -1 +errno: 20 + +chdir(device): -1 +errno: 20 + +chdir(folder): 0 +errno: 0 +getwd: /folder +errno: 0 +getcwd: /folder +errno: 0 + +chdir(nonexistent): -1 +errno: 2 + +chdir(link): 0 +errno: 0 +getwd: /folder +errno: 0 +getcwd: /folder +errno: 0 + +fchdir(/): 0 +errno: 0 +getwd: / +errno: 0 +getcwd: / +errno: 0 diff --git a/tests/unistd/dup.c b/tests/unistd/dup.c new file mode 100644 index 00000000..8b4dca34 --- /dev/null +++ b/tests/unistd/dup.c @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +int main() { + int f, f2, f3; + + printf("DUP\n"); + f = open("/", O_RDONLY); + f2 = open("/", O_RDONLY); + f3 = dup(f); + printf("errno: %d\n", errno); + printf("f: %d\n", f); + printf("f2: %d\n", f2); + printf("f3: %d\n", f3); + printf("close(f1): %d\n", close(f)); + printf("close(f2): %d\n", close(f2)); + printf("close(f3): %d\n", close(f3)); + printf("\n"); + errno = 0; + + printf("DUP2\n"); + f = open("/", O_RDONLY); + f2 = open("/", O_RDONLY); + f3 = dup2(f, f2); + printf("errno: %d\n", errno); + printf("f: %d\n", f); + printf("f2: %d\n", f2); + printf("f3: %d\n", f3); + printf("close(f1): %d\n", close(f)); + printf("close(f2): %d\n", close(f2)); + printf("close(f3): %d\n", close(f3)); + printf("\n"); + errno = 0; + + return 0; +} diff --git a/tests/unistd/dup.out b/tests/unistd/dup.out new file mode 100644 index 00000000..439c6fd5 --- /dev/null +++ b/tests/unistd/dup.out @@ -0,0 +1,17 @@ +DUP +errno: 0 +f: 1 +f2: 2 +f3: 3 +close(f1): 0 +close(f2): 0 +close(f3): 0 + +DUP2 +errno: 0 +f: 4 +f2: 5 +f3: 5 +close(f1): 0 +close(f2): 0 +close(f3): -1 diff --git a/tests/unistd/io.c b/tests/unistd/io.c new file mode 100644 index 00000000..eeb80373 --- /dev/null +++ b/tests/unistd/io.c @@ -0,0 +1,101 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> + +int main() { + char readBuffer[256] = {0}; + char writeBuffer[] = "writeme"; + + int fl = open("/folder", O_RDWR); + printf("read from folder: %d\n", read(fl, readBuffer, sizeof readBuffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("write to folder: %d\n", write(fl, writeBuffer, sizeof writeBuffer)); + printf("errno: %d\n\n", errno); + errno = 0; + + int bd = open("/broken-device", O_RDWR); + printf("read from broken device: %d\n", read(bd, readBuffer, sizeof readBuffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("write to broken device: %d\n", write(bd, writeBuffer, sizeof writeBuffer)); + printf("errno: %d\n\n", errno); + errno = 0; + + int d = open("/device", O_RDWR); + printf("read from device: %d\n", read(d, readBuffer, sizeof readBuffer)); + printf("data: %s\n", readBuffer); + memset(readBuffer, 0, sizeof readBuffer); + printf("errno: %d\n", errno); + errno = 0; + printf("write to device: %d\n", write(d, writeBuffer, sizeof writeBuffer)); + printf("errno: %d\n\n", errno); + errno = 0; + + int f = open("/file", O_RDWR); + printf("read from file: %d\n", read(f, readBuffer, sizeof readBuffer)); + printf("data: %s\n", readBuffer); + memset(readBuffer, 0, sizeof readBuffer); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("seek: %d\n", lseek(f, 3, SEEK_SET)); + printf("errno: %d\n\n", errno); + printf("partial read from file: %d\n", read(f, readBuffer, 3)); + printf("data: %s\n", readBuffer); + memset(readBuffer, 0, sizeof readBuffer); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("seek: %d\n", lseek(f, -2, SEEK_END)); + printf("errno: %d\n", errno); + errno = 0; + printf("partial read from end of file: %d\n", read(f, readBuffer, 3)); + printf("data: %s\n", readBuffer); + memset(readBuffer, 0, sizeof readBuffer); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("seek: %d\n", lseek(f, -15, SEEK_CUR)); + printf("errno: %d\n", errno); + errno = 0; + printf("partial read from before start of file: %d\n", read(f, readBuffer, 3)); + printf("data: %s\n", readBuffer); + memset(readBuffer, 0, sizeof readBuffer); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("seek: %d\n", lseek(f, 0, SEEK_SET)); + printf("write to start of file: %d\n", write(f, writeBuffer, 3)); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("seek: %d\n", lseek(f, 0, SEEK_END)); + printf("write to end of file: %d\n", write(f, writeBuffer, 3)); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("seek: %d\n", lseek(f, 10, SEEK_END)); + printf("write after end of file: %d\n", write(f, writeBuffer, sizeof writeBuffer)); + printf("errno: %d\n\n", errno); + errno = 0; + + int bytesRead; + printf("seek: %d\n", lseek(f, 0, SEEK_SET)); + printf("read after write: %d\n", bytesRead = read(f, readBuffer, sizeof readBuffer)); + printf("errno: %d\n", errno); + errno = 0; + printf("final: "); + for (int i = 0; i < bytesRead; i++) { + if (readBuffer[i] == 0) { + printf("\\0"); + } else { + printf("%c", readBuffer[i]); + } + } + printf("\n"); + + return 0; +} diff --git a/tests/unistd/io.js b/tests/unistd/io.js new file mode 100644 index 00000000..b129af44 --- /dev/null +++ b/tests/unistd/io.js @@ -0,0 +1,19 @@ +(function() { + var devicePayload = [65, 66, 67, 68]; + FS.createDevice('/', 'device', function() { + if (devicePayload.length) { + return devicePayload.shift(); + } else { + return null; + } + }, function(arg) { + print("TO DEVICE: " + arg); + }); + FS.createDevice('/', 'broken-device', function() { + throw new Error('Broken device input.'); + }, function(arg) { + throw new Error('Broken device output.'); + }); + FS.createDataFile('/', 'file', '1234567890', true, true); + FS.createFolder('/', 'folder', true, true); +})(); diff --git a/tests/unistd/io.out b/tests/unistd/io.out new file mode 100644 index 00000000..3061b94e --- /dev/null +++ b/tests/unistd/io.out @@ -0,0 +1,63 @@ +read from folder: -1 +errno: 9 +write to folder: -1 +errno: 9 + +read from broken device: -1 +errno: 5 +write to broken device: -1 +errno: 5 + +read from device: 4 +data: ABCD +errno: 0 +TO DEVICE: 119 +TO DEVICE: 114 +TO DEVICE: 105 +TO DEVICE: 116 +TO DEVICE: 101 +TO DEVICE: 109 +TO DEVICE: 101 +TO DEVICE: 0 +write to device: 8 +errno: 0 + +read from file: 10 +data: 1234567890 +errno: 0 + +seek: 3 +errno: 0 + +partial read from file: 3 +data: 456 +errno: 0 + +seek: 8 +errno: 0 +partial read from end of file: 2 +data: 90 +errno: 0 + +seek: -1 +errno: 22 +partial read from before start of file: 0 +data: +errno: 0 + +seek: 0 +write to start of file: 3 +errno: 0 + +seek: 10 +write to end of file: 3 +errno: 0 + +seek: 23 +write after end of file: 8 +errno: 0 + +seek: 0 +read after write: 31 +errno: 0 +final: wri4567890wri\0\0\0\0\0\0\0\0\0\0writeme\0 diff --git a/tests/unistd/isatty.c b/tests/unistd/isatty.c new file mode 100644 index 00000000..cc1ff641 --- /dev/null +++ b/tests/unistd/isatty.c @@ -0,0 +1,28 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +int main() { + printf("read: %d\n", isatty(open("/read", O_RDONLY))); + printf("errno: %d\n", errno); + errno = 0; + + printf("write: %d\n", isatty(open("/write", O_WRONLY))); + printf("errno: %d\n", errno); + errno = 0; + + printf("all: %d\n", isatty(open("/all", O_RDONLY))); + printf("errno: %d\n", errno); + errno = 0; + + printf("folder: %d\n", isatty(open("/folder", O_RDONLY))); + printf("errno: %d\n", errno); + errno = 0; + + printf("file: %d\n", isatty(open("/file", O_RDONLY))); + printf("errno: %d\n", errno); + errno = 0; + + return 0; +} diff --git a/tests/unistd/isatty.js b/tests/unistd/isatty.js new file mode 100644 index 00000000..6399f9e9 --- /dev/null +++ b/tests/unistd/isatty.js @@ -0,0 +1,5 @@ +FS.createDevice('/', 'read', function() {}, null); +FS.createDevice('/', 'write', null, function() {}); +FS.createDevice('/', 'all', function() {}, function() {}); +FS.createFolder('/', 'folder', true, true); +FS.createDataFile('/', 'file', true, true); diff --git a/tests/unistd/isatty.out b/tests/unistd/isatty.out new file mode 100644 index 00000000..3c138c0e --- /dev/null +++ b/tests/unistd/isatty.out @@ -0,0 +1,10 @@ +read: -1 +errno: 25 +write: -1 +errno: 25 +all: 0 +errno: 0 +folder: -1 +errno: 25 +file: -1 +errno: 25 diff --git a/tests/unistd/links.c b/tests/unistd/links.c new file mode 100644 index 00000000..c6da83b9 --- /dev/null +++ b/tests/unistd/links.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> + +int main() { + char* files[] = {"/link", "/file", "/folder"}; + char buffer[256] = {0}; + + for (int i = 0; i < sizeof files / sizeof files[0]; i++) { + printf("readlink(%s)\n", files[i]); + printf("ret: %d\n", readlink(files[i], buffer, 256)); + printf("errno: %d\n", errno); + printf("result: %s\n\n", buffer); + errno = 0; + } + + printf("symlink/overwrite\n"); + printf("ret: %d\n", symlink("new-nonexistent-path", "/link")); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("symlink/normal\n"); + printf("ret: %d\n", symlink("new-nonexistent-path", "/folder/link")); + printf("errno: %d\n", errno); + errno = 0; + + printf("readlink(created link)\n"); + printf("ret: %d\n", readlink("/folder/link", buffer, 256)); + printf("errno: %d\n", errno); + printf("result: %s\n\n", buffer); + errno = 0; + + printf("readlink(short buffer)\n"); + printf("ret: %d\n", readlink("/link", buffer, 4)); + printf("errno: %d\n", errno); + printf("result: %s\n", buffer); + errno = 0; + + return 0; +} diff --git a/tests/unistd/links.js b/tests/unistd/links.js new file mode 100644 index 00000000..5e58a729 --- /dev/null +++ b/tests/unistd/links.js @@ -0,0 +1,3 @@ +FS.createLink('/', 'link', '../test/../there!', true, true); +FS.createDataFile('/', 'file', 'test', true, true); +FS.createFolder('/', 'folder', true, true); diff --git a/tests/unistd/links.out b/tests/unistd/links.out new file mode 100644 index 00000000..75e410cb --- /dev/null +++ b/tests/unistd/links.out @@ -0,0 +1,31 @@ +readlink(/link) +ret: 17 +errno: 0 +result: ../test/../there! + +readlink(/file) +ret: -1 +errno: 22 +result: ../test/../there! + +readlink(/folder) +ret: -1 +errno: 22 +result: ../test/../there! + +symlink/overwrite +ret: -1 +errno: 17 + +symlink/normal +ret: 0 +errno: 0 +readlink(created link) +ret: 20 +errno: 0 +result: new-nonexistent-path + +readlink(short buffer) +ret: 3 +errno: 0 +result: ../-nonexistent-path diff --git a/tests/unistd/login.c b/tests/unistd/login.c new file mode 100644 index 00000000..2e4e1515 --- /dev/null +++ b/tests/unistd/login.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> + +int main() { + char host[256] = "--------------------------"; + + printf("gethostid: %d\n", gethostid()); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("gethostname/2 ret: %d\n", gethostname(host, 2)); + printf("gethostname/2: %s\n", host); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("gethostname/256 ret: %d\n", gethostname(host, 256)); + printf("gethostname/256: %s\n", host); + printf("errno: %d\n\n", errno); + errno = 0; + + char login[256] = "--------------------------"; + + printf("login: %s\n", getlogin()); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("login_r/2 ret: %d\n", getlogin_r(login, 2)); + printf("login_r/2: %s\n", login); + printf("errno: %d\n\n", errno); + errno = 0; + + printf("login_r/256 ret: %d\n", getlogin_r(login, 256)); + printf("login_r/256: %s\n", login); + printf("errno: %d\n", errno); + errno = 0; + + return 0; +} diff --git a/tests/unistd/login.out b/tests/unistd/login.out new file mode 100644 index 00000000..c1919c3c --- /dev/null +++ b/tests/unistd/login.out @@ -0,0 +1,21 @@ +gethostid: 42 +errno: 0 + +gethostname/2 ret: -1 +gethostname/2: em------------------------ +errno: 36 + +gethostname/256 ret: 0 +gethostname/256: emscripten +errno: 0 + +login: root +errno: 0 + +login_r/2 ret: 34 +login_r/2: -------------------------- +errno: 34 + +login_r/256 ret: 0 +login_r/256: root +errno: 0 diff --git a/tests/unistd/misc.c b/tests/unistd/misc.c new file mode 100644 index 00000000..4e7ac216 --- /dev/null +++ b/tests/unistd/misc.c @@ -0,0 +1,196 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +int main() { + int f = open("/", O_RDONLY); + + sync(); + + printf("fsync(good): %d", fsync(f)); + printf(", errno: %d\n", errno); + errno = 0; + printf("fsync(bad): %d", fsync(42)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("fdatasync(good): %d", fdatasync(f)); + printf(", errno: %d\n", errno); + errno = 0; + printf("fdatasync(bad): %d", fdatasync(42)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("tcgetpgrp(good): %d", tcgetpgrp(f)); + printf(", errno: %d\n", errno); + errno = 0; + printf("tcgetpgrp(bad): %d", tcgetpgrp(42)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("tcsetpgrp(good): %d", tcsetpgrp(f, 123)); + printf(", errno: %d\n", errno); + errno = 0; + printf("tcsetpgrp(bad): %d", tcsetpgrp(42, 123)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("link: %d", link("/here", "/there")); + printf(", errno: %d\n", errno); + errno = 0; + + printf("lockf(good): %d", lockf(f, 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("lockf(bad): %d", lockf(42, 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("nice: %d", nice(42)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("pause: %d", pause()); + printf(", errno: %d\n", errno); + errno = 0; + + int pipe_arg[2]; + printf("pipe(good): %d", pipe(pipe_arg)); + printf(", errno: %d\n", errno); + errno = 0; + printf("pipe(bad): %d", pipe(0)); + printf(", errno: %d\n", errno); + errno = 0; + + char* exec_argv[] = {"arg", 0}; + char* exec_env[] = {"a=b", 0}; + printf("execl: %d", execl("/program", "arg", 0)); + printf(", errno: %d\n", errno); + errno = 0; + printf("execle: %d", execle("/program", "arg", 0, exec_env)); + printf(", errno: %d\n", errno); + errno = 0; + printf("execlp: %d", execlp("program", "arg", 0)); + printf(", errno: %d\n", errno); + errno = 0; + printf("execv: %d", execv("program", exec_argv)); + printf(", errno: %d\n", errno); + errno = 0; + printf("execve: %d", execve("program", exec_argv, exec_env)); + printf(", errno: %d\n", errno); + errno = 0; + printf("execvp: %d", execvp("program", exec_argv)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("chown(good): %d", chown("/", 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("chown(bad): %d", chown("/noexist", 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("lchown(good): %d", lchown("/", 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("lchown(bad): %d", lchown("/noexist", 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("fchown(good): %d", fchown(f, 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("fchown(bad): %d", fchown(42, 123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("alarm: %d", alarm(42)); + printf(", errno: %d\n", errno); + errno = 0; + printf("ualarm: %d", ualarm(123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("fork: %d", fork()); + printf(", errno: %d\n", errno); + errno = 0; + printf("vfork: %d", vfork()); + printf(", errno: %d\n", errno); + errno = 0; + + printf("crypt: %d", crypt("foo", "bar")); + printf(", errno: %d\n", errno); + errno = 0; + char encrypt_block[64] = {0}; + printf("encrypt"); + encrypt(encrypt_block, 42); + printf(", errno: %d\n", errno); + errno = 0; + + printf("getgid: %d", getgid()); + printf(", errno: %d\n", errno); + errno = 0; + printf("getegid: %d", getegid()); + printf(", errno: %d\n", errno); + errno = 0; + printf("getuid: %d", getuid()); + printf(", errno: %d\n", errno); + errno = 0; + printf("geteuid: %d", geteuid()); + printf(", errno: %d\n", errno); + errno = 0; + + printf("getpgrp: %d", getpgrp()); + printf(", errno: %d\n", errno); + errno = 0; + printf("getpid: %d", getpid()); + printf(", errno: %d\n", errno); + errno = 0; + printf("getppid: %d", getppid()); + printf(", errno: %d\n", errno); + errno = 0; + + printf("getpgid: %d", getpgid(42)); + printf(", errno: %d\n", errno); + errno = 0; + printf("getsid: %d", getsid(42)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("setgid: %d", setgid(42)); + printf(", errno: %d\n", errno); + errno = 0; + printf("setegid: %d", setegid(42)); + printf(", errno: %d\n", errno); + errno = 0; + printf("setuid: %d", setuid(42)); + printf(", errno: %d\n", errno); + errno = 0; + printf("seteuid: %d", seteuid(42)); + printf(", errno: %d\n", errno); + errno = 0; + + printf("setpgrp: %d", setpgrp()); + printf(", errno: %d\n", errno); + errno = 0; + printf("setsid: %d", setsid()); + printf(", errno: %d\n", errno); + errno = 0; + + printf("setpgid: %d", setpgid(123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("setregid: %d", setregid(123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + printf("setreuid: %d", setreuid(123, 456)); + printf(", errno: %d\n", errno); + errno = 0; + + gid_t groups[10] = {42}; + printf("getgroups: %d", getgroups(10, groups)); + printf(", result: %d", groups[0]); + printf(", errno: %d\n", errno); + errno = 0; + + return 0; +} diff --git a/tests/unistd/misc.out b/tests/unistd/misc.out new file mode 100644 index 00000000..810da215 --- /dev/null +++ b/tests/unistd/misc.out @@ -0,0 +1,46 @@ +fsync(good): 0, errno: 0 +fsync(bad): -1, errno: 9 +fdatasync(good): 0, errno: 0 +fdatasync(bad): -1, errno: 9 +tcgetpgrp(good): 0, errno: 0 +tcgetpgrp(bad): 0, errno: 0 +tcsetpgrp(good): -1, errno: 22 +tcsetpgrp(bad): -1, errno: 22 +link: -1, errno: 31 +lockf(good): 0, errno: 0 +lockf(bad): -1, errno: 9 +nice: 0, errno: 1 +pause: -1, errno: 4 +pipe(good): -1, errno: 38 +pipe(bad): -1, errno: 38 +execl: -1, errno: 8 +execle: -1, errno: 8 +execlp: -1, errno: 8 +execv: -1, errno: 8 +execve: -1, errno: 8 +execvp: -1, errno: 8 +chown(good): 0, errno: 0 +chown(bad): -1, errno: 2 +lchown(good): 0, errno: 0 +lchown(bad): -1, errno: 2 +fchown(good): 0, errno: 0 +fchown(bad): -1, errno: 9 +alarm: 0, errno: 0 +ualarm: 0, errno: 0 +fork: -1, errno: 11 +vfork: -1, errno: 11 +crypt: 0, errno: 38 +encrypt, errno: 38 +getgid: 0, errno: 0 +getegid: 0, errno: 0 +getuid: 0, errno: 0 +geteuid: 0, errno: 0 +getpgrp: 0, errno: 0 +getpid: 0, errno: 0 +getppid: 0, errno: 0 +getpgid: 0, errno: 0 +getsid: 0, errno: 0 +setgid: -1, errno: 1 +setegid: -1, errno: 1 +setuid: -1, errno: 1 +seteuid: -1, errno: 1 diff --git a/tests/unistd/pathconf.c b/tests/unistd/pathconf.c new file mode 100644 index 00000000..4fac852b --- /dev/null +++ b/tests/unistd/pathconf.c @@ -0,0 +1,63 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> + +int main() { + int vals[] = { + _PC_LINK_MAX, + _PC_MAX_CANON, + _PC_MAX_INPUT, + _PC_NAME_MAX, + _PC_PATH_MAX, + _PC_PIPE_BUF, + _PC_REC_MIN_XFER_SIZE, + _PC_REC_XFER_ALIGN, + _PC_ALLOC_SIZE_MIN, + _PC_CHOWN_RESTRICTED, + _PC_NO_TRUNC, + _PC_2_SYMLINKS, + _PC_VDISABLE, + _PC_SYNC_IO, + _PC_ASYNC_IO, + _PC_PRIO_IO, + _PC_SOCK_MAXBUF, + _PC_REC_INCR_XFER_SIZE, + _PC_REC_MAX_XFER_SIZE, + _PC_SYMLINK_MAX, + _PC_FILESIZEBITS + }; + char* names[] = { + "_PC_LINK_MAX", + "_PC_MAX_CANON", + "_PC_MAX_INPUT", + "_PC_NAME_MAX", + "_PC_PATH_MAX", + "_PC_PIPE_BUF", + "_PC_REC_MIN_XFER_SIZE", + "_PC_REC_XFER_ALIGN", + "_PC_ALLOC_SIZE_MIN", + "_PC_CHOWN_RESTRICTED", + "_PC_NO_TRUNC", + "_PC_2_SYMLINKS", + "_PC_VDISABLE", + "_PC_SYNC_IO", + "_PC_ASYNC_IO", + "_PC_PRIO_IO", + "_PC_SOCK_MAXBUF", + "_PC_REC_INCR_XFER_SIZE", + "_PC_REC_MAX_XFER_SIZE", + "_PC_SYMLINK_MAX", + "_PC_FILESIZEBITS" + }; + + for (int i = 0; i < sizeof vals / sizeof vals[0]; i++) { + printf("%s: %ld\n", names[i], pathconf("/", vals[i])); + printf("errno: %d\n\n", errno); + errno = 0; + } + + printf("(invalid): %ld\n", pathconf("/", -123)); + printf("errno: %d\n", errno); + + return 0; +} diff --git a/tests/unistd/pathconf.out b/tests/unistd/pathconf.out new file mode 100644 index 00000000..1daf04a9 --- /dev/null +++ b/tests/unistd/pathconf.out @@ -0,0 +1,65 @@ +_PC_LINK_MAX: 32000 +errno: 0 + +_PC_MAX_CANON: 255 +errno: 0 + +_PC_MAX_INPUT: 255 +errno: 0 + +_PC_NAME_MAX: 255 +errno: 0 + +_PC_PATH_MAX: 4096 +errno: 0 + +_PC_PIPE_BUF: 4096 +errno: 0 + +_PC_REC_MIN_XFER_SIZE: 4096 +errno: 0 + +_PC_REC_XFER_ALIGN: 4096 +errno: 0 + +_PC_ALLOC_SIZE_MIN: 4096 +errno: 0 + +_PC_CHOWN_RESTRICTED: 1 +errno: 0 + +_PC_NO_TRUNC: 1 +errno: 0 + +_PC_2_SYMLINKS: 1 +errno: 0 + +_PC_VDISABLE: 0 +errno: 0 + +_PC_SYNC_IO: -1 +errno: 0 + +_PC_ASYNC_IO: -1 +errno: 0 + +_PC_PRIO_IO: -1 +errno: 0 + +_PC_SOCK_MAXBUF: -1 +errno: 0 + +_PC_REC_INCR_XFER_SIZE: -1 +errno: 0 + +_PC_REC_MAX_XFER_SIZE: -1 +errno: 0 + +_PC_SYMLINK_MAX: -1 +errno: 0 + +_PC_FILESIZEBITS: 64 +errno: 0 + +(invalid): -1 +errno: 22 diff --git a/tests/unistd/sleep.c b/tests/unistd/sleep.c new file mode 100644 index 00000000..5a0302e2 --- /dev/null +++ b/tests/unistd/sleep.c @@ -0,0 +1,21 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <time.h> + +int main() { + time_t start; + + start = time(0); + printf("sleep(2) ret: %d\n", sleep(2)); + printf("after sleep(2): %d\n", time(0) - start); + printf("errno: %d\n", errno); + errno = 0; + + start = time(0); + printf("usleep(3000000) ret: %d\n", usleep(3100000)); + printf("after usleep(3000000): %d\n", time(0) - start); + printf("errno: %d\n", errno); + + return 0; +} diff --git a/tests/unistd/sleep.out b/tests/unistd/sleep.out new file mode 100644 index 00000000..9a668e91 --- /dev/null +++ b/tests/unistd/sleep.out @@ -0,0 +1,6 @@ +sleep(2) ret: 0 +after sleep(2): 2 +errno: 0 +usleep(3000000) ret: 0 +after usleep(3000000): 3 +errno: 0 diff --git a/tests/unistd/swab.c b/tests/unistd/swab.c new file mode 100644 index 00000000..d5c9ec27 --- /dev/null +++ b/tests/unistd/swab.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <unistd.h> + +int main() { + char src[] = "abcdefg"; + char dst[10] = {0}; + swab(src, dst, 5); + + printf("before: %s\n", src); + printf("after: %s\n", dst); + + return 0; +} diff --git a/tests/unistd/swab.out b/tests/unistd/swab.out new file mode 100644 index 00000000..fe2c0f5c --- /dev/null +++ b/tests/unistd/swab.out @@ -0,0 +1,2 @@ +before: abcdefg +after: badc diff --git a/tests/unistd/sysconf.c b/tests/unistd/sysconf.c new file mode 100644 index 00000000..3211608e --- /dev/null +++ b/tests/unistd/sysconf.c @@ -0,0 +1,266 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> + +int main() { + int vals[] = { + _SC_PAGE_SIZE, + _SC_PAGESIZE, + _SC_ADVISORY_INFO, + _SC_BARRIERS, + _SC_ASYNCHRONOUS_IO, + _SC_CLOCK_SELECTION, + _SC_CPUTIME, + _SC_FSYNC, + _SC_IPV6, + _SC_MAPPED_FILES, + _SC_MEMLOCK, + _SC_MEMLOCK_RANGE, + _SC_MEMORY_PROTECTION, + _SC_MESSAGE_PASSING, + _SC_MONOTONIC_CLOCK, + _SC_PRIORITIZED_IO, + _SC_PRIORITY_SCHEDULING, + _SC_RAW_SOCKETS, + _SC_READER_WRITER_LOCKS, + _SC_REALTIME_SIGNALS, + _SC_SEMAPHORES, + _SC_SHARED_MEMORY_OBJECTS, + _SC_SPAWN, + _SC_SPIN_LOCKS, + _SC_SYNCHRONIZED_IO, + _SC_THREAD_ATTR_STACKADDR, + _SC_THREAD_ATTR_STACKSIZE, + _SC_THREAD_CPUTIME, + _SC_THREAD_PRIO_INHERIT, + _SC_THREAD_PRIO_PROTECT, + _SC_THREAD_PRIORITY_SCHEDULING, + _SC_THREAD_PROCESS_SHARED, + _SC_THREAD_SAFE_FUNCTIONS, + _SC_THREADS, + _SC_TIMEOUTS, + _SC_TIMERS, + _SC_VERSION, + _SC_2_C_BIND, + _SC_2_C_DEV, + _SC_2_CHAR_TERM, + _SC_2_LOCALEDEF, + _SC_2_SW_DEV, + _SC_2_VERSION, + _SC_MQ_OPEN_MAX, + _SC_XOPEN_STREAMS, + _SC_XBS5_LP64_OFF64, + _SC_XBS5_LPBIG_OFFBIG, + _SC_AIO_LISTIO_MAX, + _SC_AIO_MAX, + _SC_SPORADIC_SERVER, + _SC_THREAD_SPORADIC_SERVER, + _SC_TRACE, + _SC_TRACE_EVENT_FILTER, + _SC_TRACE_EVENT_NAME_MAX, + _SC_TRACE_INHERIT, + _SC_TRACE_LOG, + _SC_TRACE_NAME_MAX, + _SC_TRACE_SYS_MAX, + _SC_TRACE_USER_EVENT_MAX, + _SC_TYPED_MEMORY_OBJECTS, + _SC_V6_LP64_OFF64, + _SC_V6_LPBIG_OFFBIG, + _SC_2_FORT_DEV, + _SC_2_FORT_RUN, + _SC_2_PBS, + _SC_2_PBS_ACCOUNTING, + _SC_2_PBS_CHECKPOINT, + _SC_2_PBS_LOCATE, + _SC_2_PBS_MESSAGE, + _SC_2_PBS_TRACK, + _SC_2_UPE, + _SC_THREAD_THREADS_MAX, + _SC_SEM_NSEMS_MAX, + _SC_SYMLOOP_MAX, + _SC_TIMER_MAX, + _SC_V6_ILP32_OFF32, + _SC_V6_ILP32_OFFBIG, + _SC_JOB_CONTROL, + _SC_REGEXP, + _SC_SAVED_IDS, + _SC_SHELL, + _SC_XBS5_ILP32_OFF32, + _SC_XBS5_ILP32_OFFBIG, + _SC_XOPEN_CRYPT, + _SC_XOPEN_ENH_I18N, + _SC_XOPEN_LEGACY, + _SC_XOPEN_REALTIME, + _SC_XOPEN_REALTIME_THREADS, + _SC_XOPEN_SHM, + _SC_XOPEN_UNIX, + _SC_THREAD_KEYS_MAX, + _SC_IOV_MAX, + _SC_GETGR_R_SIZE_MAX, + _SC_GETPW_R_SIZE_MAX, + _SC_OPEN_MAX, + _SC_RTSIG_MAX, + _SC_EXPR_NEST_MAX, + _SC_TTY_NAME_MAX, + _SC_ATEXIT_MAX, + _SC_DELAYTIMER_MAX, + _SC_SEM_VALUE_MAX, + _SC_SIGQUEUE_MAX, + _SC_CHILD_MAX, + _SC_BC_SCALE_MAX, + _SC_BC_BASE_MAX, + _SC_LINE_MAX, + _SC_BC_DIM_MAX, + _SC_ARG_MAX, + _SC_NGROUPS_MAX, + _SC_MQ_PRIO_MAX, + _SC_RE_DUP_MAX, + _SC_THREAD_STACK_MIN, + _SC_BC_STRING_MAX, + _SC_XOPEN_VERSION, + _SC_LOGIN_NAME_MAX, + _SC_COLL_WEIGHTS_MAX, + _SC_CLK_TCK, + _SC_HOST_NAME_MAX, + _SC_AIO_PRIO_DELTA_MAX, + _SC_STREAM_MAX, + _SC_TZNAME_MAX, + _SC_THREAD_DESTRUCTOR_ITERATIONS + }; + char* names[] = { + "_SC_PAGE_SIZE", + "_SC_PAGESIZE", + "_SC_ADVISORY_INFO", + "_SC_BARRIERS", + "_SC_ASYNCHRONOUS_IO", + "_SC_CLOCK_SELECTION", + "_SC_CPUTIME", + "_SC_FSYNC", + "_SC_IPV6", + "_SC_MAPPED_FILES", + "_SC_MEMLOCK", + "_SC_MEMLOCK_RANGE", + "_SC_MEMORY_PROTECTION", + "_SC_MESSAGE_PASSING", + "_SC_MONOTONIC_CLOCK", + "_SC_PRIORITIZED_IO", + "_SC_PRIORITY_SCHEDULING", + "_SC_RAW_SOCKETS", + "_SC_READER_WRITER_LOCKS", + "_SC_REALTIME_SIGNALS", + "_SC_SEMAPHORES", + "_SC_SHARED_MEMORY_OBJECTS", + "_SC_SPAWN", + "_SC_SPIN_LOCKS", + "_SC_SYNCHRONIZED_IO", + "_SC_THREAD_ATTR_STACKADDR", + "_SC_THREAD_ATTR_STACKSIZE", + "_SC_THREAD_CPUTIME", + "_SC_THREAD_PRIO_INHERIT", + "_SC_THREAD_PRIO_PROTECT", + "_SC_THREAD_PRIORITY_SCHEDULING", + "_SC_THREAD_PROCESS_SHARED", + "_SC_THREAD_SAFE_FUNCTIONS", + "_SC_THREADS", + "_SC_TIMEOUTS", + "_SC_TIMERS", + "_SC_VERSION", + "_SC_2_C_BIND", + "_SC_2_C_DEV", + "_SC_2_CHAR_TERM", + "_SC_2_LOCALEDEF", + "_SC_2_SW_DEV", + "_SC_2_VERSION", + "_SC_MQ_OPEN_MAX", + "_SC_XOPEN_STREAMS", + "_SC_XBS5_LP64_OFF64", + "_SC_XBS5_LPBIG_OFFBIG", + "_SC_AIO_LISTIO_MAX", + "_SC_AIO_MAX", + "_SC_SPORADIC_SERVER", + "_SC_THREAD_SPORADIC_SERVER", + "_SC_TRACE", + "_SC_TRACE_EVENT_FILTER", + "_SC_TRACE_EVENT_NAME_MAX", + "_SC_TRACE_INHERIT", + "_SC_TRACE_LOG", + "_SC_TRACE_NAME_MAX", + "_SC_TRACE_SYS_MAX", + "_SC_TRACE_USER_EVENT_MAX", + "_SC_TYPED_MEMORY_OBJECTS", + "_SC_V6_LP64_OFF64", + "_SC_V6_LPBIG_OFFBIG", + "_SC_2_FORT_DEV", + "_SC_2_FORT_RUN", + "_SC_2_PBS", + "_SC_2_PBS_ACCOUNTING", + "_SC_2_PBS_CHECKPOINT", + "_SC_2_PBS_LOCATE", + "_SC_2_PBS_MESSAGE", + "_SC_2_PBS_TRACK", + "_SC_2_UPE", + "_SC_THREAD_THREADS_MAX", + "_SC_SEM_NSEMS_MAX", + "_SC_SYMLOOP_MAX", + "_SC_TIMER_MAX", + "_SC_V6_ILP32_OFF32", + "_SC_V6_ILP32_OFFBIG", + "_SC_JOB_CONTROL", + "_SC_REGEXP", + "_SC_SAVED_IDS", + "_SC_SHELL", + "_SC_XBS5_ILP32_OFF32", + "_SC_XBS5_ILP32_OFFBIG", + "_SC_XOPEN_CRYPT", + "_SC_XOPEN_ENH_I18N", + "_SC_XOPEN_LEGACY", + "_SC_XOPEN_REALTIME", + "_SC_XOPEN_REALTIME_THREADS", + "_SC_XOPEN_SHM", + "_SC_XOPEN_UNIX", + "_SC_THREAD_KEYS_MAX", + "_SC_IOV_MAX", + "_SC_GETGR_R_SIZE_MAX", + "_SC_GETPW_R_SIZE_MAX", + "_SC_OPEN_MAX", + "_SC_RTSIG_MAX", + "_SC_EXPR_NEST_MAX", + "_SC_TTY_NAME_MAX", + "_SC_ATEXIT_MAX", + "_SC_DELAYTIMER_MAX", + "_SC_SEM_VALUE_MAX", + "_SC_SIGQUEUE_MAX", + "_SC_CHILD_MAX", + "_SC_BC_SCALE_MAX", + "_SC_BC_BASE_MAX", + "_SC_LINE_MAX", + "_SC_BC_DIM_MAX", + "_SC_ARG_MAX", + "_SC_NGROUPS_MAX", + "_SC_MQ_PRIO_MAX", + "_SC_RE_DUP_MAX", + "_SC_THREAD_STACK_MIN", + "_SC_BC_STRING_MAX", + "_SC_XOPEN_VERSION", + "_SC_LOGIN_NAME_MAX", + "_SC_COLL_WEIGHTS_MAX", + "_SC_CLK_TCK", + "_SC_HOST_NAME_MAX", + "_SC_AIO_PRIO_DELTA_MAX", + "_SC_STREAM_MAX", + "_SC_TZNAME_MAX", + "_SC_THREAD_DESTRUCTOR_ITERATIONS" + }; + char buffer[256]; + + for (int i = 0; i < sizeof vals / sizeof vals[0]; i++) { + printf("%s: %ld\n", names[i], sysconf(vals[i])); + printf("errno: %d\n\n", errno); + errno = 0; + } + + printf("(invalid): %ld\n", sysconf(-123)); + printf("errno: %d\n", errno); + + return 0; +} diff --git a/tests/unistd/sysconf.out b/tests/unistd/sysconf.out new file mode 100644 index 00000000..5cb78bdb --- /dev/null +++ b/tests/unistd/sysconf.out @@ -0,0 +1,368 @@ +_SC_PAGE_SIZE: 4096 +errno: 0 + +_SC_PAGESIZE: 4096 +errno: 0 + +_SC_ADVISORY_INFO: 200809 +errno: 0 + +_SC_BARRIERS: 200809 +errno: 0 + +_SC_ASYNCHRONOUS_IO: 200809 +errno: 0 + +_SC_CLOCK_SELECTION: 200809 +errno: 0 + +_SC_CPUTIME: 200809 +errno: 0 + +_SC_FSYNC: 200809 +errno: 0 + +_SC_IPV6: 200809 +errno: 0 + +_SC_MAPPED_FILES: 200809 +errno: 0 + +_SC_MEMLOCK: 200809 +errno: 0 + +_SC_MEMLOCK_RANGE: 200809 +errno: 0 + +_SC_MEMORY_PROTECTION: 200809 +errno: 0 + +_SC_MESSAGE_PASSING: 200809 +errno: 0 + +_SC_MONOTONIC_CLOCK: 200809 +errno: 0 + +_SC_PRIORITIZED_IO: 200809 +errno: 0 + +_SC_PRIORITY_SCHEDULING: 200809 +errno: 0 + +_SC_RAW_SOCKETS: 200809 +errno: 0 + +_SC_READER_WRITER_LOCKS: 200809 +errno: 0 + +_SC_REALTIME_SIGNALS: 200809 +errno: 0 + +_SC_SEMAPHORES: 200809 +errno: 0 + +_SC_SHARED_MEMORY_OBJECTS: 200809 +errno: 0 + +_SC_SPAWN: 200809 +errno: 0 + +_SC_SPIN_LOCKS: 200809 +errno: 0 + +_SC_SYNCHRONIZED_IO: 200809 +errno: 0 + +_SC_THREAD_ATTR_STACKADDR: 200809 +errno: 0 + +_SC_THREAD_ATTR_STACKSIZE: 200809 +errno: 0 + +_SC_THREAD_CPUTIME: 200809 +errno: 0 + +_SC_THREAD_PRIO_INHERIT: 200809 +errno: 0 + +_SC_THREAD_PRIO_PROTECT: 200809 +errno: 0 + +_SC_THREAD_PRIORITY_SCHEDULING: 200809 +errno: 0 + +_SC_THREAD_PROCESS_SHARED: 200809 +errno: 0 + +_SC_THREAD_SAFE_FUNCTIONS: 200809 +errno: 0 + +_SC_THREADS: 200809 +errno: 0 + +_SC_TIMEOUTS: 200809 +errno: 0 + +_SC_TIMERS: 200809 +errno: 0 + +_SC_VERSION: 200809 +errno: 0 + +_SC_2_C_BIND: 200809 +errno: 0 + +_SC_2_C_DEV: 200809 +errno: 0 + +_SC_2_CHAR_TERM: 200809 +errno: 0 + +_SC_2_LOCALEDEF: 200809 +errno: 0 + +_SC_2_SW_DEV: 200809 +errno: 0 + +_SC_2_VERSION: 200809 +errno: 0 + +_SC_MQ_OPEN_MAX: -1 +errno: 0 + +_SC_XOPEN_STREAMS: -1 +errno: 0 + +_SC_XBS5_LP64_OFF64: -1 +errno: 0 + +_SC_XBS5_LPBIG_OFFBIG: -1 +errno: 0 + +_SC_AIO_LISTIO_MAX: -1 +errno: 0 + +_SC_AIO_MAX: -1 +errno: 0 + +_SC_SPORADIC_SERVER: -1 +errno: 0 + +_SC_THREAD_SPORADIC_SERVER: -1 +errno: 0 + +_SC_TRACE: -1 +errno: 0 + +_SC_TRACE_EVENT_FILTER: -1 +errno: 0 + +_SC_TRACE_EVENT_NAME_MAX: -1 +errno: 0 + +_SC_TRACE_INHERIT: -1 +errno: 0 + +_SC_TRACE_LOG: -1 +errno: 0 + +_SC_TRACE_NAME_MAX: -1 +errno: 0 + +_SC_TRACE_SYS_MAX: -1 +errno: 0 + +_SC_TRACE_USER_EVENT_MAX: -1 +errno: 0 + +_SC_TYPED_MEMORY_OBJECTS: -1 +errno: 0 + +_SC_V6_LP64_OFF64: -1 +errno: 0 + +_SC_V6_LPBIG_OFFBIG: -1 +errno: 0 + +_SC_2_FORT_DEV: -1 +errno: 0 + +_SC_2_FORT_RUN: -1 +errno: 0 + +_SC_2_PBS: -1 +errno: 0 + +_SC_2_PBS_ACCOUNTING: -1 +errno: 0 + +_SC_2_PBS_CHECKPOINT: -1 +errno: 0 + +_SC_2_PBS_LOCATE: -1 +errno: 0 + +_SC_2_PBS_MESSAGE: -1 +errno: 0 + +_SC_2_PBS_TRACK: -1 +errno: 0 + +_SC_2_UPE: -1 +errno: 0 + +_SC_THREAD_THREADS_MAX: -1 +errno: 0 + +_SC_SEM_NSEMS_MAX: -1 +errno: 0 + +_SC_SYMLOOP_MAX: -1 +errno: 0 + +_SC_TIMER_MAX: -1 +errno: 0 + +_SC_V6_ILP32_OFF32: 1 +errno: 0 + +_SC_V6_ILP32_OFFBIG: 1 +errno: 0 + +_SC_JOB_CONTROL: 1 +errno: 0 + +_SC_REGEXP: 1 +errno: 0 + +_SC_SAVED_IDS: 1 +errno: 0 + +_SC_SHELL: 1 +errno: 0 + +_SC_XBS5_ILP32_OFF32: 1 +errno: 0 + +_SC_XBS5_ILP32_OFFBIG: 1 +errno: 0 + +_SC_XOPEN_CRYPT: 1 +errno: 0 + +_SC_XOPEN_ENH_I18N: 1 +errno: 0 + +_SC_XOPEN_LEGACY: 1 +errno: 0 + +_SC_XOPEN_REALTIME: 1 +errno: 0 + +_SC_XOPEN_REALTIME_THREADS: 1 +errno: 0 + +_SC_XOPEN_SHM: 1 +errno: 0 + +_SC_XOPEN_UNIX: 1 +errno: 0 + +_SC_THREAD_KEYS_MAX: 1024 +errno: 0 + +_SC_IOV_MAX: 1024 +errno: 0 + +_SC_GETGR_R_SIZE_MAX: 1024 +errno: 0 + +_SC_GETPW_R_SIZE_MAX: 1024 +errno: 0 + +_SC_OPEN_MAX: 1024 +errno: 0 + +_SC_RTSIG_MAX: 32 +errno: 0 + +_SC_EXPR_NEST_MAX: 32 +errno: 0 + +_SC_TTY_NAME_MAX: 32 +errno: 0 + +_SC_ATEXIT_MAX: 2147483647 +errno: 0 + +_SC_DELAYTIMER_MAX: 2147483647 +errno: 0 + +_SC_SEM_VALUE_MAX: 2147483647 +errno: 0 + +_SC_SIGQUEUE_MAX: 47839 +errno: 0 + +_SC_CHILD_MAX: 47839 +errno: 0 + +_SC_BC_SCALE_MAX: 99 +errno: 0 + +_SC_BC_BASE_MAX: 99 +errno: 0 + +_SC_LINE_MAX: 2048 +errno: 0 + +_SC_BC_DIM_MAX: 2048 +errno: 0 + +_SC_ARG_MAX: 2097152 +errno: 0 + +_SC_NGROUPS_MAX: 65536 +errno: 0 + +_SC_MQ_PRIO_MAX: 32768 +errno: 0 + +_SC_RE_DUP_MAX: 32767 +errno: 0 + +_SC_THREAD_STACK_MIN: 16384 +errno: 0 + +_SC_BC_STRING_MAX: 1000 +errno: 0 + +_SC_XOPEN_VERSION: 700 +errno: 0 + +_SC_LOGIN_NAME_MAX: 256 +errno: 0 + +_SC_COLL_WEIGHTS_MAX: 255 +errno: 0 + +_SC_CLK_TCK: 100 +errno: 0 + +_SC_HOST_NAME_MAX: 64 +errno: 0 + +_SC_AIO_PRIO_DELTA_MAX: 20 +errno: 0 + +_SC_STREAM_MAX: 16 +errno: 0 + +_SC_TZNAME_MAX: 6 +errno: 0 + +_SC_THREAD_DESTRUCTOR_ITERATIONS: 4 +errno: 0 + +(invalid): -1 +errno: 22 diff --git a/tests/unistd/truncate.c b/tests/unistd/truncate.c new file mode 100644 index 00000000..18920976 --- /dev/null +++ b/tests/unistd/truncate.c @@ -0,0 +1,68 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <string.h> + +int main() { + struct stat s; + int f = open("/towrite", O_WRONLY); + int f2 = open("/toread", O_RDONLY); + printf("f2: %d\n", f2); + + fstat(f, &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + errno = 0; + printf("\n"); + + printf("ftruncate(10): %d\n", ftruncate(f, 10)); + printf("errno: %d\n", errno); + fstat(f, &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + errno = 0; + printf("\n"); + + printf("ftruncate(4): %d\n", ftruncate(f, 4)); + printf("errno: %d\n", errno); + fstat(f, &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + errno = 0; + printf("\n"); + + printf("ftruncate(-1): %d\n", ftruncate(f, -1)); + printf("errno: %d\n", errno); + fstat(f, &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + errno = 0; + printf("\n"); + + printf("truncate(2): %d\n", truncate("/towrite", 2)); + printf("errno: %d\n", errno); + stat("/towrite", &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + errno = 0; + printf("\n"); + + printf("truncate(readonly, 2): %d\n", truncate("/toread", 2)); + printf("errno: %d\n", errno); + stat("/toread", &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + errno = 0; + printf("\n"); + + printf("ftruncate(readonly, 4): %d\n", ftruncate(f2, 4)); + printf("errno: %d\n", errno); + fstat(f2, &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + errno = 0; + + return 0; +} diff --git a/tests/unistd/truncate.js b/tests/unistd/truncate.js new file mode 100644 index 00000000..6a4c6868 --- /dev/null +++ b/tests/unistd/truncate.js @@ -0,0 +1,2 @@ +FS.createDataFile('/', 'towrite', 'abcdef', true, true); +FS.createDataFile('/', 'toread', 'abcdef', true, false); diff --git a/tests/unistd/truncate.out b/tests/unistd/truncate.out new file mode 100644 index 00000000..2ab0f305 --- /dev/null +++ b/tests/unistd/truncate.out @@ -0,0 +1,25 @@ +st_size: 6 + +ftruncate(10): 0 +errno: 0 +st_size: 10 + +ftruncate(4): 0 +errno: 0 +st_size: 4 + +ftruncate(-1): -1 +errno: 22 +st_size: 4 + +truncate(2): 0 +errno: 0 +st_size: 2 + +truncate(readonly, 2): -1 +errno: 13 +st_size: 6 + +ftruncate(readonly, 4): -1 +errno: 22 +st_size: 6 diff --git a/tests/unistd/ttyname.c b/tests/unistd/ttyname.c new file mode 100644 index 00000000..7080be5d --- /dev/null +++ b/tests/unistd/ttyname.c @@ -0,0 +1,51 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +int main() { + char buffer[256]; + int d = open("/device", O_RDWR); + int f = open("/", O_RDONLY); + char* result; + + result = ctermid(buffer); + if (result) { + printf("ctermid: %s\n", result); + } else { + printf("ctermid errno: %d\n", errno); + errno = 0; + } + + if (ttyname_r(d, buffer, 256) == 0) { + printf("ttyname_r(d, ..., 256): %s\n", buffer); + } else { + printf("ttyname_r(d, ..., 256) errno: %d\n", errno); + errno = 0; + } + + if (ttyname_r(d, buffer, 2) == 0) { + printf("ttyname_r(d, ..., 2): %s\n", buffer); + } else { + printf("ttyname_r(d, ..., 2) errno: %d\n", errno); + errno = 0; + } + + result = ttyname(d); + if (result) { + printf("ttyname(d): %s\n", result); + } else { + printf("ttyname(d) errno: %d\n", errno); + errno = 0; + } + + result = ttyname(f); + if (result) { + printf("ttyname(f): %s\n", result); + } else { + printf("ttyname(f) errno: %d\n", errno); + errno = 0; + } + + return 0; +} diff --git a/tests/unistd/ttyname.js b/tests/unistd/ttyname.js new file mode 100644 index 00000000..a21f417f --- /dev/null +++ b/tests/unistd/ttyname.js @@ -0,0 +1 @@ +FS.createDevice('/', 'device', function() {}, function() {}); diff --git a/tests/unistd/ttyname.out b/tests/unistd/ttyname.out new file mode 100644 index 00000000..b47cbf75 --- /dev/null +++ b/tests/unistd/ttyname.out @@ -0,0 +1,5 @@ +ctermid: /dev/tty +ttyname_r(d, ..., 256): /device +ttyname_r(d, ..., 2) errno: 34 +ttyname(d): /device +ttyname(f) errno: 25 diff --git a/tests/unistd/unlink.c b/tests/unistd/unlink.c new file mode 100644 index 00000000..3f7d84b6 --- /dev/null +++ b/tests/unistd/unlink.c @@ -0,0 +1,35 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> + +int main() { + char* files[] = {"/device", "/file", "/file-forbidden", "/noexist"}; + char* folders[] = {"/empty", "/empty-forbidden", "/full"}; + int i; + + for (i = 0; i < sizeof files / sizeof files[0]; i++) { + printf("access(%s) before: %d\n", files[i], access(files[i], F_OK)); + rmdir(files[i]); + printf("errno: %d\n", errno); + errno = 0; + printf("access(%s) after rmdir: %d\n", files[i], access(files[i], F_OK)); + unlink(files[i]); + printf("errno: %d\n", errno); + errno = 0; + printf("access(%s) after unlink: %d\n\n", files[i], access(files[i], F_OK)); + } + + for (i = 0; i < sizeof folders / sizeof folders[0]; i++) { + printf("access(%s) before: %d\n", folders[i], access(folders[i], F_OK)); + unlink(folders[i]); + printf("errno: %d\n", errno); + errno = 0; + printf("access(%s) after unlink: %d\n", folders[i], access(folders[i], F_OK)); + rmdir(folders[i]); + printf("errno: %d\n", errno); + errno = 0; + printf("access(%s) after rmdir: %d\n\n", folders[i], access(folders[i], F_OK)); + } + + return 0; +} diff --git a/tests/unistd/unlink.js b/tests/unistd/unlink.js new file mode 100644 index 00000000..c2366080 --- /dev/null +++ b/tests/unistd/unlink.js @@ -0,0 +1,7 @@ +FS.createDevice('/', 'device', function() {}, function() {}); +FS.createDataFile('/', 'file', 'test', true, true); +FS.createDataFile('/', 'file-forbidden', 'test', true, false); +FS.createFolder('/', 'empty', true, true); +FS.createFolder('/', 'empty-forbidden', true, false); +FS.createFolder('/', 'full', true, true); +FS.createFolder('/full', 'junk', true, true); diff --git a/tests/unistd/unlink.out b/tests/unistd/unlink.out new file mode 100644 index 00000000..1dcec761 --- /dev/null +++ b/tests/unistd/unlink.out @@ -0,0 +1,42 @@ +access(/device) before: 0 +errno: 20 +access(/device) after rmdir: 0 +errno: 0 +access(/device) after unlink: -1 + +access(/file) before: 0 +errno: 20 +access(/file) after rmdir: 0 +errno: 0 +access(/file) after unlink: -1 + +access(/file-forbidden) before: 0 +errno: 13 +access(/file-forbidden) after rmdir: 0 +errno: 13 +access(/file-forbidden) after unlink: 0 + +access(/noexist) before: -1 +errno: 2 +access(/noexist) after rmdir: -1 +errno: 2 +access(/noexist) after unlink: -1 + +access(/empty) before: 0 +errno: 21 +access(/empty) after unlink: 0 +errno: 0 +access(/empty) after rmdir: -1 + +access(/empty-forbidden) before: 0 +errno: 21 +access(/empty-forbidden) after unlink: 0 +errno: 13 +access(/empty-forbidden) after rmdir: 0 + +access(/full) before: 0 +errno: 21 +access(/full) after unlink: 0 +errno: 39 +access(/full) after rmdir: 0 + |