diff options
author | max99x <max99x@gmail.com> | 2011-07-20 10:20:09 +0300 |
---|---|---|
committer | max99x <max99x@gmail.com> | 2011-07-21 02:48:24 +0300 |
commit | 10ca04685b6e0ec0e8089fbe859e0085d8020622 (patch) | |
tree | e256b40bfbf8324e73c977b82c36cc4a227f7be5 | |
parent | 278416d5426493959216d46279d3c40f91f33f81 (diff) |
Implemented <fcntl.h>.
-rw-r--r-- | src/library.js | 191 | ||||
-rw-r--r-- | tests/fcntl-misc/output.txt | 10 | ||||
-rw-r--r-- | tests/fcntl-misc/src.c | 31 | ||||
-rw-r--r-- | tests/fcntl-open/output.txt | 723 | ||||
-rw-r--r-- | tests/fcntl-open/src.c | 56 | ||||
-rw-r--r-- | tests/fcntl/output.txt | 42 | ||||
-rw-r--r-- | tests/fcntl/src.c | 80 | ||||
-rw-r--r-- | tests/runner.py | 37 |
8 files changed, 1157 insertions, 13 deletions
diff --git a/src/library.js b/src/library.js index 46c396cb..793454de 100644 --- a/src/library.js +++ b/src/library.js @@ -679,6 +679,184 @@ LibraryManager.library = { }, // ========================================================================== + // fcntl.h + // ========================================================================== + + __flock_struct_layout: Types.structDefinitions.flock, + open__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', + 'strlen', 'strcpy', 'dirname', 'basename'], + open: function(path, oflag, mode) { + // int open(const char *path, int oflag, ...); + // http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html + // NOTE: This implementation tries to mimic glibc rather that strictly + // following the POSIX standard. + + // Simplify flags. + var accessMode = oflag & 0x3; // O_ACCMODE. + var isWrite = accessMode != 0x0; // O_RDONLY. + var isRead = accessMode != 0x1; // O_WRONLY. + var isCreate = Boolean(oflag & 0x40); // O_CREAT. + var isExistCheck = Boolean(oflag & 0x80); // O_EXCL. + var isTruncate = Boolean(oflag & 0x200); // O_TRUNC. + var isAppend = Boolean(oflag & 0x400); // O_APPEND. + + // Verify path. + var pathStr = Pointer_stringify(path); + if (!pathStr) { + ___setErrNo(ERRNO_CODES.ENOENT); + return -1; + } + var absolutePath = FS.absolutePath(pathStr); + if (absolutePath === null) { + ___setErrNo(ERRNO_CODES.ENOENT); + return -1; + } + var buffer = _malloc(_strlen(path) + 1); + var parentPath = Pointer_stringify(_dirname(_strcpy(buffer, path))); + var name = Pointer_stringify(_basename(_strcpy(buffer, path))); + _free(buffer); + var parent = FS.findObject(parentPath); + if (parent === null) return -1; + if (!parent.isFolder || !parent.read) { + ___setErrNo(ERRNO_CODES.EACCES); + return -1; + } + var target = parent.contents[name] || null; + + // Verify the file exists, create if needed and allowed. + if (target) { + if (isCreate && isExistCheck) { + ___setErrNo(ERRNO_CODES.EEXIST); + return -1; + } + if ((isWrite || isCreate || isTruncate) && target.isFolder) { + ___setErrNo(ERRNO_CODES.EISDIR); + return -1; + } + if (isRead && !target.read || isWrite && !target.write) { + ___setErrNo(ERRNO_CODES.EACCES); + return -1; + } + if (isTruncate && !target.isDevice) { + target.contents = []; + } else { + if (!FS.forceLoadFile(target)) { + ___setErrNo(ERRNO_CODES.EIO); + return -1; + } + } + } else { + if (!isCreate) { + ___setErrNo(ERRNO_CODES.ENOENT); + return -1; + } + if (!parent.write) { + ___setErrNo(ERRNO_CODES.EACCES); + return -1; + } + target = FS.createDataFile(parent, name, [], mode & 0x100, mode & 0x80); // S_IRUSR, S_IWUSR. + } + + // Actually create an open stream. + var id = FS.streams.length; + FS.streams[id] = { + isFolder: false, + path: absolutePath, + object: target, + position: 0, + isRead: isRead, + isWrite: isWrite, + isAppend: isAppend + }; + return id; + }, + creat__deps: ['open'], + creat: function(path, mode) { + // int creat(const char *path, mode_t mode); + // http://pubs.opengroup.org/onlinepubs/009695399/functions/creat.html + return _open(path, 0x241, mode); // O_WRONLY | O_CREAT | O_TRUNC. + }, + fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__flock_struct_layout'], + fcntl: function(fildes, cmd, arg) { + // int fcntl(int fildes, int cmd, ...); + // http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html + if (!(fildes in FS.streams)) { + ___setErrNo(ERRNO_CODES.EBADF); + return -1; + } + var stream = FS.streams[fildes]; + switch (cmd) { + case 0: // F_DUPFD. + if (arg < 0) { + ___setErrNo(ERRNO_CODES.EINVAL); + return -1; + } + var newStream = {}; + for (var member in stream) { + newStream[member] = stream[member]; + } + if (arg in FS.streams) arg = FS.streams.length; + FS.streams[arg] = newStream; + return arg; + case 1: // F_GETFD. + case 2: // F_SETFD. + return 0; // FD_CLOEXEC makes no sense for a single process. + case 3: // F_GETFL. + var flags = 0; + if (stream.isRead && stream.isWrite) flags = 0x2; // O_RDWR. + else if (!stream.isRead && stream.isWrite) flags = 0x1; // O_WRONLY. + else if (stream.isRead && !stream.isWrite) flags = 0x0; // O_RDONLY. + if (stream.isAppend) flags |= 0x400; // O_APPEND. + // Synchronization and blocking flags are irrelevant to us. + return flags; + case 4: // F_SETFL. + stream.isAppend = Boolean(arg | 0x400); // O_APPEND. + // Synchronization and blocking flags are irrelevant to us. + return 0; + case 5: // F_GETLK. + var offset = ___flock_struct_layout.members.l_type.offset; + // We're always unlocked. + {{{ makeSetValue('arg', 'offset', '2', 'i16') }}} // F_UNLCK. + return 0; + case 6: // F_SETLK. + case 7: // F_SETLKW. + // Pretend that the locking is successful. + return 0; + case 8: // F_SETOWN. + case 9: // F_GETOWN. + // These are for sockets. We don't have them implemented (yet?). + ___setErrNo(ERRNO_CODES.EINVAL); + return -1; + default: + ___setErrNo(ERRNO_CODES.EINVAL); + return -1; + } + // Should never be reached. Only to silence strict warnings. + return -1; + }, + posix_fadvise: function(fd, offset, len, advice) { + // int posix_fadvise(int fd, off_t offset, off_t len, int advice); + // http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_fadvise.html + // Advise as much as you wish. We don't care. + return 0; + }, + posix_madvise: 'posix_fadvise', + posix_fallocate__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], + posix_fallocate: function(fd, offset, len) { + // int posix_fallocate(int fd, off_t offset, off_t len); + // http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_fallocate.html + if (!(fd in FS.streams) || FS.streams[fd].link || + FS.streams[fd].isFolder || FS.streams[fd].isDevice) { + ___setErrNo(ERRNO_CODES.EBADF); + return -1; + } + var contents = FS.streams[fd].object.contents; + var limit = offset + len; + while (limit > contents.length) contents.push(0); + return 0; + }, + + // ========================================================================== _scanString: function() { // Supports %x, %4x, %d.%d, %s @@ -1446,17 +1624,6 @@ LibraryManager.library = { // unix file IO, see http://rabbit.eng.miami.edu/info/functions/unixio.html - open: function(filename, flags, mode) { - filename = Pointer_stringify(filename); - if (flags === 0) { // RDONLY - return STDIO.open(filename); - } else if (flags === 1) { // WRONLY - return STDIO.prepare(filename); - } else { - return assert(false, 'open with odd params: ' + [flags, mode]); - } - }, - __01open64___deps: ['open'], __01open64_: function(filename, mode, flags) { // open(), but with flags and mode switched. @@ -1472,8 +1639,6 @@ LibraryManager.library = { return STDIO.read(stream, ptr, numbytes); }, - fcntl: function() { }, // TODO... - mmap: function(start, num, prot, flags, stream, offset) { // Leaky and non-shared... FIXME var info = STDIO.streams[stream]; diff --git a/tests/fcntl-misc/output.txt b/tests/fcntl-misc/output.txt new file mode 100644 index 00000000..73eae541 --- /dev/null +++ b/tests/fcntl-misc/output.txt @@ -0,0 +1,10 @@ +posix_fadvise: 0 +errno: 0 + +posix_fallocate: 0 +errno: 0 +st_size: 6 + +posix_fallocate2: 0 +errno: 0 +st_size: 10 diff --git a/tests/fcntl-misc/src.c b/tests/fcntl-misc/src.c new file mode 100644 index 00000000..73734969 --- /dev/null +++ b/tests/fcntl-misc/src.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <errno.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +int main() { + struct stat s; + int f = open("/test", O_RDONLY, 0777); + + printf("posix_fadvise: %d\n", posix_fadvise(f, 3, 2, POSIX_FADV_DONTNEED)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("posix_fallocate: %d\n", posix_fallocate(f, 3, 2)); + printf("errno: %d\n", errno); + stat("/test", &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + printf("\n"); + errno = 0; + + printf("posix_fallocate2: %d\n", posix_fallocate(f, 3, 7)); + printf("errno: %d\n", errno); + stat("/test", &s); + printf("st_size: %d\n", s.st_size); + memset(&s, 0, sizeof s); + + return 0; +} diff --git a/tests/fcntl-open/output.txt b/tests/fcntl-open/output.txt new file mode 100644 index 00000000..314ae880 --- /dev/null +++ b/tests/fcntl-open/output.txt @@ -0,0 +1,723 @@ +EXISTING FILE 0,0 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,0 +success: 1 +errno: 0 +st_mode: 040000 + +NON-EXISTING 0,0 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,1 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,1 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,1 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 0,2 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,2 +success: 1 +errno: 0 +st_mode: 040000 + +NON-EXISTING 0,2 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,3 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 0,3 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 0,3 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 0,4 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,4 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,4 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,5 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,5 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,5 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 0,6 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,6 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,6 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,7 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 0,7 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 0,7 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 0,8 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,8 +success: 1 +errno: 0 +st_mode: 040000 + +NON-EXISTING 0,8 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,9 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,9 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,9 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 0,10 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,10 +success: 1 +errno: 0 +st_mode: 040000 + +NON-EXISTING 0,10 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,11 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 0,11 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 0,11 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 0,12 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,12 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,12 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,13 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,13 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,13 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 0,14 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 0,14 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 0,14 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 0,15 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 0,15 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 0,15 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,0 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,0 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,0 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,1 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,1 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,1 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,2 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,2 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,2 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,3 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 1,3 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 1,3 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,4 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,4 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,4 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,5 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,5 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,5 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,6 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,6 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,6 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,7 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 1,7 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 1,7 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,8 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,8 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,8 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,9 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,9 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,9 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,10 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,10 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,10 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,11 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 1,11 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 1,11 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,12 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,12 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,12 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,13 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,13 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,13 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 1,14 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 1,14 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 1,14 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 1,15 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 1,15 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 1,15 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,0 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,0 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,0 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,1 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,1 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,1 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,2 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,2 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,2 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,3 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 2,3 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 2,3 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,4 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,4 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,4 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,5 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,5 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,5 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,6 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,6 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,6 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,7 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 2,7 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 2,7 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,8 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,8 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,8 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,9 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,9 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,9 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,10 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,10 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,10 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,11 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 2,11 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 2,11 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,12 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,12 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,12 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,13 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,13 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,13 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FILE 2,14 +success: 1 +errno: 0 +st_mode: 0100000 + +EXISTING FOLDER 2,14 +success: 0 +errno: 21 +st_mode: 040000 + +NON-EXISTING 2,14 +success: 0 +errno: 2 +st_mode: 00 + +EXISTING FILE 2,15 +success: 0 +errno: 17 +st_mode: 0100000 + +EXISTING FOLDER 2,15 +success: 0 +errno: 17 +st_mode: 040000 + +NON-EXISTING 2,15 +success: 1 +errno: 0 +st_mode: 0100000 + +CREAT +success: 1 +errno: 0 diff --git a/tests/fcntl-open/src.c b/tests/fcntl-open/src.c new file mode 100644 index 00000000..52d2e7e4 --- /dev/null +++ b/tests/fcntl-open/src.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <errno.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +int main() { + struct stat s; + int modes[] = {O_RDONLY, O_WRONLY, O_RDWR}; + char nonexistent_name[] = "/noexist-##"; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 16; j++) { + int flags = modes[i]; + if (j & 0x1) flags |= O_CREAT; + if (j & 0x2) flags |= O_EXCL; + if (j & 0x4) flags |= O_TRUNC; + if (j & 0x8) flags |= O_APPEND; + + printf("EXISTING FILE %d,%d\n", i, j); + printf("success: %d\n", open("/test-file", flags, 0777) != -1); + printf("errno: %d\n", errno); + stat("/test-file", &s); + printf("st_mode: 0%o\n", s.st_mode & 037777777000); + memset(&s, 0, sizeof s); + printf("\n"); + errno = 0; + + printf("EXISTING FOLDER %d,%d\n", i, j); + printf("success: %d\n", open("/test-folder", flags, 0777) != -1); + printf("errno: %d\n", errno); + stat("/test-folder", &s); + printf("st_mode: 0%o\n", s.st_mode & 037777777000); + memset(&s, 0, sizeof s); + printf("\n"); + errno = 0; + + nonexistent_name[9] = 'a' + i; + nonexistent_name[10] = 'a' + j; + printf("NON-EXISTING %d,%d\n", i, j); + printf("success: %d\n", open(nonexistent_name, flags, 0777) != -1); + printf("errno: %d\n", errno); + stat(nonexistent_name, &s); + printf("st_mode: 0%o\n", s.st_mode & 037777777000); + memset(&s, 0, sizeof s); + printf("\n"); + errno = 0; + } + } + + printf("CREAT\n"); + printf("success: %d\n", creat("/creat-me", 0777) != -1); + printf("errno: %d\n", errno); + + return 0; +} diff --git a/tests/fcntl/output.txt b/tests/fcntl/output.txt new file mode 100644 index 00000000..1077e89b --- /dev/null +++ b/tests/fcntl/output.txt @@ -0,0 +1,42 @@ +F_DUPFD: 100 +errno: 0 + +F_DUPFD/error1: -1 +errno: 9 + +F_DUPFD/error2: -1 +errno: 22 + +F_GETFD: 0 +errno: 0 + +F_SETFD: 0 +errno: 0 + +F_GETFL: 2 +errno: 0 + +F_SETFL: 0 +errno: 0 + +F_GETFL/2: 0x402 +errno: 0 + +F_GETLK: 0 +errno: 0 +lk.l_type == F_UNLCK: 1 + +F_SETLK: 0 +errno: 0 + +F_SETLKW: 0 +errno: 0 + +F_SETOWN: -1 +errno: 22 + +F_GETOWN: -1 +errno: 22 + +INVALID: -1 +errno: 22 diff --git a/tests/fcntl/src.c b/tests/fcntl/src.c new file mode 100644 index 00000000..1e9a1536 --- /dev/null +++ b/tests/fcntl/src.c @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> + +int main() { + int f = open("/test", O_RDWR, 0777); + + printf("F_DUPFD: %d\n", fcntl(f, F_DUPFD, 100)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_DUPFD/error1: %d\n", fcntl(50, F_DUPFD, 200)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_DUPFD/error2: %d\n", fcntl(f, F_DUPFD, -1)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_GETFD: %d\n", fcntl(f, F_GETFD)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_SETFD: %d\n", fcntl(f, F_SETFD)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_GETFL: %d\n", fcntl(f, F_GETFL)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_SETFL: %d\n", fcntl(f, F_SETFL, O_APPEND)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_GETFL/2: %#x\n", fcntl(f, F_GETFL)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + flock lk; + lk.l_type = 42; + printf("F_GETLK: %d\n", fcntl(f, F_GETLK, &lk)); + printf("errno: %d\n", errno); + printf("lk.l_type == F_UNLCK: %d\n", lk.l_type == F_UNLCK); + printf("\n"); + errno = 0; + + printf("F_SETLK: %d\n", fcntl(f, F_SETLK, &lk)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_SETLKW: %d\n", fcntl(f, F_SETLK, &lk)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_SETOWN: %d\n", fcntl(f, F_SETOWN, 123)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("F_GETOWN: %d\n", fcntl(f, F_GETOWN)); + printf("errno: %d\n", errno); + printf("\n"); + errno = 0; + + printf("INVALID: %d\n", fcntl(f, 123)); + printf("errno: %d\n", errno); + + return 0; +} diff --git a/tests/runner.py b/tests/runner.py index 27c19867..4a91f59e 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -2173,6 +2173,43 @@ if 'benchmark' not in sys.argv: expected = open(path_from_root('tests', 'stat', 'output.txt'), 'r').read() self.do_test(src, expected, post_build=addPreRun) + def test_fcntl(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + "FS.createDataFile('/', 'test', 'abcdef', true, true);" + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'fcntl', 'src.c'), 'r').read() + expected = open(path_from_root('tests', 'fcntl', 'output.txt'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_fcntl_open(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + ''' + FS.createDataFile('/', 'test-file', 'abcdef', true, true); + FS.createFolder('/', 'test-folder', true, true); + FS.root.write = true; + ''' + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'fcntl-open', 'src.c'), 'r').read() + expected = open(path_from_root('tests', 'fcntl-open', 'output.txt'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + + def test_fcntl_misc(self): + def addPreRun(filename): + src = open(filename, 'r').read().replace( + '// {{PRE_RUN_ADDITIONS}}', + "FS.createDataFile('/', 'test', 'abcdef', true, true);" + ) + open(filename, 'w').write(src) + src = open(path_from_root('tests', 'fcntl-misc', 'src.c'), 'r').read() + expected = open(path_from_root('tests', 'fcntl-misc', 'output.txt'), 'r').read() + self.do_test(src, expected, post_build=addPreRun) + def test_statvfs(self): src = r''' #include <stdio.h> |