Merge branch 'incoming' of github.com:kanaka/emscripten into incoming
This commit is contained in:
Коммит
020c6b7291
126
src/library.js
126
src/library.js
|
@ -63,6 +63,24 @@ LibraryManager.library = {
|
|||
// This is set to false when the runtime is initialized, allowing you
|
||||
// to modify the filesystem freely before run() is called.
|
||||
ignorePermissions: true,
|
||||
createFileHandle: function(stream, fd) {
|
||||
if (typeof stream === 'undefined') {
|
||||
stream = null;
|
||||
}
|
||||
fd = (typeof fd !== 'undefined') ? fd : FS.streams.length;
|
||||
for (var i = FS.streams.length; i < fd; i++) {
|
||||
FS.streams[i] = null; // Keep dense
|
||||
}
|
||||
// Close WebSocket first if we are about to replace the fd (i.e. dup2)
|
||||
if (FS.streams[fd] && FS.streams[fd].socket && FS.streams[fd].socket.close) {
|
||||
FS.streams[fd].socket.close();
|
||||
}
|
||||
FS.streams[fd] = stream;
|
||||
return fd;
|
||||
},
|
||||
removeFileHandle: function(fd) {
|
||||
FS.streams[fd] = null;
|
||||
},
|
||||
joinPath: function(parts, forceRelative) {
|
||||
var ret = parts[0];
|
||||
for (var i = 1; i < parts.length; i++) {
|
||||
|
@ -677,10 +695,9 @@ LibraryManager.library = {
|
|||
___setErrNo(ERRNO_CODES.EACCES);
|
||||
return 0;
|
||||
}
|
||||
var id = FS.streams.length; // Keep dense
|
||||
var contents = [];
|
||||
for (var key in target.contents) contents.push(key);
|
||||
FS.streams[id] = {
|
||||
var id = FS.createFileHandle({
|
||||
path: path,
|
||||
object: target,
|
||||
// An index into contents. Special values: -2 is ".", -1 is "..".
|
||||
|
@ -697,7 +714,7 @@ LibraryManager.library = {
|
|||
contents: contents,
|
||||
// Each stream has its own area for readdir() returns.
|
||||
currentEntry: _malloc(___dirent_struct_layout.__size__)
|
||||
};
|
||||
});
|
||||
#if ASSERTIONS
|
||||
FS.checkStreams();
|
||||
#endif
|
||||
|
@ -1215,7 +1232,7 @@ LibraryManager.library = {
|
|||
finalPath = path.parentPath + '/' + path.name;
|
||||
}
|
||||
// Actually create an open stream.
|
||||
var id = FS.streams.length; // Keep dense
|
||||
var id;
|
||||
if (target.isFolder) {
|
||||
var entryBuffer = 0;
|
||||
if (___dirent_struct_layout) {
|
||||
|
@ -1223,7 +1240,7 @@ LibraryManager.library = {
|
|||
}
|
||||
var contents = [];
|
||||
for (var key in target.contents) contents.push(key);
|
||||
FS.streams[id] = {
|
||||
id = FS.createFileHandle({
|
||||
path: finalPath,
|
||||
object: target,
|
||||
// An index into contents. Special values: -2 is ".", -1 is "..".
|
||||
|
@ -1240,9 +1257,9 @@ LibraryManager.library = {
|
|||
contents: contents,
|
||||
// Each stream has its own area for readdir() returns.
|
||||
currentEntry: entryBuffer
|
||||
};
|
||||
});
|
||||
} else {
|
||||
FS.streams[id] = {
|
||||
id = FS.createFileHandle({
|
||||
path: finalPath,
|
||||
object: target,
|
||||
position: 0,
|
||||
|
@ -1252,7 +1269,7 @@ LibraryManager.library = {
|
|||
error: false,
|
||||
eof: false,
|
||||
ungotten: []
|
||||
};
|
||||
});
|
||||
}
|
||||
#if ASSERTIONS
|
||||
FS.checkStreams();
|
||||
|
@ -1295,10 +1312,7 @@ LibraryManager.library = {
|
|||
newStream[member] = stream[member];
|
||||
}
|
||||
arg = dup2 ? arg : Math.max(arg, FS.streams.length); // dup2 wants exactly arg; fcntl wants a free descriptor >= arg
|
||||
for (var i = FS.streams.length; i < arg; i++) {
|
||||
FS.streams[i] = null; // Keep dense
|
||||
}
|
||||
FS.streams[arg] = newStream;
|
||||
FS.createFileHandle(newStream, arg);
|
||||
#if ASSERTIONS
|
||||
FS.checkStreams();
|
||||
#endif
|
||||
|
@ -1775,12 +1789,14 @@ LibraryManager.library = {
|
|||
return bytesRead;
|
||||
}
|
||||
},
|
||||
read__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'pread'],
|
||||
read__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'recv', 'pread'],
|
||||
read: function(fildes, buf, nbyte) {
|
||||
// ssize_t read(int fildes, void *buf, size_t nbyte);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/read.html
|
||||
var stream = FS.streams[fildes];
|
||||
if (!stream) {
|
||||
if ('socket' in stream) {
|
||||
return _recv(fildes, buf, nbyte, 0);
|
||||
} else if (!stream) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return -1;
|
||||
} else if (!stream.isRead) {
|
||||
|
@ -1971,12 +1987,14 @@ LibraryManager.library = {
|
|||
return i;
|
||||
}
|
||||
},
|
||||
write__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'pwrite'],
|
||||
write__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'send', 'pwrite'],
|
||||
write: function(fildes, buf, nbyte) {
|
||||
// ssize_t write(int fildes, const void *buf, size_t nbyte);
|
||||
// http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
|
||||
var stream = FS.streams[fildes];
|
||||
if (!stream) {
|
||||
if ('socket' in stream) {
|
||||
return _send(fildes, buf, nbyte, 0);
|
||||
} else if (!stream) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return -1;
|
||||
} else if (!stream.isWrite) {
|
||||
|
@ -7291,7 +7309,13 @@ LibraryManager.library = {
|
|||
*/
|
||||
socket__deps: ['$Sockets'],
|
||||
socket: function(family, type, protocol) {
|
||||
var fd = Sockets.nextFd++;
|
||||
var fd = FS.createFileHandle({
|
||||
addr: null,
|
||||
port: null,
|
||||
inQueue: new CircularBuffer(INCOMING_QUEUE_LENGTH),
|
||||
header: new Uint16Array(2),
|
||||
bound: false
|
||||
};
|
||||
assert(fd < 64); // select() assumes socket fd values are in 0..63
|
||||
var stream = type == {{{ cDefine('SOCK_STREAM') }}};
|
||||
if (protocol) {
|
||||
|
@ -7408,13 +7432,6 @@ LibraryManager.library = {
|
|||
};
|
||||
};
|
||||
|
||||
Sockets.fds[fd] = {
|
||||
addr: null,
|
||||
port: null,
|
||||
inQueue: new CircularBuffer(INCOMING_QUEUE_LENGTH),
|
||||
header: new Uint16Array(2),
|
||||
bound: false
|
||||
};
|
||||
return fd;
|
||||
},
|
||||
|
||||
|
@ -7436,7 +7453,7 @@ LibraryManager.library = {
|
|||
|
||||
bind__deps: ['$Sockets', '_inet_ntop_raw', 'ntohs', 'mkport'],
|
||||
bind: function(fd, addr, addrlen) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
if (addr) {
|
||||
info.port = _ntohs(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16'));
|
||||
|
@ -7457,7 +7474,7 @@ LibraryManager.library = {
|
|||
|
||||
sendmsg__deps: ['$Sockets', 'bind', '_inet_ntop_raw', 'ntohs'],
|
||||
sendmsg: function(fd, msg, flags) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
// if we are not connected, use the address info in the message
|
||||
if (!info.bound) {
|
||||
|
@ -7513,7 +7530,7 @@ LibraryManager.library = {
|
|||
|
||||
recvmsg__deps: ['$Sockets', 'bind', '__setErrNo', '$ERRNO_CODES', 'htons'],
|
||||
recvmsg: function(fd, msg, flags) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
// if we are not connected, use the address info in the message
|
||||
if (!info.port) {
|
||||
|
@ -7564,14 +7581,14 @@ LibraryManager.library = {
|
|||
},
|
||||
|
||||
shutdown: function(fd, how) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
info.close();
|
||||
Sockets.fds[fd] = null;
|
||||
FS.removeFileHandle(fd);
|
||||
},
|
||||
|
||||
ioctl: function(fd, request, varargs) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
var bytes = 0;
|
||||
if (info.hasData()) {
|
||||
|
@ -7591,7 +7608,7 @@ LibraryManager.library = {
|
|||
// TODO: webrtc queued incoming connections, etc.
|
||||
// For now, the model is that bind does a connect, and we "accept" that one connection,
|
||||
// which has host:port the same as ours. We also return the same socket fd.
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
if (addr) {
|
||||
setValue(addr + Sockets.sockaddr_in_layout.sin_addr, info.addr, 'i32');
|
||||
|
@ -7632,7 +7649,7 @@ LibraryManager.library = {
|
|||
var mask = 1 << (fd % 32), int = fd < 32 ? srcLow : srcHigh;
|
||||
if (int & mask) {
|
||||
// index is in the set, check if it is ready for read
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (info && can(info)) {
|
||||
// set bit
|
||||
fd < 32 ? (dstLow = dstLow | mask) : (dstHigh = dstHigh | mask);
|
||||
|
@ -7657,22 +7674,21 @@ LibraryManager.library = {
|
|||
#else
|
||||
socket__deps: ['$Sockets'],
|
||||
socket: function(family, type, protocol) {
|
||||
var fd = Sockets.nextFd++;
|
||||
assert(fd < 64); // select() assumes socket fd values are in 0..63
|
||||
var stream = type == {{{ cDefine('SOCK_STREAM') }}};
|
||||
if (protocol) {
|
||||
assert(stream == (protocol == {{{ cDefine('IPPROTO_TCP') }}})); // if stream, must be tcp
|
||||
assert(stream == (protocol == {{{ cDefine('IPPROTO_TCP') }}})); // if SOCK_STREAM, must be tcp
|
||||
}
|
||||
Sockets.fds[fd] = {
|
||||
var fd = FS.createFileHandle({
|
||||
connected: false,
|
||||
stream: stream
|
||||
};
|
||||
});
|
||||
assert(fd < 64); // select() assumes socket fd values are in 0..63
|
||||
return fd;
|
||||
},
|
||||
|
||||
connect__deps: ['$Sockets', '_inet_ntop_raw', 'htons', 'gethostbyname'],
|
||||
connect__deps: ['$FS', '$Sockets', '_inet_ntop_raw', 'ntohs', 'gethostbyname'],
|
||||
connect: function(fd, addr, addrlen) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
info.connected = true;
|
||||
info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32');
|
||||
|
@ -7788,9 +7804,9 @@ LibraryManager.library = {
|
|||
return 0;
|
||||
},
|
||||
|
||||
recv__deps: ['$Sockets'],
|
||||
recv__deps: ['$FS'],
|
||||
recv: function(fd, buf, len, flags) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[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
|
||||
|
@ -7814,17 +7830,17 @@ LibraryManager.library = {
|
|||
return buffer.length;
|
||||
},
|
||||
|
||||
send__deps: ['$Sockets'],
|
||||
send__deps: ['$FS'],
|
||||
send: function(fd, buf, len, flags) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
info.sender(HEAPU8.subarray(buf, buf+len));
|
||||
return len;
|
||||
},
|
||||
|
||||
sendmsg__deps: ['$Sockets', 'connect'],
|
||||
sendmsg__deps: ['$FS', '$Sockets', 'connect'],
|
||||
sendmsg: function(fd, msg, flags) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
// if we are not connected, use the address info in the message
|
||||
if (!info.connected) {
|
||||
|
@ -7857,9 +7873,9 @@ LibraryManager.library = {
|
|||
return ret;
|
||||
},
|
||||
|
||||
recvmsg__deps: ['$Sockets', 'connect', 'recv', '__setErrNo', '$ERRNO_CODES', 'htons'],
|
||||
recvmsg__deps: ['$FS', '$Sockets', 'connect', 'recv', '__setErrNo', '$ERRNO_CODES', 'htons'],
|
||||
recvmsg: function(fd, msg, flags) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
// if we are not connected, use the address info in the message
|
||||
if (!info.connected) {
|
||||
|
@ -7915,9 +7931,9 @@ LibraryManager.library = {
|
|||
return ret;
|
||||
},
|
||||
|
||||
recvfrom__deps: ['$Sockets', 'connect', 'recv'],
|
||||
recvfrom__deps: ['$FS', 'connect', 'recv'],
|
||||
recvfrom: function(fd, buf, len, flags, addr, addrlen) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
// if we are not connected, use the address info in the message
|
||||
if (!info.connected) {
|
||||
|
@ -7928,14 +7944,14 @@ LibraryManager.library = {
|
|||
},
|
||||
|
||||
shutdown: function(fd, how) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
info.socket.close();
|
||||
Sockets.fds[fd] = null;
|
||||
FS.removeFileHandle(fd);
|
||||
},
|
||||
|
||||
ioctl: function(fd, request, varargs) {
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
var bytes = 0;
|
||||
if (info.hasData()) {
|
||||
|
@ -7960,11 +7976,12 @@ LibraryManager.library = {
|
|||
return 0;
|
||||
},
|
||||
|
||||
accept__deps: ['$FS', '$Sockets'],
|
||||
accept: function(fd, addr, addrlen) {
|
||||
// TODO: webrtc queued incoming connections, etc.
|
||||
// For now, the model is that bind does a connect, and we "accept" that one connection,
|
||||
// which has host:port the same as ours. We also return the same socket fd.
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (!info) return -1;
|
||||
if (addr) {
|
||||
setValue(addr + Sockets.sockaddr_in_layout.sin_addr, info.addr, 'i32');
|
||||
|
@ -7974,6 +7991,7 @@ LibraryManager.library = {
|
|||
return fd;
|
||||
},
|
||||
|
||||
select__deps: ['$FS'],
|
||||
select: function(nfds, readfds, writefds, exceptfds, timeout) {
|
||||
// readfds are supported,
|
||||
// writefds checks socket open status
|
||||
|
@ -8019,7 +8037,7 @@ LibraryManager.library = {
|
|||
var mask = 1 << (fd % 32), int = fd < 32 ? srcLow : srcHigh;
|
||||
if (int & mask) {
|
||||
// index is in the set, check if it is ready for read
|
||||
var info = Sockets.fds[fd];
|
||||
var info = FS.streams[fd];
|
||||
if (info && can(info)) {
|
||||
// set bit
|
||||
fd < 32 ? (dstLow = dstLow | mask) : (dstHigh = dstHigh | mask);
|
||||
|
|
|
@ -12919,20 +12919,22 @@ elif 'browser' in str(sys.argv):
|
|||
|
||||
def test_websockets_bi(self):
|
||||
for datagram in [0,1]:
|
||||
try:
|
||||
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=['-DTEST_DGRAM=%d' % datagram])
|
||||
finally:
|
||||
self.clean_pids()
|
||||
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])
|
||||
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')
|
||||
self.btest('websockets_bi_listener.c', expected='2499', args=['-DSOCKK=6993'])
|
||||
finally:
|
||||
self.clean_pids()
|
||||
|
||||
|
@ -12948,7 +12950,7 @@ elif 'browser' in str(sys.argv):
|
|||
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=['-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')])
|
||||
self.btest('websockets_bi_bigdata.c', expected='0', args=['-DSOCKK=3993', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')])
|
||||
finally:
|
||||
self.clean_pids()
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
#define EXPECTED_BYTES 28
|
||||
|
||||
#ifndef SOCKK
|
||||
#define SOCKK 8992
|
||||
#endif
|
||||
|
||||
int SocketFD;
|
||||
|
||||
unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
|
||||
|
@ -25,7 +29,11 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize)
|
|||
char buffer[1024];
|
||||
int n;
|
||||
unsigned int offset = 0;
|
||||
#if TEST_FILE_OPS
|
||||
while((errno = 0, (n = read(sock, buffer, sizeof(buffer)))>0) ||
|
||||
#else
|
||||
while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) ||
|
||||
#endif
|
||||
errno == EINTR) {
|
||||
if(n>0)
|
||||
{
|
||||
|
@ -96,13 +104,7 @@ int main(void)
|
|||
memset(&stSockAddr, 0, sizeof(stSockAddr));
|
||||
|
||||
stSockAddr.sin_family = AF_INET;
|
||||
stSockAddr.sin_port = htons(
|
||||
#if EMSCRIPTEN
|
||||
8993
|
||||
#else
|
||||
8992
|
||||
#endif
|
||||
);
|
||||
stSockAddr.sin_port = htons(SOCKK);
|
||||
Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr);
|
||||
|
||||
if (0 > Res) {
|
||||
|
|
|
@ -54,10 +54,17 @@ int main(void)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#if TEST_FILE_OPS
|
||||
printf("write..\n");
|
||||
|
||||
char data[] = "hello from the other siide (fileops)\n";
|
||||
write(SocketFD, data, sizeof(data));
|
||||
#else
|
||||
printf("send..\n");
|
||||
|
||||
char data[] = "hello from the other siide\n";
|
||||
send(SocketFD, data, sizeof(data), 0);
|
||||
#endif
|
||||
|
||||
printf("stall..\n");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче