aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormax99x <max99x@gmail.com>2011-07-21 04:08:42 +0300
committermax99x <max99x@gmail.com>2011-07-21 04:08:42 +0300
commit818de314d4d36f1cc0a7554c8f425ab842da5983 (patch)
tree94b13f86cc56a3817a6d148608c4aa7b62b1c07f
parent10ca04685b6e0ec0e8089fbe859e0085d8020622 (diff)
Implemented <poll.h>.
-rw-r--r--src/library.js30
-rw-r--r--tests/runner.py51
2 files changed, 81 insertions, 0 deletions
diff --git a/src/library.js b/src/library.js
index 793454de..3088fb3c 100644
--- a/src/library.js
+++ b/src/library.js
@@ -857,6 +857,36 @@ LibraryManager.library = {
},
// ==========================================================================
+ // poll.h
+ // ==========================================================================
+
+ __pollfd_struct_layout: Types.structDefinitions.pollfd,
+ poll__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__pollfd_struct_layout'],
+ poll: function(fds, nfds, timeout) {
+ // int poll(struct pollfd fds[], nfds_t nfds, int timeout);
+ // http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html
+ // NOTE: This is pretty much a no-op mimicing glibc.
+ var members = ___pollfd_struct_layout.members;
+ var nonzero = 0;
+ for (var i = 0; i < nfds; i++) {
+ var pollfd = fds + ___pollfd_struct_layout.size * i;
+ var fd = {{{ makeGetValue('pollfd', 'members.fd.offset', 'i32') }}};
+ var events = {{{ makeGetValue('pollfd', 'members.events.offset', 'i16') }}};
+ var revents = 0;
+ if (fd in FS.streams) {
+ var stream = FS.streams[fd];
+ if (events & 0x1) revents |= 0x1; // POLLIN.
+ if (events & 0x4) revents |= 0x4; // POLLOUT.
+ } else {
+ if (events & 0x20) revents |= 0x20; // POLLNVAL.
+ }
+ if (revents) nonzero++;
+ {{{ makeSetValue('pollfd', 'members.revents.offset', 'revents', 'i16') }}}
+ }
+ return nonzero;
+ },
+
+ // ==========================================================================
_scanString: function() {
// Supports %x, %4x, %d.%d, %s
diff --git a/tests/runner.py b/tests/runner.py
index 4a91f59e..99ab9974 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2210,6 +2210,57 @@ if 'benchmark' not in sys.argv:
expected = open(path_from_root('tests', 'fcntl-misc', 'output.txt'), 'r').read()
self.do_test(src, expected, post_build=addPreRun)
+ def test_poll(self):
+ def addPreRun(filename):
+ src = open(filename, 'r').read().replace(
+ '// {{PRE_RUN_ADDITIONS}}',
+ '''
+ FS.createDataFile('/', 'file', 'abcdef', true, true);
+ FS.createDevice('/', 'device', function() {}, function() {});
+ '''
+ )
+ open(filename, 'w').write(src)
+ src = r'''
+ #include <stdio.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <poll.h>
+
+ int main() {
+ struct pollfd multi[5];
+ multi[0].fd = open("/file", O_RDONLY, 0777);
+ multi[1].fd = open("/device", O_RDONLY, 0777);
+ multi[2].fd = 123;
+ multi[3].fd = open("/file", O_RDONLY, 0777);
+ multi[4].fd = open("/file", O_RDONLY, 0777);
+ multi[0].events = POLLIN | POLLOUT | POLLNVAL | POLLERR;
+ multi[1].events = POLLIN | POLLOUT | POLLNVAL | POLLERR;
+ multi[2].events = POLLIN | POLLOUT | POLLNVAL | POLLERR;
+ multi[3].events = 0x00;
+ multi[4].events = POLLOUT | POLLNVAL | POLLERR;
+
+ printf("ret: %d\n", poll(multi, 5, 123));
+ printf("errno: %d\n", errno);
+ printf("multi[0].revents: 0x%x\n", multi[0].revents);
+ printf("multi[1].revents: 0x%x\n", multi[1].revents);
+ printf("multi[2].revents: 0x%x\n", multi[2].revents);
+ printf("multi[3].revents: 0x%x\n", multi[3].revents);
+ printf("multi[4].revents: 0x%x\n", multi[4].revents);
+
+ return 0;
+ }
+ '''
+ expected = r'''
+ ret: 4
+ errno: 0
+ multi[0].revents: 0x5
+ multi[1].revents: 0x5
+ multi[2].revents: 0x20
+ multi[3].revents: 0x0
+ multi[4].revents: 0x4
+ '''
+ self.do_test(src, re.sub('(^|\n)\s+', '\\1', expected), post_build=addPreRun)
+
def test_statvfs(self):
src = r'''
#include <stdio.h>