aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library.js72
-rwxr-xr-xtests/runner.py71
-rw-r--r--tests/sockets/test_sockets.c (renamed from tests/websockets.c)118
-rw-r--r--tests/sockets/test_sockets_bi.c (renamed from tests/websockets_bi.c)114
-rw-r--r--tests/sockets/test_sockets_bi_bigdata.c (renamed from tests/websockets_bi_bigdata.c)119
-rw-r--r--tests/sockets/test_sockets_bi_side.c93
-rw-r--r--tests/sockets/test_sockets_bi_side_bigdata.c90
-rw-r--r--tests/sockets/test_sockets_bigdata.h (renamed from tests/websockets_bigdata.h)0
-rw-r--r--tests/sockets/test_sockets_gethostbyname.c138
-rw-r--r--tests/sockets/test_sockets_partial.c119
-rw-r--r--tests/sockets/test_sockets_select.c98
-rw-r--r--tests/sockets/test_sockets_select_server_closes_connection.c112
-rw-r--r--tests/sockets/test_sockets_select_server_closes_connection_rw.c (renamed from tests/websockets_select_server_closes_connection_rw.c)176
-rw-r--r--tests/stdio/test_rename.c3
-rw-r--r--tests/websockets_bi_listener.c151
-rw-r--r--tests/websockets_bi_side.c76
-rw-r--r--tests/websockets_bi_side_bigdata.c69
-rw-r--r--tests/websockets_gethostbyname.c132
-rw-r--r--tests/websockets_partial.c127
-rw-r--r--tests/websockets_select.c95
-rw-r--r--tests/websockets_select_server_closes_connection.c126
-rw-r--r--tools/file_packager.py4
22 files changed, 1000 insertions, 1103 deletions
diff --git a/src/library.js b/src/library.js
index e85008f3..b68a9324 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1022,14 +1022,14 @@ LibraryManager.library = {
if (relative.charAt(0) !== '.') {
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
}
- // see if the new path alreay exists
+ // see if the new path already exists
var new_node;
try {
new_node = FS.lookupNode(new_dir, new_name);
} catch (e) {
// not fatal
}
- // early out if nothing needs to changews
+ // early out if nothing needs to change
if (old_node === new_node) {
return;
}
@@ -1383,7 +1383,7 @@ LibraryManager.library = {
stream.stream_ops.allocate(stream, offset, length);
},
mmap: function(stream, buffer, offset, length, position, prot, flags) {
- // TODO if PROT is PROT_WRITE, make sure we have write acccess
+ // TODO if PROT is PROT_WRITE, make sure we have write access
if ((stream.flags & {{{ cDefine('O_ACCMODE') }}}) === {{{ cDefine('O_WRONLY')}}}) {
throw new FS.ErrnoError(ERRNO_CODES.EACCES);
}
@@ -1695,7 +1695,7 @@ LibraryManager.library = {
}
},
// NOTE: This is weird to support stdout and stderr
- // overrides in addition to print and printErr orverrides.
+ // overrides in addition to print and printErr overrides.
default_tty_ops: {
get_char: function(tty) {
if (!tty.input.length) {
@@ -2901,7 +2901,7 @@ LibraryManager.library = {
value = ENV['PATH'] || '/';
break;
case {{{ cDefine('_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS') }}}:
- // Mimicing glibc.
+ // Mimicking glibc.
value = 'POSIX_V6_ILP32_OFF32\nPOSIX_V6_ILP32_OFFBIG';
break;
case {{{ cDefine('_CS_GNU_LIBC_VERSION') }}}:
@@ -9464,17 +9464,30 @@ LibraryManager.library = {
return -1;
}
- return 0;
+ // always "fail" in non-blocking mode
+ ___setErrNo(ERRNO_CODES.EINPROGRESS);
+ return -1;
},
recv__deps: ['$FS'],
recv: function(fd, buf, len, flags) {
var info = FS.getStream(fd);
- if (!info) return -1;
- if (!info.hasData()) {
- ___setErrNo(ERRNO_CODES.EAGAIN); // no data, and all sockets are nonblocking, so this is the right behavior
+ if (!info) {
+ ___setErrNo(ERRNO_CODES.EBADF);
return -1;
}
+#if SOCKET_WEBRTC == 0
+ if (!info.hasData()) {
+ if (info.socket.readyState === WebSocket.CLOSING || info.socket.readyState === WebSocket.CLOSED) {
+ // socket has closed
+ return 0;
+ } else {
+ // else, our socket is in a valid state but truly has nothing available
+ ___setErrNo(ERRNO_CODES.EAGAIN);
+ return -1;
+ }
+ }
+#endif
var buffer = info.inQueue.shift();
#if SOCKET_DEBUG
Module.print('recv: ' + [Array.prototype.slice.call(buffer)]);
@@ -9496,7 +9509,19 @@ LibraryManager.library = {
send__deps: ['$FS'],
send: function(fd, buf, len, flags) {
var info = FS.getStream(fd);
- if (!info) return -1;
+ if (!info) {
+ ___setErrNo(ERRNO_CODES.EBADF);
+ return -1;
+ }
+#if SOCKET_WEBRTC == 0
+ if (info.socket.readyState === WebSocket.CLOSING || info.socket.readyState === WebSocket.CLOSED) {
+ ___setErrNo(ERRNO_CODES.ENOTCONN);
+ return -1;
+ } else if (info.socket.readyState === WebSocket.CONNECTING) {
+ ___setErrNo(ERRNO_CODES.EAGAIN);
+ return -1;
+ }
+#endif
info.sender(HEAPU8.subarray(buf, buf+len));
return len;
},
@@ -9634,7 +9659,8 @@ LibraryManager.library = {
bind__deps: ['connect'],
bind: function(fd, addr, addrlen) {
- return _connect(fd, addr, addrlen);
+ _connect(fd, addr, addrlen);
+ return 0;
},
listen: function(fd, backlog) {
@@ -9667,24 +9693,12 @@ LibraryManager.library = {
var errorCondition = 0;
function canRead(info) {
- // make sure hasData exists.
- // we do create it when the socket is connected,
- // but other implementations may create it lazily
- if ((info.socket.readyState == WebSocket.CLOSING || info.socket.readyState == WebSocket.CLOSED) && info.inQueue.length == 0) {
- errorCondition = -1;
- return false;
- }
- return info.hasData && info.hasData();
+ return (info.hasData && info.hasData()) ||
+ info.socket.readyState == WebSocket.CLOSING || // let recv return 0 once closed
+ info.socket.readyState == WebSocket.CLOSED;
}
function canWrite(info) {
- // make sure socket exists.
- // we do create it when the socket is connected,
- // but other implementations may create it lazily
- if ((info.socket.readyState == WebSocket.CLOSING || info.socket.readyState == WebSocket.CLOSED)) {
- errorCondition = -1;
- return false;
- }
return info.socket && (info.socket.readyState == info.socket.OPEN);
}
@@ -9703,7 +9717,11 @@ LibraryManager.library = {
if (int_ & mask) {
// index is in the set, check if it is ready for read
var info = FS.getStream(fd);
- if (info && can(info)) {
+ if (!info) {
+ ___setErrNo(ERRNO_CODES.EBADF);
+ return -1;
+ }
+ if (can(info)) {
// set bit
fd < 32 ? (dstLow = dstLow | mask) : (dstHigh = dstHigh | mask);
bitsSet++;
diff --git a/tests/runner.py b/tests/runner.py
index e77efffb..096f3426 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -27,6 +27,10 @@ Running the main part of the test suite. Don't forget to run the other parts!
benchmark - run before and after each set of changes before pushing to
master, verify no regressions
browser - runs pages in a web browser
+
+There are also commands to run specific subsets of the test suite:
+
+ browser sockets - runs websocket networking tests
browser audio - runs audio tests in a web browser (requires human verification)
To run one of those parts, do something like
@@ -12400,6 +12404,24 @@ elif 'browser' in str(sys.argv):
'browser.test_freealut'
]
+ if 'sockets' in sys.argv:
+ print
+ print 'Running the browser socket tests.'
+ print
+ i = sys.argv.index('sockets')
+ sys.argv = sys.argv[:i] + sys.argv[i+1:]
+ i = sys.argv.index('browser')
+ sys.argv = sys.argv[:i] + sys.argv[i+1:]
+ sys.argv += [
+ 'browser.test_sockets_bi',
+ 'browser.test_sockets_gethostbyname',
+ 'browser.test_sockets_bi_bigdata',
+ 'browser.test_sockets_select_server_down',
+ 'browser.test_sockets_select_server_closes_connection',
+ 'browser.test_sockets_select_server_closes_connection_rw',
+ 'browser.test_enet'
+ ]
+
# Run a server and a web page. When a test runs, we tell the server about it,
# which tells the web page, which then opens a window with the test. Doing
# it this way then allows the page to close() itself when done.
@@ -14011,14 +14033,14 @@ Press any key to continue.'''
# always run these tests last
# make sure to use different ports in each one because it takes a while for the processes to be cleaned up
- def test_websockets(self):
+ def test_sockets(self):
try:
with self.WebsockHarness(8990):
- self.btest('websockets.c', expected='571')
+ self.btest('sockets/test_sockets.c', expected='571', args=['-DSOCKK=8991'])
finally:
self.clean_pids()
- def test_websockets_partial(self):
+ def test_sockets_partial(self):
def partial(q):
import socket
@@ -14041,7 +14063,7 @@ Press any key to continue.'''
try:
with self.WebsockHarness(8990, partial):
- self.btest('websockets_partial.c', expected='165')
+ self.btest('sockets/test_sockets_partial.c', expected='165', args=['-DSOCKK=8991'])
finally:
self.clean_pids()
@@ -14053,44 +14075,35 @@ Press any key to continue.'''
proc.communicate()
return relay_server
- def test_websockets_bi(self):
+ def test_sockets_bi(self):
for datagram in [0,1]:
for fileops in [0,1]:
try:
print >> sys.stderr, 'test_websocket_bi datagram %d, fileops %d' % (datagram, fileops)
- with self.WebsockHarness(8992, self.make_relay_server(8992, 8994)):
- with self.WebsockHarness(8994, no_server=True):
- Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=8995', '-DTEST_DGRAM=%d' % datagram]).communicate()
- self.btest('websockets_bi.c', expected='2499', args=['-DSOCKK=8993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops])
+ with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)):
+ with self.WebsockHarness(6994, no_server=True):
+ Popen([PYTHON, EMCC, path_from_root('tests', 'sockets/test_sockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995', '-DTEST_DGRAM=%d' % datagram]).communicate()
+ self.btest('sockets/test_sockets_bi.c', expected='2499', args=['-DSOCKK=6993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops])
finally:
self.clean_pids()
- def test_websockets_bi_listen(self):
- try:
- with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)):
- with self.WebsockHarness(6994, no_server=True):
- Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995']).communicate()
- self.btest('websockets_bi_listener.c', expected='2499', args=['-DSOCKK=6993'])
- finally:
- self.clean_pids()
-
- def test_websockets_gethostbyname(self):
+ def test_sockets_gethostbyname(self):
try:
with self.WebsockHarness(7000):
- self.btest('websockets_gethostbyname.c', expected='571', args=['-O2'])
+ self.btest('sockets/test_sockets_gethostbyname.c', expected='571', args=['-O2', '-DSOCKK=7001'])
finally:
self.clean_pids()
- def test_websockets_bi_bigdata(self):
+ def test_sockets_bi_bigdata(self):
try:
with self.WebsockHarness(3992, self.make_relay_server(3992, 3994)):
with self.WebsockHarness(3994, no_server=True):
- Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side_bigdata.c'), '-o', 'side.html', '-DSOCKK=3995', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')]).communicate()
- self.btest('websockets_bi_bigdata.c', expected='0', args=['-DSOCKK=3993', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')])
+ Popen([PYTHON, EMCC, path_from_root('tests', 'sockets/test_sockets_bi_side_bigdata.c'), '-o', 'side.html', '-DSOCKK=3995', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests/sockets')]).communicate()
+ self.btest('sockets/test_sockets_bi_bigdata.c', expected='0', args=['-DSOCKK=3993', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests/sockets')])
finally:
self.clean_pids()
- def test_websockets_select_server_down(self):
+ def test_sockets_select_server_down(self):
def closedServer(q):
import socket
@@ -14099,11 +14112,11 @@ Press any key to continue.'''
ssock.bind(("127.0.0.1", 8994))
try:
with self.WebsockHarness(8994, closedServer):
- self.btest('websockets_select.c', expected='266')
+ self.btest('sockets/test_sockets_select.c', expected='266', args=['-DSOCKK=8995'])
finally:
self.clean_pids()
- def test_websockets_select_server_closes_connection(self):
+ def test_sockets_select_server_closes_connection(self):
def closingServer(q):
import socket
@@ -14119,11 +14132,11 @@ Press any key to continue.'''
try:
with self.WebsockHarness(8994, closingServer):
- self.btest('websockets_select_server_closes_connection.c', expected='266')
+ self.btest('sockets/test_sockets_select_server_closes_connection.c', expected='266', args=['-DSOCKK=8995'])
finally:
self.clean_pids()
- def test_websockets_select_server_closes_connection_rw(self):
+ def test_sockets_select_server_closes_connection_rw(self):
def closingServer_rw(q):
import socket
@@ -14151,7 +14164,7 @@ Press any key to continue.'''
try:
with self.WebsockHarness(8998, closingServer_rw):
- self.btest('websockets_select_server_closes_connection_rw.c', expected='266')
+ self.btest('sockets/test_sockets_select_server_closes_connection_rw.c', expected='266', args=['-DSOCKK=8999'])
finally:
self.clean_pids()
diff --git a/tests/websockets.c b/tests/sockets/test_sockets.c
index 8882f5ba..8845ef43 100644
--- a/tests/websockets.c
+++ b/tests/sockets/test_sockets.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/ioctl.h>
#include <assert.h>
#if EMSCRIPTEN
@@ -15,12 +16,18 @@
#define EXPECTED_BYTES 5
-int SocketFD;
-
+int sockfd;
int not_always_data = 0;
-unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
-{
+void finish(int result) {
+ close(sockfd);
+#if EMSCRIPTEN
+ REPORT_RESULT();
+#endif
+ exit(result);
+}
+
+unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) {
// select check for IO
fd_set sett;
FD_ZERO(&sett);
@@ -35,6 +42,7 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
int bytes;
if (ioctl(sock, FIONREAD, &bytes) || bytes == 0) {
not_always_data = 1;
+ printf("ioctl says 0, FD_ISSET says %ld\n", FD_ISSET(sock, &sett));
assert(FD_ISSET(sock, &sett) == 0);
return 0;
}
@@ -47,28 +55,42 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
unsigned int offset = 0;
while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) ||
errno == EINTR) {
- if(n>0)
- {
- if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); }
+ if(n > 0) {
+ if (((unsigned int) n)+offset > maxsize) {
+ fprintf(stderr, "too much data!");
+ finish(EXIT_FAILURE);
+ }
memcpy(output+offset, buffer, n);
offset += n;
}
}
- if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
+ if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
fprintf(stderr, "error in get_all_buf! %d", errno);
- exit(EXIT_FAILURE);
+ finish(EXIT_FAILURE);
}
return offset;
}
-int done = 0;
-
void iter(void *arg) {
- /* perform read write operations ... */
static char out[1024*2];
static int pos = 0;
- int n = get_all_buf(SocketFD, out+pos, 1024-pos);
+ fd_set fdr;
+ int res;
+
+ // make sure that sockfd is ready to read
+ FD_ZERO(&fdr);
+ FD_SET(sockfd, &fdr);
+ res = select(64, &fdr, NULL, NULL, NULL);
+ if (res == -1) {
+ perror("select failed");
+ finish(EXIT_FAILURE);
+ } else if (!FD_ISSET(sockfd, &fdr)) {
+ return;
+ }
+
+ // perform read write operations ...
+ int n = get_all_buf(sockfd, out+pos, 1024-pos);
if (n) printf("read! %d\n", n);
pos += n;
if (pos >= EXPECTED_BYTES) {
@@ -78,70 +100,44 @@ void iter(void *arg) {
sum += out[i];
}
- shutdown(SocketFD, SHUT_RDWR);
-
- close(SocketFD);
+ shutdown(sockfd, SHUT_RDWR);
- done = 1;
+ close(sockfd);
printf("sum: %d\n", sum);
-
-#if EMSCRIPTEN
- //assert(not_always_data == 1);
-
- int result = sum;
- REPORT_RESULT();
-#endif
+ finish(sum);
}
}
-int main(void)
-{
- struct sockaddr_in stSockAddr;
- int Res;
- SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+void main() {
+ struct sockaddr_in addr;
+ int res;
- if (-1 == SocketFD)
- {
+ sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sockfd == -1) {
perror("cannot create socket");
- exit(EXIT_FAILURE);
+ finish(EXIT_FAILURE);
}
-
- memset(&stSockAddr, 0, sizeof(stSockAddr));
-
- stSockAddr.sin_family = AF_INET;
- stSockAddr.sin_port = htons(
-#if EMSCRIPTEN
- 8991
-#else
- 8990
-#endif
- );
- Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr);
-
- if (0 > Res) {
- perror("error: first parameter is not a valid address family");
- close(SocketFD);
- exit(EXIT_FAILURE);
- } else if (0 == Res) {
- perror("char string (second parameter does not contain valid ipaddress)");
- close(SocketFD);
- exit(EXIT_FAILURE);
+ fcntl(sockfd, F_SETFL, O_NONBLOCK);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(SOCKK);
+ if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) {
+ perror("inet_pton failed");
+ finish(EXIT_FAILURE);
}
-
- if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) {
+
+ res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+ if (res == -1 && errno != EINPROGRESS) {
perror("connect failed");
- close(SocketFD);
- exit(EXIT_FAILURE);
-
+ finish(EXIT_FAILURE);
}
#if EMSCRIPTEN
emscripten_set_main_loop(iter, 0, 0);
#else
- while (!done) iter(NULL);
+ while (1) iter(NULL);
#endif
-
- return EXIT_SUCCESS;
}
diff --git a/tests/websockets_bi.c b/tests/sockets/test_sockets_bi.c
index fb60177b..4266d20c 100644
--- a/tests/websockets_bi.c
+++ b/tests/sockets/test_sockets_bi.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/ioctl.h>
#if EMSCRIPTEN
#include <emscripten.h>
@@ -14,14 +15,17 @@
#define EXPECTED_BYTES 28
-#ifndef SOCKK
-#define SOCKK 8992
-#endif
+int sockfd;
-int SocketFD;
+void finish(int result) {
+ close(sockfd);
+#if EMSCRIPTEN
+ REPORT_RESULT();
+#endif
+ exit(result);
+}
-unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
-{
+unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) {
int bytes;
if (ioctl(sock, FIONREAD, &bytes)) return 0;
if (bytes == 0) return 0;
@@ -35,9 +39,11 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) ||
#endif
errno == EINTR) {
- if(n>0)
- {
- if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); }
+ if(n > 0) {
+ if (((unsigned int) n)+offset > maxsize) {
+ fprintf(stderr, "too much data!");
+ finish(EXIT_FAILURE);
+ }
memcpy(output+offset, buffer, n);
offset += n;
}
@@ -45,18 +51,30 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
fprintf(stderr, "error in get_all_buf!");
- exit(EXIT_FAILURE);
+ finish(EXIT_FAILURE);
}
return offset;
}
-int done = 0;
-
void iter(void *arg) {
- /* perform read write operations ... */
static char out[1024*2];
static int pos = 0;
- int n = get_all_buf(SocketFD, out+pos, 1024-pos);
+ fd_set fdr;
+ int res;
+
+ // make sure that sockfd is ready to read
+ FD_ZERO(&fdr);
+ FD_SET(sockfd, &fdr);
+ res = select(64, &fdr, NULL, NULL, NULL);
+ if (res == -1) {
+ perror("select failed");
+ finish(EXIT_FAILURE);
+ } else if (!FD_ISSET(sockfd, &fdr)) {
+ return;
+ }
+
+ // perform read write operations ...
+ int n = get_all_buf(sockfd, out+pos, 1024-pos);
if (n) printf("read! %d\n", n);
pos += n;
if (pos >= EXPECTED_BYTES) {
@@ -66,62 +84,43 @@ void iter(void *arg) {
sum += out[i];
}
- shutdown(SocketFD, SHUT_RDWR);
-
- close(SocketFD);
-
- done = 1;
+ shutdown(sockfd, SHUT_RDWR);
+ close(sockfd);
printf("sum: %d\n", sum);
-
- emscripten_cancel_main_loop();
-
-#if EMSCRIPTEN
- int result = sum;
- REPORT_RESULT();
-#endif
+ finish(sum);
}
}
-int main(void)
-{
+int main() {
+ struct sockaddr_in addr;
+ int res;
+
printf("hello from main page\n");
- struct sockaddr_in stSockAddr;
- int Res;
#if !TEST_DGRAM
- SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#else
- SocketFD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
#endif
-
- if (-1 == SocketFD)
- {
+ if (sockfd == -1) {
perror("cannot create socket");
- exit(EXIT_FAILURE);
+ finish(EXIT_FAILURE);
}
-
- memset(&stSockAddr, 0, sizeof(stSockAddr));
-
- stSockAddr.sin_family = AF_INET;
- stSockAddr.sin_port = htons(SOCKK);
- Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr);
-
- if (0 > Res) {
- perror("error: first parameter is not a valid address family");
- close(SocketFD);
- exit(EXIT_FAILURE);
- } else if (0 == Res) {
- perror("char string (second parameter does not contain valid ipaddress)");
- close(SocketFD);
- exit(EXIT_FAILURE);
+ fcntl(sockfd, F_SETFL, O_NONBLOCK);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(SOCKK);
+ if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) {
+ perror("inet_pton failed");
+ finish(EXIT_FAILURE);
}
-
- if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) {
+
+ res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+ if (res == -1 && errno != EINPROGRESS) {
perror("connect failed");
- close(SocketFD);
- exit(EXIT_FAILURE);
-
+ finish(EXIT_FAILURE);
}
#if EMSCRIPTEN
@@ -132,9 +131,8 @@ int main(void)
"console.log('added.');");
emscripten_set_main_loop(iter, 0, 0);
#else
- while (!done) iter(NULL);
+ while (1) iter(NULL);
#endif
return EXIT_SUCCESS;
}
-
diff --git a/tests/websockets_bi_bigdata.c b/tests/sockets/test_sockets_bi_bigdata.c
index 2039f83c..c1d8100e 100644
--- a/tests/websockets_bi_bigdata.c
+++ b/tests/sockets/test_sockets_bi_bigdata.c
@@ -7,19 +7,27 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/ioctl.h>
#if EMSCRIPTEN
#include <emscripten.h>
#endif
-#include "websockets_bigdata.h"
+#include "test_sockets_bigdata.h"
#define EXPECTED_BYTES DATA_SIZE
-int SocketFD;
+int sockfd;
-unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
-{
+void finish(int result) {
+ close(sockfd);
+#if EMSCRIPTEN
+ REPORT_RESULT();
+#endif
+ exit(result);
+}
+
+unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) {
int bytes;
if (ioctl(sock, FIONREAD, &bytes)) return 0;
if (bytes == 0) return 0;
@@ -29,41 +37,51 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
unsigned int offset = 0;
while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) ||
errno == EINTR) {
- if(n>0)
- {
- if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); }
+ if (n > 0) {
+ if (((unsigned int) n)+offset > maxsize) {
+ fprintf(stderr, "too much data!");
+ finish(EXIT_FAILURE);
+ }
memcpy(output+offset, buffer, n);
offset += n;
}
}
- if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
+ if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
fprintf(stderr, "error in get_all_buf!");
- exit(EXIT_FAILURE);
+ finish(EXIT_FAILURE);
}
return offset;
}
-int done = 0;
-
void iter(void *arg) {
- /* perform read write operations ... */
static char out[EXPECTED_BYTES];
static int pos = 0;
+ fd_set fdr;
+ int res;
+
+ // make sure that sockfd has finished connecting and is ready to read
+ FD_ZERO(&fdr);
+ FD_SET(sockfd, &fdr);
+ res = select(64, &fdr, NULL, NULL, NULL);
+ if (res == -1) {
+ perror("select failed");
+ finish(EXIT_FAILURE);
+ return;
+ } else if (!FD_ISSET(sockfd, &fdr)) {
+ return;
+ }
+
+ // perform read write operations ...
printf("so far %d, expecting up to %d\n", pos, EXPECTED_BYTES-pos);
- int n = get_all_buf(SocketFD, out+pos, EXPECTED_BYTES-pos);
- if (n) printf("read! %d\n", n);
- pos += n;
+ res = get_all_buf(sockfd, out+pos, EXPECTED_BYTES-pos);
+ if (res) printf("read! %d\n", res);
+ pos += res;
if (pos >= EXPECTED_BYTES) {
- shutdown(SocketFD, SHUT_RDWR);
-
- close(SocketFD);
-
- done = 1;
+ shutdown(sockfd, SHUT_RDWR);
- emscripten_cancel_main_loop();
+ close(sockfd);
-#if EMSCRIPTEN
char *comp = generateData();
int result = strcmp(comp, out);
if (result != 0) {
@@ -71,52 +89,35 @@ void iter(void *arg) {
printf("%d:%d\n", comp[i], out[i]);
}
}
- REPORT_RESULT();
-#endif
+ finish(result);
}
}
-int main(void)
-{
- printf("hello from main page\n");
+int main() {
+ struct sockaddr_in addr;
+ int res;
- struct sockaddr_in stSockAddr;
- int Res;
- SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ printf("hello from main page\n");
- if (-1 == SocketFD)
- {
+ sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sockfd == -1) {
perror("cannot create socket");
- exit(EXIT_FAILURE);
+ finish(EXIT_FAILURE);
}
-
- memset(&stSockAddr, 0, sizeof(stSockAddr));
-
- stSockAddr.sin_family = AF_INET;
- stSockAddr.sin_port = htons(
-#if EMSCRIPTEN
- 3993
-#else
- 3992
-#endif
- );
- Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr);
-
- if (0 > Res) {
- perror("error: first parameter is not a valid address family");
- close(SocketFD);
- exit(EXIT_FAILURE);
- } else if (0 == Res) {
- perror("char string (second parameter does not contain valid ipaddress)");
- close(SocketFD);
- exit(EXIT_FAILURE);
+ fcntl(sockfd, F_SETFL, O_NONBLOCK);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(SOCKK);
+ if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) {
+ perror("inet_pton failed");
+ finish(EXIT_FAILURE);
}
- if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) {
+ res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+ if (res == -1 && errno != EINPROGRESS) {
perror("connect failed");
- close(SocketFD);
- exit(EXIT_FAILURE);
-
+ finish(EXIT_FAILURE);
}
#if EMSCRIPTEN
@@ -129,7 +130,7 @@ int main(void)
"console.log('added.');");
emscripten_set_main_loop(iter, 3, 0);
#else
- while (!done) iter(NULL);
+ while (1) iter(NULL);
#endif
return EXIT_SUCCESS;
diff --git a/tests/sockets/test_sockets_bi_side.c b/tests/sockets/test_sockets_bi_side.c
new file mode 100644
index 00000000..b8910632
--- /dev/null
+++ b/tests/sockets/test_sockets_bi_side.c
@@ -0,0 +1,93 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+#define EXPECTED_BYTES 5
+
+int sockfd = -1;
+
+void finish(int result) {
+ close(sockfd);
+ exit(result);
+}
+
+void loop() {
+ fd_set fdw;
+ int res;
+
+ // Make sure that sockfd has actually finished connecting
+ // and is ready to read.
+ FD_ZERO(&fdw);
+ FD_SET(sockfd, &fdw);
+ res = select(64, NULL, &fdw, NULL, NULL);
+ if (res == -1) {
+ perror("select failed");
+ finish(EXIT_FAILURE);
+ } else if (!FD_ISSET(sockfd, &fdw)) {
+ return;
+ }
+
+ char data[]