summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rwxr-xr-xemcc5
-rwxr-xr-xemscripten.py5
-rwxr-xr-xscons-tools/emscripten.py17
-rwxr-xr-xscons-tools/llvm.py7
-rw-r--r--src/intertyper.js6
-rw-r--r--src/library.js326
-rw-r--r--src/library_egl.js9
-rw-r--r--src/library_glut.js2
-rw-r--r--src/library_openal.js14
-rw-r--r--src/library_path.js14
-rw-r--r--src/library_sdl.js4
-rw-r--r--src/preamble.js9
-rw-r--r--src/settings.js16
-rw-r--r--src/shell.js53
-rw-r--r--system/include/libc/sys/signal.h4
-rw-r--r--system/include/net/if.h21
-rw-r--r--system/include/net/netinet/in.h67
-rw-r--r--system/include/netdb.h36
-rw-r--r--system/include/sys/ioctl.h58
-rw-r--r--system/include/sys/select.h2
-rw-r--r--system/include/sys/socket.h211
-rw-r--r--system/lib/libc/musl/src/stdlib/ecvt.c19
-rw-r--r--system/lib/libc/musl/src/stdlib/fcvt.c25
-rw-r--r--system/lib/libc/musl/src/stdlib/gcvt.c8
-rw-r--r--system/lib/libcextra.symbols3
-rwxr-xr-xtests/runner.py92
-rw-r--r--tools/asm_module.py2
-rw-r--r--tools/shared.py16
29 files changed, 770 insertions, 282 deletions
diff --git a/AUTHORS b/AUTHORS
index d3cdd156..5161f7ad 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -92,4 +92,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Michael Lelli <toadking@toadking.com>
* Yu Kobayashi <yukoba@accelart.jp>
* Pin Zhang <zhangpin04@gmail.com>
+* Nick Bray <ncbray@chromium.org> (copyright owned by Google, Inc.)
diff --git a/emcc b/emcc
index ca715542..0eb4499b 100755
--- a/emcc
+++ b/emcc
@@ -1297,6 +1297,11 @@ try:
'wctob.c',
'wctomb.c',
]],
+ ['stdlib', [
+ 'ecvt.c',
+ 'fcvt.c',
+ 'gcvt.c',
+ ]],
['string', [
'wcpcpy.c',
'wcpncpy.c',
diff --git a/emscripten.py b/emscripten.py
index ab68fcaa..aa47e4f1 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -11,7 +11,6 @@ headers, for the libc implementation in JS).
import os, sys, json, optparse, subprocess, re, time, multiprocessing, string
-from tools import shared
from tools import jsrun, cache as cache_module, tempfiles
from tools.response_file import read_response_file
@@ -26,6 +25,7 @@ def get_configuration():
if hasattr(get_configuration, 'configuration'):
return get_configuration.configuration
+ from tools import shared
configuration = shared.Configuration(environ=os.environ)
get_configuration.configuration = configuration
return configuration
@@ -469,6 +469,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
}
''' % (sig, i, args, arg_coercions, jsret))
+ from tools import shared
asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n'
basic_funcs.append('invoke_%s' % sig)
@@ -807,7 +808,7 @@ WARNING: You should normally never use this! Use emcc instead.
'''
if len(positional) != 1:
- raise RuntimeError('Must provide exactly one positional argument.')
+ raise RuntimeError('Must provide exactly one positional argument. Got ' + str(len(positional)) + ': "' + '", "'.join(positional) + '"')
keywords.infile = os.path.abspath(positional[0])
if isinstance(keywords.outfile, basestring):
keywords.outfile = open(keywords.outfile, 'w')
diff --git a/scons-tools/emscripten.py b/scons-tools/emscripten.py
index 473c51ad..b4912aaa 100755
--- a/scons-tools/emscripten.py
+++ b/scons-tools/emscripten.py
@@ -24,6 +24,7 @@ def build_version_file(env):
EMSCRIPTEN_DEPENDENCIES = [
env.Glob('${EMSCRIPTEN_HOME}/src/*.js'),
+ env.Glob('${EMSCRIPTEN_HOME}/src/embind/*.js'),
env.Glob('${EMSCRIPTEN_HOME}/tools/*.py'),
'${EMSCRIPTEN_HOME}/emscripten.py',
]
@@ -141,7 +142,7 @@ def emscripten(env, target_js, source_bc):
[global_emscripten_min_js] = env.JSOptimizer(
buildName('global.min.js'),
closure_js,
- JS_OPTIMIZER_PASSES=['simplifyExpressionsPost', 'compress', 'last'])
+ JS_OPTIMIZER_PASSES=['simplifyExpressionsPost', 'minifyWhitespace', 'last'])
[emscripten_iteration_js] = env.WrapInModule(
buildName('iteration.js'),
@@ -155,8 +156,6 @@ def emscripten(env, target_js, source_bc):
buildName('min.js'),
global_emscripten_min_js)
- env.InstallAs(buildName('js'), emscripten_js)
-
return [emscripten_iteration_js, emscripten_js, emscripten_min_js]
LIBC_SOURCES = [
@@ -265,9 +264,9 @@ def generate(env):
)
env.Replace(
- CC='${LLVM_ROOT}/${CLANG}',
- CXX='${LLVM_ROOT}/${CLANGXX}',
- AR='${LLVM_ROOT}/${LLVM_LINK}',
+ CC=os.path.join('${LLVM_ROOT}', '${CLANG}'),
+ CXX=os.path.join('${LLVM_ROOT}', '${CLANGXX}'),
+ AR=os.path.join('${LLVM_ROOT}', '${LLVM_LINK}'),
ARCOM='$AR -o $TARGET $SOURCES',
OBJSUFFIX='.bc',
LIBPREFIX='',
@@ -301,6 +300,12 @@ def generate(env):
'__IEEE_LITTLE_ENDIAN',
])
+ env.Append(
+ CPPPATH=[
+ env.Dir('${EMSCRIPTEN_HOME}/system/include'),
+ ]
+ )
+
env['BUILDERS']['Emscripten'] = Builder(
action='$PYTHON ${EMSCRIPTEN_HOME}/emscripten.py $EMSCRIPTEN_FLAGS $_EMSCRIPTEN_SETTINGS_FLAGS --temp-dir=$EMSCRIPTEN_TEMP_DIR --compiler $JS_ENGINE --relooper=third-party/relooper.js $SOURCE > $TARGET',
target_scanner=EmscriptenScanner)
diff --git a/scons-tools/llvm.py b/scons-tools/llvm.py
index f272bd16..2dc65dd3 100755
--- a/scons-tools/llvm.py
+++ b/scons-tools/llvm.py
@@ -1,5 +1,6 @@
from SCons.Scanner.Prog import scan
from SCons.Builder import Builder
+import os
def exists(env):
return True
@@ -23,11 +24,11 @@ def generate(env):
LLVM_LINK='llvm-link')
env['BUILDERS']['LLVMDis'] = Builder(
- action='${LLVM_ROOT}/$LLVM_DIS -o=$TARGET $SOURCE')
+ action=os.path.join('${LLVM_ROOT}', '$LLVM_DIS') + ' -o=$TARGET $SOURCE')
env['BUILDERS']['LLVMOpt'] = Builder(
- action='${LLVM_ROOT}/$LLVM_OPT $LLVM_OPT_FLAGS $LLVM_OPT_PASSES -o=$TARGET $SOURCE')
+ action=os.path.join('${LLVM_ROOT}', '$LLVM_OPT') + ' $LLVM_OPT_FLAGS $LLVM_OPT_PASSES -o=$TARGET $SOURCE')
env['BUILDERS']['LLVMLink'] = Builder(
- action='${LLVM_ROOT}/$LLVM_LINK -o=$TARGET $SOURCES',
+ action=os.path.join('${LLVM_ROOT}', '$LLVM_LINK') + ' -o=$TARGET $SOURCES',
emitter=add_libraries)
diff --git a/src/intertyper.js b/src/intertyper.js
index abfbdacb..dd6e5522 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -700,6 +700,12 @@ function intertyper(data, sidePass, baseLineNums) {
item.intertype = 'value';
if (tokensLeft[0].text == 'sideeffect') tokensLeft.splice(0, 1);
item.ident = tokensLeft[0].text.substr(1, tokensLeft[0].text.length-2) || ';'; // use ; for empty inline assembly
+ var i = 0;
+ splitTokenList(tokensLeft[3].item.tokens).map(function(element) {
+ var ident = toNiceIdent(element[1].text);
+ var type = element[0].text;
+ item.ident = item.ident.replace(new RegExp('\\$' + i++, 'g'), ident);
+ });
return { forward: null, ret: [item], item: item };
}
if (item.ident.substr(-2) == '()') {
diff --git a/src/library.js b/src/library.js
index f48220bb..a6a38cfe 100644
--- a/src/library.js
+++ b/src/library.js
@@ -56,7 +56,7 @@ LibraryManager.library = {
// to modify the filesystem freely before run() is called.
ignorePermissions: true,
- ErrnoError: function (errno) {
+ ErrnoError: function(errno) {
this.errno = errno;
for (var key in ERRNO_CODES) {
if (ERRNO_CODES[key] === errno) {
@@ -75,19 +75,19 @@ LibraryManager.library = {
//
// nodes
//
- hashName: function (parentid, name) {
+ hashName: function(parentid, name) {
var hash = 0;
for (var i = 0; i < name.length; i++) {
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
}
return (parentid + hash) % FS.name_table.length;
},
- hashAddNode: function (node) {
+ hashAddNode: function(node) {
var hash = FS.hashName(node.parent.id, node.name);
node.name_next = FS.name_table[hash];
FS.name_table[hash] = node;
},
- hashRemoveNode: function (node) {
+ hashRemoveNode: function(node) {
var hash = FS.hashName(node.parent.id, node.name);
if (FS.name_table[hash] === node) {
FS.name_table[hash] = node.name_next;
@@ -102,7 +102,7 @@ LibraryManager.library = {
}
}
},
- lookupNode: function (parent, name) {
+ lookupNode: function(parent, name) {
var err = FS.mayLookup(parent);
if (err) {
throw new FS.ErrnoError(err);
@@ -116,7 +116,7 @@ LibraryManager.library = {
// if we failed to find it in the cache, call into the VFS
return VFS.lookup(parent, name);
},
- createNode: function (parent, name, mode, rdev) {
+ createNode: function(parent, name, mode, rdev) {
var node = {
id: FS.nextInode++,
name: name,
@@ -136,12 +136,12 @@ LibraryManager.library = {
var readMode = {{{ cDefine('S_IRUGO') }}} | {{{ cDefine('S_IXUGO') }}};
var writeMode = {{{ cDefine('S_IWUGO') }}};
Object.defineProperty(node, 'read', {
- get: function () { return (node.mode & readMode) === readMode; },
- set: function (val) { val ? node.mode |= readMode : node.mode &= ~readMode; }
+ get: function() { return (node.mode & readMode) === readMode; },
+ set: function(val) { val ? node.mode |= readMode : node.mode &= ~readMode; }
});
Object.defineProperty(node, 'write', {
- get: function () { return (node.mode & writeMode) === writeMode; },
- set: function (val) { val ? node.mode |= writeMode : node.mode &= ~writeMode; }
+ get: function() { return (node.mode & writeMode) === writeMode; },
+ set: function(val) { val ? node.mode |= writeMode : node.mode &= ~writeMode; }
});
// TODO add:
// isFolder
@@ -149,31 +149,31 @@ LibraryManager.library = {
FS.hashAddNode(node);
return node;
},
- destroyNode: function (node) {
+ destroyNode: function(node) {
FS.hashRemoveNode(node);
},
- isRoot: function (node) {
+ isRoot: function(node) {
return node === node.parent;
},
- isMountpoint: function (node) {
+ isMountpoint: function(node) {
return node.mounted;
},
- isFile: function (mode) {
+ isFile: function(mode) {
return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFREG') }}};
},
- isDir: function (mode) {
+ isDir: function(mode) {
return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFDIR') }}};
},
- isLink: function (mode) {
+ isLink: function(mode) {
return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFLNK') }}};
},
- isChrdev: function (mode) {
+ isChrdev: function(mode) {
return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFCHR') }}};
},
- isBlkdev: function (mode) {
+ isBlkdev: function(mode) {
return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFBLK') }}};
},
- isFIFO: function (mode) {
+ isFIFO: function(mode) {
return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFIFO') }}};
},
@@ -183,7 +183,7 @@ LibraryManager.library = {
cwd: function() {
return FS.currentPath;
},
- lookupPath: function (path, opts) {
+ lookupPath: function(path, opts) {
path = PATH.resolve(FS.currentPath, path);
opts = opts || { recurse_count: 0 };
@@ -192,7 +192,7 @@ LibraryManager.library = {
}
// split the path
- var parts = PATH.normalizeArray(path.split('/').filter(function (p) {
+ var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
return !!p;
}), false);
@@ -236,7 +236,7 @@ LibraryManager.library = {
return { path: current_path, node: current };
},
- getPath: function (node) {
+ getPath: function(node) {
var path;
while (true) {
if (FS.isRoot(node)) {
@@ -268,7 +268,7 @@ LibraryManager.library = {
'"xa+"': {{{ cDefine('O_APPEND') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_RDWR') }}} | {{{ cDefine('O_EXCL') }}}
},
// convert the 'r', 'r+', etc. to it's corresponding set of O_* flags
- modeStringToFlags: function (str) {
+ modeStringToFlags: function(str) {
var flags = FS.flagModes[str];
if (typeof flags === 'undefined') {
throw new Error('Unknown file open mode: ' + str);
@@ -276,7 +276,7 @@ LibraryManager.library = {
return flags;
},
// convert O_* bitmask to a string for nodePermissions
- flagsToPermissionString: function (flag) {
+ flagsToPermissionString: function(flag) {
var accmode = flag & {{{ cDefine('O_ACCMODE') }}};
var perms = ['r', 'w', 'rw'][accmode];
if ((flag & {{{ cDefine('O_TRUNC') }}})) {
@@ -284,7 +284,7 @@ LibraryManager.library = {
}
return perms;
},
- nodePermissions: function (node, perms) {
+ nodePermissions: function(node, perms) {
if (FS.ignorePermissions) {
return 0;
}
@@ -298,10 +298,10 @@ LibraryManager.library = {
}
return 0;
},
- mayLookup: function (dir) {
+ mayLookup: function(dir) {
return FS.nodePermissions(dir, 'x');
},
- mayMknod: function (mode) {
+ mayMknod: function(mode) {
switch (mode & {{{ cDefine('S_IFMT') }}}) {
case {{{ cDefine('S_IFREG') }}}:
case {{{ cDefine('S_IFCHR') }}}:
@@ -313,7 +313,7 @@ LibraryManager.library = {
return ERRNO_CODES.EINVAL;
}
},
- mayCreate: function (dir, name) {
+ mayCreate: function(dir, name) {
try {
var node = FS.lookupNode(dir, name);
return ERRNO_CODES.EEXIST;
@@ -321,7 +321,7 @@ LibraryManager.library = {
}
return FS.nodePermissions(dir, 'wx');
},
- mayDelete: function (dir, name, isdir) {
+ mayDelete: function(dir, name, isdir) {
var node;
try {
node = FS.lookupNode(dir, name);
@@ -346,7 +346,7 @@ LibraryManager.library = {
}
return 0;
},
- mayOpen: function (node, flags) {
+ mayOpen: function(node, flags) {
if (!node) {
return ERRNO_CODES.ENOENT;
}
@@ -371,7 +371,7 @@ LibraryManager.library = {
// however, once opened, the stream's operations are overridden with
// the operations of the device its underlying node maps back to.
chrdev_stream_ops: {
- open: function (stream) {
+ open: function(stream) {
var device = FS.getDevice(stream.node.rdev);
// override node's stream ops with the device's
stream.stream_ops = device.stream_ops;
@@ -380,23 +380,23 @@ LibraryManager.library = {
stream.stream_ops.open(stream);
}
},
- llseek: function () {
+ llseek: function() {
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
}
},
- major: function (dev) {
+ major: function(dev) {
return ((dev) >> 8);
},
- minor: function (dev) {
+ minor: function(dev) {
return ((dev) & 0xff);
},
- makedev: function (ma, mi) {
+ makedev: function(ma, mi) {
return ((ma) << 8 | (mi));
},
- registerDevice: function (dev, ops) {
+ registerDevice: function(dev, ops) {
FS.devices[dev] = { stream_ops: ops };
},
- getDevice: function (dev) {
+ getDevice: function(dev) {
return FS.devices[dev];
},
@@ -404,7 +404,7 @@ LibraryManager.library = {
// streams
//
MAX_OPEN_FDS: 4096,
- nextfd: function (fd_start, fd_end) {
+ nextfd: function(fd_start, fd_end) {
fd_start = fd_start || 1;
fd_end = fd_end || FS.MAX_OPEN_FDS;
for (var fd = fd_start; fd <= fd_end; fd++) {
@@ -414,46 +414,46 @@ LibraryManager.library = {
}
throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
},
- getStream: function (fd) {
+ getStream: function(fd) {
return FS.streams[fd];
},
- createStream: function (stream, fd_start, fd_end) {
+ createStream: function(stream, fd_start, fd_end) {
var fd = FS.nextfd(fd_start, fd_end);
stream.fd = fd;
// compatibility
Object.defineProperty(stream, 'object', {
- get: function () { return stream.node; },
- set: function (val) { stream.node = val; }
+ get: function() { return stream.node; },
+ set: function(val) { stream.node = val; }
});
Object.defineProperty(stream, 'isRead', {
- get: function () { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; }
+ get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; }
});
Object.defineProperty(stream, 'isWrite', {
- get: function () { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; }
+ get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; }
});
Object.defineProperty(stream, 'isAppend', {
- get: function () { return (stream.flags & {{{ cDefine('O_APPEND') }}}); }
+ get: function() { return (stream.flags & {{{ cDefine('O_APPEND') }}}); }
});
FS.streams[fd] = stream;
return stream;
},
- closeStream: function (fd) {
+ closeStream: function(fd) {
FS.streams[fd] = null;
},
//
// general
//
- createDefaultDirectories: function () {
+ createDefaultDirectories: function() {
VFS.mkdir('/tmp', 0777);
},
- createDefaultDevices: function () {
+ createDefaultDevices: function() {
// create /dev
VFS.mkdir('/dev', 0777);
// setup /dev/null
FS.registerDevice(FS.makedev(1, 3), {
- read: function () { return 0; },
- write: function () { return 0; }
+ read: function() { return 0; },
+ write: function() { return 0; }
});
VFS.mkdev('/dev/null', 0666, FS.makedev(1, 3));
// setup /dev/tty and /dev/tty1
@@ -468,7 +468,7 @@ LibraryManager.library = {
VFS.mkdir('/dev/shm', 0777);
VFS.mkdir('/dev/shm/tmp', 0777);
},
- createStandardStreams: function () {
+ createStandardStreams: function() {
// TODO deprecate the old functionality of a single
// input / output callback and that utilizes FS.createDevice
// and instead require a unique set of stream ops
@@ -506,14 +506,14 @@ LibraryManager.library = {
{{{ makeSetValue(makeGlobalUse('_stderr'), 0, 'stderr.fd', 'void*') }}};
assert(stderr.fd === 3, 'invalid handle for stderr (' + stderr.fd + ')');
},
- staticInit: function () {
+ staticInit: function() {
FS.root = FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
VFS.mount(MEMFS, {}, '/');
FS.createDefaultDirectories();
FS.createDefaultDevices();
},
- init: function (input, output, error) {
+ init: function(input, output, error) {
assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
FS.init.initialized = true;
@@ -524,7 +524,7 @@ LibraryManager.library = {
FS.createStandardStreams();
},
- quit: function () {
+ quit: function() {
FS.init.initialized = false;
for (var i = 0; i < FS.streams.length; i++) {
var stream = FS.streams[i];
@@ -538,24 +538,24 @@ LibraryManager.library = {
//
// compatibility
//
- getMode: function (canRead, canWrite) {
+ getMode: function(canRead, canWrite) {
var mode = 0;
if (canRead) mode |= {{{ cDefine('S_IRUGO') }}} | {{{ cDefine('S_IXUGO') }}};
if (canWrite) mode |= {{{ cDefine('S_IWUGO') }}};
return mode;
},
- joinPath: function (parts, forceRelative) {
+ joinPath: function(parts, forceRelative) {
var path = PATH.join.apply(null, parts);
if (forceRelative && path[0] == '/') path = path.substr(1);
return path;
},
- absolutePath: function (relative, base) {
+ absolutePath: function(relative, base) {
return PATH.resolve(base, relative);
},
- standardizePath: function (path) {
+ standardizePath: function(path) {
return PATH.normalize(path);
},
- findObject: function (path, dontResolveLastLink) {
+ findObject: function(path, dontResolveLastLink) {
var ret = FS.analyzePath(path, dontResolveLastLink);
if (ret.exists) {
return ret.object;
@@ -564,7 +564,7 @@ LibraryManager.library = {
return null;
}
},
- analyzePath: function (path, dontResolveLastLink) {
+ analyzePath: function(path, dontResolveLastLink) {
// operate from within the context of the symlink's target
try {
var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
@@ -592,12 +592,12 @@ LibraryManager.library = {
};
return ret;
},
- createFolder: function (parent, name, canRead, canWrite) {
+ createFolder: function(parent, name, canRead, canWrite) {
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name);
var mode = FS.getMode(canRead, canWrite);
return VFS.mkdir(path, mode);
},
- createPath: function (parent, path, canRead, canWrite) {
+ createPath: function(parent, path, canRead, canWrite) {
parent = typeof parent === 'string' ? parent : FS.getPath(parent);
var parts = path.split('/').reverse();
while (parts.length) {
@@ -613,12 +613,12 @@ LibraryManager.library = {
}
return current;
},
- createFile: function (parent, name, properties, canRead, canWrite) {
+ createFile: function(parent, name, properties, canRead, canWrite) {
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name);
var mode = FS.getMode(canRead, canWrite);
return VFS.create(path, mode);
},
- createDataFile: function (parent, name, data, canRead, canWrite) {
+ createDataFile: function(parent, name, data, canRead, canWrite) {
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name);
var mode = FS.getMode(canRead, canWrite);
var node = VFS.create(path, mode);
@@ -637,7 +637,7 @@ LibraryManager.library = {
}
return node;
},
- createDevice: function (parent, name, input, output) {
+ createDevice: function(parent, name, input, output) {
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name);
var mode = input && output ? 0777 : (input ? 0333 : 0555);
if (!FS.createDevice.major) FS.createDevice.major = 64;
@@ -645,16 +645,16 @@ LibraryManager.library = {
// Create a fake device that a set of stream ops to emulate
// the old behavior.
FS.registerDevice(dev, {
- open: function (stream) {
+ open: function(stream) {
stream.seekable = false;
},
- close: function (stream) {
+ close: function(stream) {
// flush any pending line data
- if (output.buffer && output.buffer.length) {
+ if (output && output.buffer && output.buffer.length) {
output({{{ charCode('\n') }}});
}
},
- read: function (stream, buffer, offset, length, pos /* ignored */) {
+ read: function(stream, buffer, offset, length, pos /* ignored */) {
var bytesRead = 0;
for (var i = 0; i < length; i++) {
var result;
@@ -675,7 +675,7 @@ LibraryManager.library = {
}
return bytesRead;
},
- write: function (stream, buffer, offset, length, pos) {
+ write: function(stream, buffer, offset, length, pos) {
for (var i = 0; i < length; i++) {
try {
output(buffer[offset+i]);
@@ -691,7 +691,7 @@ LibraryManager.library = {
});
return VFS.mkdev(path, mode, dev);
},
- createLink: function (parent, name, target, canRead, canWrite) {
+ createLink: function(parent, name, target, canRead, canWrite) {
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name);
return VFS.symlink(target, path);
},
@@ -833,9 +833,9 @@ LibraryManager.library = {
// override each stream op with one that tries to force load the lazy file first
var stream_ops = {};
var keys = Object.keys(node.stream_ops);
- keys.forEach(function (key) {
+ keys.forEach(function(key) {
var fn = node.stream_ops[key];
- stream_ops[key] = function () {
+ stream_ops[key] = function() {
if (!FS.forceLoadFile(node)) {
throw new FS.ErrnoError(ERRNO_CODES.EIO);
}
@@ -843,7 +843,7 @@ LibraryManager.library = {
};
});
// use a custom read function
- stream_ops.read = function (stream, buffer, offset, length, position) {
+ stream_ops.read = function(stream, buffer, offset, length, position) {
var contents = stream.node.contents;
var size = Math.min(contents.length - position, length);
if (contents.slice) { // normal array
@@ -909,7 +909,7 @@ LibraryManager.library = {
$VFS__deps: ['$FS'],
$VFS: {
- mount: function (type, opts, mountpoint) {
+ mount: function(type, opts, mountpoint) {
var mount = {
type: type,
opts: opts,
@@ -935,11 +935,11 @@ LibraryManager.library = {
}
return root;
},
- lookup: function (parent, name) {
+ lookup: function(parent, name) {
return parent.node_ops.lookup(parent, name);
},
// generic function for all node creation
- mknod: function (path, mode, dev) {
+ mknod: function(path, mode, dev) {
var lookup = FS.lookupPath(path, { parent: true });
var parent = lookup.node;
var name = PATH.basename(path);
@@ -953,21 +953,21 @@ LibraryManager.library = {
return parent.node_ops.mknod(parent, name, mode, dev);
},
// helpers to create specific types of nodes
- create: function (path, mode) {
+ create: function(path, mode) {
mode &= {{{ cDefine('S_IALLUGO') }}};
mode |= {{{ cDefine('S_IFREG') }}};
return VFS.mknod(path, mode, 0);
},
- mkdir: function (path, mode) {
+ mkdir: function(path, mode) {
mode &= {{{ cDefine('S_IRWXUGO') }}} | {{{ cDefine('S_ISVTX') }}};
mode |= {{{ cDefine('S_IFDIR') }}};
return VFS.mknod(path, mode, 0);
},
- mkdev: function (path, mode, dev) {
+ mkdev: function(path, mode, dev) {
mode |= {{{ cDefine('S_IFCHR') }}};
return VFS.mknod(path, mode, dev);
},
- symlink: function (oldpath, newpath) {
+ symlink: function(oldpath, newpath) {
var lookup = FS.lookupPath(newpath, { parent: true });
var parent = lookup.node;
var newname = PATH.basename(newpath);
@@ -980,7 +980,7 @@ LibraryManager.library = {
}
return parent.node_ops.symlink(parent, newname, oldpath);
},
- rename: function (old_path, new_path) {
+ rename: function(old_path, new_path) {
var old_dirname = PATH.dirname(old_path);
var new_dirname = PATH.dirname(new_path);
var old_name = PATH.basename(old_path);
@@ -1062,7 +1062,7 @@ LibraryManager.library = {
FS.hashAddNode(old_node);
}
},
- rmdir: function (path) {
+ rmdir: function(path) {
var lookup = FS.lookupPath(path, { parent: true });
var parent = lookup.node;
var name = PATH.basename(path);
@@ -1080,7 +1080,7 @@ LibraryManager.library = {
parent.node_ops.rmdir(parent, name);
FS.destroyNode(node);
},
- unlink: function (path) {
+ unlink: function(path) {
var lookup = FS.lookupPath(path, { parent: true });
var parent = lookup.node;
var name = PATH.basename(path);
@@ -1100,7 +1100,7 @@ LibraryManager.library = {
parent.node_ops.unlink(parent, name);
FS.destroyNode(node);
},
- readlink: function (path) {
+ readlink: function(path) {
var lookup = FS.lookupPath(path, { follow: false });
var link = lookup.node;
if (!link.node_ops.readlink) {
@@ -1108,7 +1108,7 @@ LibraryManager.library = {
}
return link.node_ops.readlink(link);
},
- stat: function (path, dontFollow) {
+ stat: function(path, dontFollow) {
var lookup = FS.lookupPath(path, { follow: !dontFollow });
var node = lookup.node;
if (!node.node_ops.getattr) {
@@ -1116,10 +1116,10 @@ LibraryManager.library = {
}
return node.node_ops.getattr(node);
},
- lstat: function (path) {
+ lstat: function(path) {
return VFS.stat(path, true);
},
- chmod: function (path, mode, dontFollow) {
+ chmod: function(path, mode, dontFollow) {
var node;
if (typeof path === 'string') {
var lookup = FS.lookupPath(path, { follow: !dontFollow });
@@ -1135,17 +1135,17 @@ LibraryManager.library = {
timestamp: Date.now()
});
},
- lchmod: function (path, mode) {
+ lchmod: function(path, mode) {
VFS.chmod(path, mode, true);
},
- fchmod: function (fd, mode) {
+ fchmod: function(fd, mode) {
var stream = FS.getStream(fd);
if (!stream) {
throw new FS.ErrnoError(ERRNO_CODES.EBADF);
}
VFS.chmod(stream.node, mode);
},
- chown: function (path, uid, gid, dontFollow) {
+ chown: function(path, uid, gid, dontFollow) {
var node;
if (typeof path === 'string') {
var lookup = FS.lookupPath(path, { follow: !dontFollow });
@@ -1161,17 +1161,17 @@ LibraryManager.library = {
// we ignore the uid / gid for now
});
},
- lchown: function (path, uid, gid) {
+ lchown: function(path, uid, gid) {
VFS.chown(path, uid, gid, true);
},
- fchown: function (fd, uid, gid) {
+ fchown: function(fd, uid, gid) {
var stream = FS.getStream(fd);
if (!stream) {
throw new FS.ErrnoError(ERRNO_CODES.EBADF);
}
VFS.chown(stream.node, uid, gid);
},
- truncate: function (path, len) {
+ truncate: function(path, len) {
if (len < 0) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
}
@@ -1200,7 +1200,7 @@ LibraryManager.library = {
timestamp: Date.now()
});
},
- ftruncate: function (fd, len) {
+ ftruncate: function(fd, len) {
var stream = FS.getStream(fd);
if (!stream) {
throw new FS.ErrnoError(ERRNO_CODES.EBADF);
@@ -1210,14 +1210,14 @@ LibraryManager.library = {
}
VFS.truncate(stream.node, len);
},
- utime: function (path, atime, mtime) {
+ utime: function(path, atime, mtime) {
var lookup = FS.lookupPath(path, { follow: true });
var node = lookup.node;
node.node_ops.setattr(node, {
timestamp: Math.max(atime, mtime)
});
},
- open: function (path, flags, mode, fd_start, fd_end) {
+ open: function(path, flags, mode, fd_start, fd_end) {
path = PATH.normalize(path);
flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
if ((flags & {{{ cDefine('O_CREAT') }}})) {
@@ -1281,7 +1281,7 @@ LibraryManager.library = {
}
return stream;
},
- close: function (stream) {
+ close: function(stream) {
try {
if (stream.stream_ops.close) {
stream.stream_ops.close(stream);
@@ -1292,19 +1292,19 @@ LibraryManager.library = {
FS.closeStream(stream.fd);
}
},
- llseek: function (stream, offset, whence) {
+ llseek: function(stream, offset, whence) {
if (!stream.seekable || !stream.stream_ops.llseek) {
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
}
return stream.stream_ops.llseek(stream, offset, whence);
},
- readdir: function (stream) {
+ readdir: function(stream) {
if (!stream.stream_ops.readdir) {
throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
}
return stream.stream_ops.readdir(stream);
},
- read: function (stream, buffer, offset, length, position) {
+ read: function(stream, buffer, offset, length, position) {
if (length < 0 || position < 0) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
}
@@ -1328,7 +1328,7 @@ LibraryManager.library = {
if (!seeking) stream.position += bytesRead;
return bytesRead;
},
- write: function (stream, buffer, offset, length, position) {
+ write: function(stream, buffer, offset, length, position) {
if (length < 0 || position < 0) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
}
@@ -1356,7 +1356,7 @@ LibraryManager.library = {
if (!seeking) stream.position += bytesWritten;
return bytesWritten;
},
- allocate: function (stream, offset, length) {
+ allocate: function(stream, offset, length) {
if (offset < 0 || length <= 0) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
}
@@ -1371,7 +1371,7 @@ LibraryManager.library = {
}
stream.stream_ops.allocate(stream, offset, length);
},
- mmap: function (stream, buffer, offset, length, position, prot, flags) {
+ mmap: function(stream, buffer, offset, length, position, prot, flags) {
// TODO if PROT is PROT_WRITE, make sure we have write acccess
if ((stream.flags & {{{ cDefine('O_ACCMODE') }}}) === {{{ cDefine('O_WRONLY')}}}) {
throw new FS.ErrnoError(ERRNO_CODES.EACCES);
@@ -1385,10 +1385,10 @@ LibraryManager.library = {
$MEMFS__deps: ['$FS'],
$MEMFS: {
- mount: function (mount) {
+ mount: function(mount) {
return MEMFS.create_node(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
},
- create_node: function (parent, name, mode, dev) {
+ create_node: function(parent, name, mode, dev) {
if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
// no supported
throw new FS.ErrnoError(ERRNO_CODES.EPERM);
@@ -1414,7 +1414,7 @@ LibraryManager.library = {
return node;
},
node_ops: {
- getattr: function (node) {
+ getattr: function(node) {
var attr = {};
// device numbers reuse inode numbers.
attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
@@ -1442,7 +1442,7 @@ LibraryManager.library = {
attr.blocks = Math.ceil(attr.size / attr.blksize);
return attr;
},
- setattr: function (node, attr) {
+ setattr: function(node, attr) {
if (attr.mode !== undefined) {
node.mode = attr.mode;
}
@@ -1455,13 +1455,13 @@ LibraryManager.library = {
else while (attr.size > contents.length) contents.push(0);
}
},
- lookup: function (parent, name) {
+ lookup: function(parent, name) {
throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
},
- mknod: function (parent, name, mode, dev) {
+ mknod: function(parent, name, mode, dev) {
return MEMFS.create_node(parent, name, mode, dev);
},
- rename: function (old_node, new_dir, new_name) {
+ rename: function(old_node, new_dir, new_name) {
// if we're overwriting a directory at new_name, make sure it's empty.
if (FS.isDir(old_node.mode)) {
var new_node;
@@ -1480,22 +1480,22 @@ LibraryManager.library = {
old_node.name = new_name;
new_dir.contents[new_name] = old_node;
},
- unlink: function (parent, name) {
+ unlink: function(parent, name) {
delete parent.contents[name];
},
- rmdir: function (parent, name) {
+ rmdir: function(parent, name) {
var node = FS.lookupNode(parent, name);
for (var i in node.contents) {
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
}
delete parent.contents[name];
},
- symlink: function (parent, newname, oldpath) {
+ symlink: function(parent, newname, oldpath) {
var node = MEMFS.create_node(parent, newname, 0777 | {{{ cDefine('S_IFLNK') }}}, 0);
node.link = oldpath;
return node;
},
- readlink: function (node) {
+ readlink: function(node) {
if (!FS.isLink(node.mode)) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
}
@@ -1503,7 +1503,7 @@ LibraryManager.library = {
},
},
stream_ops: {
- open: function (stream) {
+ open: function(stream) {
if (FS.isDir(stream.node.mode)) {
// cache off the directory entries when open'd
var entries = ['.', '..']
@@ -1516,7 +1516,7 @@ LibraryManager.library = {
stream.entries = entries;
}
},
- read: function (stream, buffer, offset, length, position) {
+ read: function(stream, buffer, offset, length, position) {
var contents = stream.node.contents;
var size = Math.min(contents.length - position, length);
#if USE_TYPED_ARRAYS == 2
@@ -1531,7 +1531,7 @@ LibraryManager.library = {
}
return size;
},
- write: function (stream, buffer, offset, length, position) {
+ write: function(stream, buffer, offset, length, position) {
var contents = stream.node.contents;
while (contents.length < position) contents.push(0);
for (var i = 0; i < length; i++) {
@@ -1540,7 +1540,7 @@ LibraryManager.library = {
stream.node.timestamp = Date.now();
return length;
},
- llseek: function (stream, offset, whence) {
+ llseek: function(stream, offset, whence) {
var position = offset;
if (whence === 1) { // SEEK_CUR.
position += stream.position;
@@ -1556,15 +1556,15 @@ LibraryManager.library = {
stream.position = position;
return position;
},
- readdir: function (stream) {
+ readdir: function(stream) {
return stream.entries;
},
- allocate: function (stream, offset, length) {
+ allocate: function(stream, offset, length) {
var contents = stream.node.contents;
var limit = offset + length;
while (limit > contents.length) contents.push(0);
},
- mmap: function (stream, buffer, offset, length, position, prot, flags) {
+ mmap: function(stream, buffer, offset, length, position, prot, flags) {
if (!FS.isFile(stream.node.mode)) {
throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
}
@@ -1602,7 +1602,7 @@ LibraryManager.library = {
$SOCKFS__postset: '__ATINIT__.push({ func: function() { SOCKFS.root = VFS.mount(SOCKFS, {}, null); } });',
$SOCKFS__deps: ['$FS'],
$SOCKFS: {
- mount: function (mount) {
+ mount: function(mount) {
var node = FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
node.node_ops = SOCKFS.node_ops;
node.stream_ops = SOCKFS.stream_ops;
@@ -1619,12 +1619,12 @@ LibraryManager.library = {
$TTY__deps: ['$FS'],
$TTY: {
ttys: [],
- register: function (dev, ops) {
+ register: function(dev, ops) {
TTY.ttys[dev] = { input: [], output: [], ops: ops };
FS.registerDevice(dev, TTY.stream_ops);
},
stream_ops: {
- open: function (stream) {
+ open: function(stream) {
// this wouldn't be required if the library wasn't eval'd at first...
if (!TTY.utf8) {
TTY.utf8 = new Runtime.UTF8Processor();
@@ -1636,13 +1636,13 @@ LibraryManager.library = {
stream.tty = tty;
stream.seekable = false;
},
- close: function (stream) {
+ close: function(stream) {
// flush any pending line data
if (stream.tty.output.length) {
stream.tty.ops.put_char(stream.tty, {{{ charCode('\n') }}});
}
},
- read: function (stream, buffer, offset, length, pos /* ignored */) {
+ read: function(stream, buffer, offset, length, pos /* ignored */) {
if (!stream.tty || !stream.tty.ops.get_char) {
throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
}
@@ -1666,7 +1666,7 @@ LibraryManager.library = {
}
return bytesRead;
},
- write: function (stream, buffer, offset, length, pos) {
+ write: function(stream, buffer, offset, length, pos) {
if (!stream.tty || !stream.tty.ops.put_char) {
throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
}
@@ -1686,7 +1686,7 @@ LibraryManager.library = {
// NOTE: This is weird to support stdout and stderr
// overrides in addition to print and printErr orverrides.
default_tty_ops: {
- get_char: function (tty) {
+ get_char: function(tty) {
if (!tty.input.length) {
var result = null;
if (ENVIRONMENT_IS_NODE) {
@@ -1715,7 +1715,7 @@ LibraryManager.library = {
}
return tty.input.shift();
},
- put_char: function (tty, val) {
+ put_char: function(tty, val) {
if (val === null || val === {{{ charCode('\n') }}}) {
Module['print'](tty.output.join(''));
tty.output = [];
@@ -1725,7 +1725,7 @@ LibraryManager.library = {
}
},
default_tty1_ops: {
- put_char: function (tty, val) {
+ put_char: function(tty, val) {
if (val === null || val === {{{ charCode('\n') }}}) {
Module['printErr'](tty.output.join(''));
tty.output = [];
@@ -1820,7 +1820,7 @@ LibraryManager.library = {
}
if (stream.position < 0 || stream.position >= entries.length) {
{{{ makeSetValue('result', '0', '0', 'i8*') }}}
- return;
+ return 0;
}
var id;
var type;
@@ -2102,7 +2102,7 @@ LibraryManager.library = {
}
},
lchmod__deps: ['chmod'],
- lchmod: function (path, mode) {
+ lchmod: function(path, mode) {
path = Pointer_stringify(path);
try {
VFS.lchmod(path, mode);
@@ -2701,6 +2701,11 @@ LibraryManager.library = {
}
try {
var slab = {{{ makeGetSlabs('buf', 'i8', true) }}};
+#if SAFE_HEAP
+#if USE_TYPED_ARRAYS == 0
+ SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually
+#endif
+#endif
return VFS.read(stream, slab, buf, nbyte, offset);
} catch (e) {
FS.handleFSError(e);
@@ -2723,6 +2728,11 @@ LibraryManager.library = {
try {
var slab = {{{ makeGetSlabs('buf', 'i8', true) }}};
+#if SAFE_HEAP
+#if USE_TYPED_ARRAYS == 0
+ SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually
+#endif
+#endif
return VFS.read(stream, slab, buf, nbyte);
} catch (e) {
FS.handleFSError(e);
@@ -2824,6 +2834,11 @@ LibraryManager.library = {
}
try {
var slab = {{{ makeGetSlabs('buf', 'i8', true) }}};
+#if SAFE_HEAP
+#if USE_TYPED_ARRAYS == 0
+ SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually
+#endif
+#endif
return VFS.write(stream, slab, buf, nbyte, offset);
} catch (e) {
FS.handleFSError(e);
@@ -2841,11 +2856,16 @@ LibraryManager.library = {
}
if (stream && ('socket' in stream)) {
- return _send(fildes, buf, nbyte, 0);
+ return _send(fildes, buf, nbyte, 0);
}
try {
var slab = {{{ makeGetSlabs('buf', 'i8', true) }}};
+#if SAFE_HEAP
+#if USE_TYPED_ARRAYS == 0
+ SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually
+#endif
+#endif
return VFS.write(stream, slab, buf, nbyte);
} catch (e) {
FS.handleFSError(e);
@@ -2977,7 +2997,7 @@ LibraryManager.library = {
},
// TODO: Implement initgroups (grp.h).
setgroups__deps: ['__setErrNo', '$ERRNO_CODES', 'sysconf'],
- setgroups: function (ngroups, gidset) {
+ setgroups: function(ngroups, gidset) {
// int setgroups(int ngroups, const gid_t *gidset);
// https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/setgroups.2.html
if (ngroups < 1 || ngroups > _sysconf({{{ cDefine('_SC_NGROUPS_MAX') }}})) {
@@ -5139,7 +5159,7 @@ LibraryManager.library = {
// FIXME: memcpy, memmove and memset should all return their destination pointers.
- memcpy__inline: function (dest, src, num, align) {
+ memcpy__inline: function(dest, src, num, align) {
var ret = '';
#if ASSERTIONS
#if ASM_JS == 0
@@ -5152,7 +5172,7 @@ LibraryManager.library = {
memcpy__asm: true,
memcpy__sig: 'iiii',
- memcpy: function (dest, src, num) {
+ memcpy: function(dest, src, num) {
dest = dest|0; src = src|0; num = num|0;
var ret = 0;
ret = dest|0;
@@ -5704,17 +5724,7 @@ LibraryManager.library = {
(chr >= {{{ charCode('{') }}} && chr <= {{{ charCode('~') }}});
},
isspace: function(chr) {
- switch(chr) {
- case 32:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- return true;
- default:
- return false;
- };
+ return (chr == 32) || (chr >= 9 && chr <= 13);
},
isblank: function(chr) {
return chr == {{{ charCode(' ') }}} || chr == {{{ charCode('\t') }}};
@@ -6366,7 +6376,7 @@ LibraryManager.library = {
// http://www.digitalmars.com/archives/cplusplus/3634.html
// and mruby source code at
// https://github.com/mruby/mruby/blob/master/src/math.c
- erfc: function (x) {
+ erfc: function(x) {
var MATH_TOLERANCE = 1E-12;
var ONE_SQRTPI = 0.564189583547756287;
var a = 1;
@@ -6398,7 +6408,7 @@ LibraryManager.library = {
},
erfcf: 'erfcf',
erf__deps: ['erfc'],
- erf: function (x) {
+ erf: function(x) {
var MATH_TOLERANCE = 1E-12;
var TWO_SQRTPI = 1.128379167095512574;
var sum = x;
@@ -8942,7 +8952,7 @@ LibraryManager.library = {
* Module['webrtc']['ondisconnect']: function(peer), invoked when an existing connection is closed
* Module['webrtc']['onerror']: function(error), invoked when an error occurs
*/
- socket__deps: ['$Sockets'],
+ socket__deps: ['$FS', '$Sockets'],
socket: function(family, type, protocol) {
var INCOMING_QUEUE_LENGTH = 64;
var stream = FS.createStream({
@@ -9087,7 +9097,7 @@ LibraryManager.library = {
// Stub: connection-oriented sockets are not supported yet.
},
- bind__deps: ['$Sockets', '_inet_ntoa_raw', 'ntohs', 'mkport'],
+ bind__deps: ['$FS', '$Sockets', '_inet_ntoa_raw', 'ntohs', 'mkport'],
bind: function(fd, addr, addrlen) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9108,7 +9118,7 @@ LibraryManager.library = {
info.bound = true;
},
- sendmsg__deps: ['$Sockets', 'bind', '_inet_ntoa_raw', 'ntohs'],
+ sendmsg__deps: ['$FS', '$Sockets', 'bind', '_inet_ntoa_raw', 'ntohs'],
sendmsg: function(fd, msg, flags) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9164,7 +9174,7 @@ LibraryManager.library = {
connection.send('unreliable', buffer.buffer);
},
- recvmsg__deps: ['$Sockets', 'bind', '__setErrNo', '$ERRNO_CODES', 'htons'],
+ recvmsg__deps: ['$FS', '$Sockets', 'bind', '__setErrNo', '$ERRNO_CODES', 'htons'],
recvmsg: function(fd, msg, flags) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9216,6 +9226,7 @@ LibraryManager.library = {
return ret;
},
+ shutdown__deps: ['$FS'],
shutdown: function(fd, how) {
var stream = FS.getStream(fd);
if (!stream) return -1;
@@ -9223,6 +9234,7 @@ LibraryManager.library = {
FS.closeStream(stream);
},
+ ioctl__deps: ['$FS'],
ioctl: function(fd, request, varargs) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9240,6 +9252,7 @@ LibraryManager.library = {
return 0;
},
+ accept__deps: ['$FS'],
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,
@@ -9254,6 +9267,7 @@ LibraryManager.library = {
return fd;
},
+ select__deps: ['$FS'],
select: function(nfds, readfds, writefds, exceptfds, timeout) {
// readfds are supported,
// writefds checks socket open status
@@ -9308,7 +9322,7 @@ LibraryManager.library = {
}
},
#else
- socket__deps: ['$Sockets'],
+ socket__deps: ['$FS', '$Sockets'],
socket: function(family, type, protocol) {
var stream = type == {{{ cDefine('SOCK_STREAM') }}};
if (protocol) {
@@ -9581,6 +9595,7 @@ LibraryManager.library = {
return _recv(fd, buf, len, flags);
},
+ shutdown__deps: ['$FS'],
shutdown: function(fd, how) {
var stream = FS.getStream(fd);
if (!stream) return -1;
@@ -9588,6 +9603,7 @@ LibraryManager.library = {
FS.closeStream(stream);
},
+ ioctl__deps: ['$FS'],
ioctl: function(fd, request, varargs) {
var info = FS.getStream(fd);
if (!info) return -1;
diff --git a/src/library_egl.js b/src/library_egl.js
index 0ccb13e6..0e96e92f 100644
--- a/src/library_egl.js
+++ b/src/library_egl.js
@@ -260,8 +260,13 @@ var LibraryEGL = {
}
EGL.windowID = _glutCreateWindow();
- EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
- return 62004; // Magic ID for Emscripten EGLContext
+ if (EGL.windowID != 0) {
+ EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
+ return 62004; // Magic ID for Emscripten EGLContext
+ } else {
+ EGL.setErrorCode(0x3009 /* EGL_BAD_MATCH */); // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.
+ return 0; /* EGL_NO_CONTEXT */
+ }
},
eglDestroyContext__deps: ['glutDestroyWindow', '$GL'],
diff --git a/src/library_glut.js b/src/library_glut.js
index 36d47787..29957e6f 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -385,7 +385,7 @@ var LibraryGLUT = {
glutCreateWindow__deps: ['$Browser'],
glutCreateWindow: function(name) {
Module.ctx = Browser.createContext(Module['canvas'], true, true);
- return 1;
+ return Module.ctx ? 1 /* a new GLUT window ID for the created context */ : 0 /* failure */;
},
glutDestroyWindow__deps: ['$Browser'],
diff --git a/src/library_openal.js b/src/library_openal.js
index d2516559..c55415b8 100644
--- a/src/library_openal.js
+++ b/src/library_openal.js
@@ -85,7 +85,7 @@ var LibraryOpenAL = {
err: 0,
src: [],
buf: [],
- interval: setInterval(function () { _updateSources(context); }, AL.QUEUE_INTERVAL)
+ interval: setInterval(function() { _updateSources(context); }, AL.QUEUE_INTERVAL)
};
AL.contexts.push(context);
return AL.contexts.length;
@@ -95,14 +95,14 @@ var LibraryOpenAL = {
},
updateSources__deps: ['updateSource'],
- updateSources: function (context) {
+ updateSources: function(context) {
for (var i = 0; i < context.src.length; i++) {
_updateSource(context.src[i]);
}
},
updateSource__deps: ['setSourceState'],
- updateSource: function (src) {
+ updateSource: function(src) {
#if OPENAL_DEBUG
var idx = AL.currentContext.src.indexOf(src);
#endif
@@ -154,7 +154,7 @@ var LibraryOpenAL = {
},
setSourceState__deps: ['updateSource', 'stopSourceQueue'],
- setSourceState: function (src, state) {
+ setSourceState: function(src, state) {
#if OPENAL_DEBUG
var idx = AL.currentContext.src.indexOf(src);
#endif
@@ -208,7 +208,7 @@ var LibraryOpenAL = {
}
},
- stopSourceQueue: function (src) {
+ stopSourceQueue: function(src) {
for (var i = 0; i < src.queue.length; i++) {
var entry = src.queue[i];
if (entry.src) {
@@ -906,7 +906,7 @@ var LibraryOpenAL = {
return 0;
},
- alGetString: function (param) {
+ alGetString: function(param) {
return allocate(intArrayFromString('NA'), 'i8', ALLOC_NORMAL);
},
@@ -914,7 +914,7 @@ var LibraryOpenAL = {
return 0;
},
- alcGetString: function (param) {
+ alcGetString: function(param) {
return allocate(intArrayFromString('NA'), 'i8', ALLOC_NORMAL);
},
diff --git a/src/library_path.js b/src/library_path.js
index feec1e68..2c2c016a 100644
--- a/src/library_path.js
+++ b/src/library_path.js
@@ -3,11 +3,11 @@ mergeInto(LibraryManager.library, {
$PATH: {
// split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
- splitPath: function (filename) {
+ splitPath: function(filename) {
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
return splitPathRe.exec(filename).slice(1);
},
- normalizeArray: function (parts, allowAboveRoot) {
+ normalizeArray: function(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
@@ -30,7 +30,7 @@ mergeInto(LibraryManager.library, {
}
return parts;
},
- normalize: function (path) {
+ normalize: function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.substr(-1) === '/';
// Normalize the path
@@ -45,7 +45,7 @@ mergeInto(LibraryManager.library, {
}
return (isAbsolute ? '/' : '') + path;
},
- dirname: function (path) {
+ dirname: function(path) {
var result = PATH.splitPath(path),
root = result[0],
dir = result[1];
@@ -59,7 +59,7 @@ mergeInto(LibraryManager.library, {
}
return root + dir;
},
- basename: function (path, ext) {
+ basename: function(path, ext) {
// EMSCRIPTEN return '/'' for '/', not an empty string
if (path === '/') return '/';
var f = PATH.splitPath(path)[2];
@@ -68,7 +68,7 @@ mergeInto(LibraryManager.library, {
}
return f;
},
- join: function () {
+ join: function() {
var paths = Array.prototype.slice.call(arguments, 0);
return PATH.normalize(paths.filter(function(p, index) {
if (typeof p !== 'string') {
@@ -77,7 +77,7 @@ mergeInto(LibraryManager.library, {
return p;
}).join('/'));
},
- resolve: function () {
+ resolve: function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 80c7ac07..19152646 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -318,7 +318,7 @@ var LibrarySDL = {
usePageCanvas: usePageCanvas,
source: source,
- isFlagSet: function (flag) {
+ isFlagSet: function(flag) {
return flags & flag;
}
};
@@ -2112,7 +2112,7 @@ var LibrarySDL = {
return -1;
},
- SDL_SetGammaRamp: function (redTable, greenTable, blueTable) {
+ SDL_SetGammaRamp: function(redTable, greenTable, blueTable) {
return -1;
},
diff --git a/src/preamble.js b/src/preamble.js
index 2955c885..585db832 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -156,6 +156,15 @@ function SAFE_HEAP_COPY_HISTORY(dest, src) {
SAFE_HEAP_ACCESS(dest, HEAP_HISTORY[dest] || null, true, false);
}
+function SAFE_HEAP_FILL_HISTORY(from, to, type) {
+#if SAFE_HEAP_LOG
+ Module.print('SAFE_HEAP fill: ' + [from, to, type]);
+#endif
+ for (var i = from; i < to; i++) {
+ HEAP_HISTORY[i] = type;
+ }
+}
+
//==========================================
#endif
diff --git a/src/settings.js b/src/settings.js
index 19108f3b..f620edf7 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -444,7 +444,7 @@ var C_DEFINES = {
'ABMON_9': '41',
'ACCESSPERMS': '0000400',
'AF_INET': '2',
- 'AF_INET6': '6',
+ 'AF_INET6': '10',
'ALLPERMS': '0004000',
'ALT_DIGITS': '49',
'AM_STR': '5',
@@ -620,8 +620,8 @@ var C_DEFINES = {
'HAVE__ULTOA': '1',
'HUGE_VAL': 'inf',
'INT_MAX': '2147483647',
- 'IPPROTO_TCP': '1',
- 'IPPROTO_UDP': '2',
+ 'IPPROTO_TCP': '6',
+ 'IPPROTO_UDP': '17',
'ITIMER_PROF': '2',
'ITIMER_REAL': '0',
'ITIMER_VIRTUAL': '1',
@@ -676,7 +676,7 @@ var C_DEFINES = {
'NOSTR': '55',
'NO_ARG': '0',
'no_argument': '0',
- 'NSIG': '32',
+ 'NSIG': '64',
'NULL': '0',
'OPTIONAL_ARG': '2',
'optional_argument': '2',
@@ -830,8 +830,8 @@ var C_DEFINES = {
'SIGPROF': '27',
'SIGPWR': '19',
'SIGQUIT': '3',
- 'SIGRTMAX': '31',
- 'SIGRTMIN': '27',
+ 'SIGRTMAX': '64',
+ 'SIGRTMIN': '32',
'SIGSEGV': '11',
'SIGSTOP': '17',
'SIGSYS': '12',
@@ -857,8 +857,8 @@ var C_DEFINES = {
'SI_QUEUE': '2',
'SI_TIMER': '3',
'SI_USER': '1',
- 'SOCK_DGRAM': '20',
- 'SOCK_STREAM': '200',
+ 'SOCK_DGRAM': '2',
+ 'SOCK_STREAM': '1',
'STDC_HEADERS': '1',
'STDERR_FILENO': '2',
'STDIN_FILENO': '0',
diff --git a/src/shell.js b/src/shell.js
index 2082eeae..bac4eaa3 100644
--- a/src/shell.js
+++ b/src/shell.js
@@ -70,8 +70,7 @@ if (ENVIRONMENT_IS_NODE) {
module.exports = Module;
}
-
-if (ENVIRONMENT_IS_SHELL) {
+else if (ENVIRONMENT_IS_SHELL) {
Module['print'] = print;
if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
@@ -88,20 +87,7 @@ if (ENVIRONMENT_IS_SHELL) {
this['{{{ EXPORT_NAME }}}'] = Module;
}
-
-if (ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER) {
- Module['print'] = function(x) {
- console.log(x);
- };
-
- Module['printErr'] = function(x) {
- console.log(x);
- };
-
- this['{{{ EXPORT_NAME }}}'] = Module;
-}
-
-if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
Module['read'] = function(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
@@ -112,21 +98,30 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
if (typeof arguments != 'undefined') {
Module['arguments'] = arguments;
}
-}
-if (ENVIRONMENT_IS_WORKER) {
- // We can do very little here...
- var TRY_USE_DUMP = false;
- Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
- dump(x);
- }) : (function(x) {
- // self.postMessage(x); // enable this if you want stdout to be sent as messages
- }));
-
- Module['load'] = importScripts;
+ if (ENVIRONMENT_IS_WEB) {
+ Module['print'] = function(x) {
+ console.log(x);
+ };
+
+ Module['printErr'] = function(x) {
+ console.log(x);
+ };
+
+ this['{{{ EXPORT_NAME }}}'] = Module;
+ } else if (ENVIRONMENT_IS_WORKER) {
+ // We can do very little here...
+ var TRY_USE_DUMP = false;
+ Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+ dump(x);
+ }) : (function(x) {
+ // self.postMessage(x); // enable this if you want stdout to be sent as messages
+ }));
+
+ Module['load'] = importScripts;
+ }
}
-
-if (!ENVIRONMENT_IS_WORKER && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_SHELL) {
+else {
// Unreachable because SHELL is dependant on the others
throw 'Unknown runtime environment. Where are we?';
}
diff --git a/system/include/libc/sys/signal.h b/system/include/libc/sys/signal.h
index 49a94d80..fc9b67d5 100644
--- a/system/include/libc/sys/signal.h
+++ b/system/include/libc/sys/signal.h
@@ -298,7 +298,9 @@ int _EXFUN(sigqueue, (pid_t pid, int signo, const union sigval value));
#define SIGLOST 29 /* resource lost (eg, record-lock lost) */
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
-#define NSIG 32 /* signal 0 implied */
+#define NSIG 64 /* signal 0 implied */
+#define SIGRTMIN 32
+#define SIGRTMAX NSIG
#endif
#endif
diff --git a/system/include/net/if.h b/system/include/net/if.h
index dd7884aa..0ef18520 100644
--- a/system/include/net/if.h
+++ b/system/include/net/if.h
@@ -77,7 +77,26 @@ char *if_indextoname(unsigned int a, char *b);
struct if_nameindex *if_nameindex();
void if_freenameindex(struct if_nameindex *a);
-
+#define IFF_UP 0x1
+#define IFF_BROADCAST 0x2
+#define IFF_DEBUG 0x4
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_NOTRAILERS 0x20
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+#define IFF_PROMISC 0x100
+#define IFF_ALLMULTI 0x200
+#define IFF_MASTER 0x400
+#define IFF_SLAVE 0x800
+#define IFF_MULTICAST 0x1000
+#define IFF_PORTSEL 0x2000
+#define IFF_AUTOMEDIA 0x4000
+#define IFF_DYNAMIC 0x8000
+#define IFF_LOWER_UP 0x10000
+#define IFF_DORMANT 0x20000
+#define IFF_ECHO 0x40000
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
#ifdef __cplusplus
}
diff --git a/system/include/net/netinet/in.h b/system/include/net/netinet/in.h
index fba1a7b3..1d3952f5 100644
--- a/system/include/net/netinet/in.h
+++ b/system/include/net/netinet/in.h
@@ -11,11 +11,63 @@ extern "C" {
enum {
IPPROTO_IP = 0,
-#define IPPROTO_IP IPPROTO_IP
- IPPROTO_TCP = 1,
-#define IPPROTO_TCP IPPROTO_TCP
- IPPROTO_UDP = 2,
-#define IPPROTO_UDP IPPROTO_UDP
+#define IPPROTO_IP IPPROTO_IP
+ IPPROTO_HOPOPTS = 0,
+#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
+ IPPROTO_ICMP = 1,
+#define IPPROTO_ICMP IPPROTO_ICMP
+ IPPROTO_IGMP = 2,
+#define IPPROTO_IGMP IPPROTO_IGMP
+ IPPROTO_IPIP = 4,
+#define IPPROTO_IPIP IPPROTO_IPIP
+ IPPROTO_TCP = 6,
+#define IPPROTO_TCP IPPROTO_TCP
+ IPPROTO_EGP = 8,
+#define IPPROTO_EGP IPPROTO_EGP
+ IPPROTO_PUP = 12,
+#define IPPROTO_PUP IPPROTO_PUP
+ IPPROTO_UDP = 17,
+#define IPPROTO_UDP IPPROTO_UDP
+ IPPROTO_IDP = 22,
+#define IPPROTO_IDP IPPROTO_IDP
+ IPPROTO_TP = 29,
+#define IPPROTO_TP IPPROTO_TP
+ IPPROTO_DCCP = 33,
+#define IPPROTO_DCCP IPPROTO_DCCP
+ IPPROTO_IPV6 = 41,
+#define IPPROTO_IPV6 IPPROTO_IPV6
+ IPPROTO_ROUTING = 43,
+#define IPPROTO_ROUTING IPPROTO_ROUTING
+ IPPROTO_FRAGMENT = 44,
+#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
+ IPPROTO_RSVP = 46,
+#define IPPROTO_RSVP IPPROTO_RSVP
+ IPPROTO_GRE = 47,
+#define IPPROTO_GRE IPPROTO_GRE
+ IPPROTO_ESP = 50,
+#define IPPROTO_ESP IPPROTO_ESP
+ IPPROTO_AH = 51,
+#define IPPROTO_AH IPPROTO_AH
+ IPPROTO_ICMPV6 = 58,
+#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
+ IPPROTO_NONE = 59,
+#define IPPROTO_NONE IPPROTO_NONE
+ IPPROTO_DSTOPTS = 60,
+#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
+ IPPROTO_MTP = 92,
+#define IPPROTO_MTP IPPROTO_MTP
+ IPPROTO_ENCAP = 98,
+#define IPPROTO_ENCAP IPPROTO_ENCAP
+ IPPROTO_PIM = 103,
+#define IPPROTO_PIM IPPROTO_PIM
+ IPPROTO_COMP = 108,
+#define IPPROTO_COMP IPPROTO_COMP
+ IPPROTO_SCTP = 132,
+#define IPPROTO_SCTP IPPROTO_SCTP
+ IPPROTO_UDPLITE = 136,
+#define IPPROTO_UDPLITE IPPROTO_UDPLITE
+ IPPROTO_RAW = 255,
+#define IPPROTO_RAW IPPROTO_RAW
IPPROTO_MAX
};
@@ -75,6 +127,11 @@ struct ip_mreq {
struct in_addr imr_interface;
};
+#define IP_PMTUDISC_DONT 0
+#define IP_PMTUDISC_WANT 1
+#define IP_PMTUDISC_DO 2
+#define IP_PMTUDISC_PROBE 3
+
#define IP_MULTICAST_IF 32
#define IP_MULTICAST_TTL 33
#define IP_MULTICAST_LOOP 34
diff --git a/system/include/netdb.h b/system/include/netdb.h
index 48acdcc4..df74a117 100644
--- a/system/include/netdb.h
+++ b/system/include/netdb.h
@@ -11,6 +11,20 @@ extern "C" {
#define NO_DATA 4
#define NO_ADDRESS 5
+#define AI_PASSIVE 0x0001
+#define AI_CANONNAME 0x0002
+#define AI_NUMERICHOST 0x0004
+#define AI_V4MAPPED 0x0008
+#define AI_ALL 0x0010
+#define AI_ADDRCONFIG 0x0020
+#ifdef __USE_GNU
+# define AI_IDN 0x0040
+# define AI_CANONIDN 0x0080
+# define AI_IDN_ALLOW_UNASSIGNED 0x0100
+# define AI_IDN_USE_STD3_ASCII_RULES 0x0200
+#endif
+#define AI_NUMERICSERV 0x0400
+
#define EAI_ADDRFAMILY 1
#define EAI_AGAIN 2
#define EAI_BADFLAGS 3
@@ -47,6 +61,15 @@ extern "C" {
#define IP_PASSSEC 18
#define IP_TRANSPARENT 19
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+
typedef int socklen_t;
struct addrinfo
@@ -85,6 +108,19 @@ const char* hstrerror(int err);
extern int h_errno;
+struct servent {
+ char *s_name;
+ char **s_aliases;
+ int s_port;
+ char *s_proto;
+};
+
+struct servent *getservent(void);
+struct servent *getservbyname(const char *name, const char *proto);
+struct servent *getservbyport(int port, const char *proto);
+void setservent(int stayopen);
+void endservent(void);
+
#include <netinet/in.h>
#ifdef __cplusplus
diff --git a/system/include/sys/ioctl.h b/system/include/sys/ioctl.h
index c54d4ccc..047329cb 100644
--- a/system/include/sys/ioctl.h
+++ b/system/include/sys/ioctl.h
@@ -5,9 +5,6 @@
extern "C" {
#endif
-#define SIOCGIFCONF 1 // bogus value
-#define SIOCGIFNETMASK 2 // bogus value
-
#define TIOCGSIZE 80 // bogus
#define TIOCGWINSZ 80 // bogus
@@ -19,6 +16,61 @@ int ioctl(int d, int request, ...);
#define SO_RCVTIMEO 1000
#define SO_SNDTIMEO 2000
+#define SIOCADDRT 0x890B
+#define SIOCDELRT 0x890C
+#define SIOCRTMSG 0x890D
+#define SIOCGIFNAME 0x8910
+#define SIOCSIFLINK 0x8911
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFADDR 0x8915
+#define SIOCSIFADDR 0x8916
+#define SIOCGIFDSTADDR 0x8917
+#define SIOCSIFDSTADDR 0x8918
+#define SIOCGIFBRDADDR 0x8919
+#define SIOCSIFBRDADDR 0x891a
+#define SIOCGIFNETMASK 0x891b
+#define SIOCSIFNETMASK 0x891c
+#define SIOCGIFMETRIC 0x891d
+#define SIOCSIFMETRIC 0x891e
+#define SIOCGIFMEM 0x891f
+#define SIOCSIFMEM 0x8920
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCSIFNAME 0x8923
+#define SIOCSIFHWADDR 0x8924
+#define SIOCGIFENCAP 0x8925
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927
+#define SIOCGIFSLAVE 0x8929
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933
+#define SIOGIFINDEX SIOCGIFINDEX
+#define SIOCSIFPFLAGS 0x8934
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT 0x8938
+#define SIOCGIFBR 0x8940
+#define SIOCSIFBR 0x8941
+#define SIOCGIFTXQLEN 0x8942
+#define SIOCSIFTXQLEN 0x8943
+#define SIOCDARP 0x8953
+#define SIOCGARP 0x8954
+#define SIOCSARP 0x8955
+#define SIOCDRARP 0x8960
+#define SIOCGRARP 0x8961
+#define SIOCSRARP 0x8962
+#define SIOCGIFMAP 0x8970
+#define SIOCSIFMAP 0x8971
+#define SIOCADDDLCI 0x8980
+#define SIOCDELDLCI 0x8981
+#define SIOCDEVPRIVATE 0x89F0
+#define SIOCPROTOPRIVATE 0x89E0
+
#ifdef __cplusplus
}
#endif
diff --git a/system/include/sys/select.h b/system/include/sys/select.h
index a5c73147..d6957fea 100644
--- a/system/include/sys/select.h
+++ b/system/include/sys/select.h
@@ -1,6 +1,8 @@
#ifndef _SELECT_H
#define _SELECT_H
+#include <unistd.h>
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/system/include/sys/socket.h b/system/include/sys/socket.h
index 9650bb9a..abc0aa62 100644
--- a/system/include/sys/socket.h
+++ b/system/include/sys/socket.h
@@ -4,44 +4,196 @@
#include <netdb.h>
#include <sys/select.h>
#include <sys/uio.h>
+#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
-// Note that the values of these constants are mostly arbitrary numbers.
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define SOCK_RAW 3
+#define SOCK_RDM 4
+#define SOCK_SEQPACKET 5
+#define SOCK_DCCP 6
+#define SOCK_PACKET 10
+#define SOCK_CLOEXEC 02000000
+#define SOCK_NONBLOCK 04000
+
+#define PF_UNSPEC 0
+#define PF_LOCAL 1
+#define PF_UNIX PF_LOCAL
+#define PF_FILE PF_LOCAL
+#define PF_INET 2
+#define PF_AX25 3
+#define PF_IPX 4
+#define PF_APPLETALK 5
+#define PF_NETROM 6
+#define PF_BRIDGE 7
+#define PF_ATMPVC 8
+#define PF_X25 9
+#define PF_INET6 10
+#define PF_ROSE 11
+#define PF_DECnet 12
+#define PF_NETBEUI 13
+#define PF_SECURITY 14
+#define PF_KEY 15
+#define PF_NETLINK 16
+#define PF_ROUTE PF_NETLINK
+#define PF_PACKET 17
+#define PF_ASH 18
+#define PF_ECONET 19
+#define PF_ATMSVC 20
+#define PF_RDS 21
+#define PF_SNA 22
+#define PF_IRDA 23
+#define PF_PPPOX 24
+#define PF_WANPIPE 25
+#define PF_LLC 26
+#define PF_CAN 29
+#define PF_TIPC 30
+#define PF_BLUETOOTH 31
+#define PF_IUCV 32
+#define PF_RXRPC 33
+#define PF_ISDN 34
+#define PF_PHONET 35
+#define PF_IEEE802154 36
+#define PF_CAIF 37
+#define PF_ALG 38
+#define PF_NFC 39
+#define PF_MAX 40
+
+#define AF_UNSPEC PF_UNSPEC
+#define AF_LOCAL PF_LOCAL
+#define AF_UNIX PF_UNIX
+#define AF_FILE PF_FILE
+#define AF_INET PF_INET
+#define AF_AX25 PF_AX25
+#define AF_IPX PF_IPX
+#define AF_APPLETALK PF_APPLETALK
+#define AF_NETROM PF_NETROM
+#define AF_BRIDGE PF_BRIDGE
+#define AF_ATMPVC PF_ATMPVC
+#define AF_X25 PF_X25
+#define AF_INET6 PF_INET6
+#define AF_ROSE PF_ROSE
+#define AF_DECnet PF_DECnet
+#define AF_NETBEUI PF_NETBEUI
+#define AF_SECURITY PF_SECURITY
+#define AF_KEY PF_KEY
+#define AF_NETLINK PF_NETLINK
+#define AF_ROUTE PF_ROUTE
+#define AF_PACKET PF_PACKET
+#define AF_ASH PF_ASH
+#define AF_ECONET PF_ECONET
+#define AF_ATMSVC PF_ATMSVC
+#define AF_RDS PF_RDS
+#define AF_SNA PF_SNA
+#define AF_IRDA PF_IRDA
+#define AF_PPPOX PF_PPPOX
+#define AF_WANPIPE PF_WANPIPE
+#define AF_LLC PF_LLC
+#define AF_CAN PF_CAN
+#define AF_TIPC PF_TIPC
+#define AF_BLUETOOTH PF_BLUETOOTH
+#define AF_IUCV PF_IUCV
+#define AF_RXRPC PF_RXRPC
+#define AF_ISDN PF_ISDN
+#define AF_PHONET PF_PHONET
+#define AF_IEEE802154 PF_IEEE802154
+#define AF_CAIF PF_CAIF
+#define AF_ALG PF_ALG
+#define AF_NFC PF_NFC
+#define AF_MAX PF_MAX
+
#define SOMAXCONN 128
-#define PF_LOCAL 1
-#define PF_UNIX PF_LOCAL
-#define PF_INET 2
-#define SO_BROADCAST 6
-#define AF_UNIX PF_UNIX
-
-#define AF_UNSPEC 0
-#define SOCK_STREAM 200
-#define SOL_SOCKET 50
-#define SO_ERROR 10
-#define SOCK_DGRAM 20
-#define SO_REUSEADDR 30
-#define SO_SNDBUF 40
-#define SO_RCVBUF 60
-#define SO_LINGER 70
-#define SO_NOSIGPIPE 80
-#define SO_KEEPALIVE 90
-#define SO_OOBINLINE 100
-#define SO_NO_CHECK 110
-#define SO_PRIORITY 120
-#define SO_LINGER 130
-#define SO_BSDCOMPAT 140
+
+#define SOL_SOCKET 1
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+#ifndef SO_PASSCRED
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+#endif
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+#define SO_BINDTODEVICE 25
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SO_ACCEPTCONN 30
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+#define SO_PROTOCOL 38
+#define SO_DOMAIN 39
+#define SO_RXQ_OVFL 40
+
+#if __BSD_VISIBLE
+#define SO_NOSIGPIPE 0x0800
+#endif
+
+#define MSG_OOB 0x01
+#define MSG_PEEK 0x02
+#define MSG_DONTROUTE 0x04
+#ifdef __USE_GNU
+# define MSG_TRYHARD MSG_DONTROUTE
+#endif
+#define MSG_CTRUNC 0x08
+#define MSG_PROXY 0x10
+#define MSG_TRUNC 0x20
+#define MSG_DONTWAIT 0x40
+#define MSG_EOR 0x80
+#define MSG_WAITALL 0x100
+#define MSG_FIN 0x200
+#define MSG_SYN 0x400
+#define MSG_CONFIRM 0x800
+#define MSG_RST 0x1000
+#define MSG_ERRQUEUE 0x2000
+#define MSG_NOSIGNAL 0x4000
+#define MSG_MORE 0x8000
+#define MSG_WAITFORONE 0x10000
+#define MSG_CMSG_CLOEXEC 0x40000000
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906
+#define SIOCGSTAMPNS 0x8907
+
typedef unsigned int sa_family_t;
-#define AF_INET PF_INET
-#define AF_INET6 6
-#define PF_INET6 AF_INET6
struct sockaddr {
sa_family_t sa_family;
@@ -87,13 +239,6 @@ struct linger {
int l_linger;
};
-#define SIOCATMARK 0x8905
-
-#define SOCK_RAW 111
-#define SOCK_SEQPACKET 555
-
-#define PF_APPLETALK 5
-
#ifdef __cplusplus
}
#endif
diff --git a/system/lib/libc/musl/src/stdlib/ecvt.c b/system/lib/libc/musl/src/stdlib/ecvt.c
new file mode 100644
index 00000000..79c3de63
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/ecvt.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+char *ecvt(double x, int n, int *dp, int *sign)
+{
+ static char buf[16];
+ char tmp[32];
+ int i, j;
+
+ if (n-1U > 15) n = 15;
+ sprintf(tmp, "%.*e", n-1, x);
+ i = *sign = (tmp[0]=='-');
+ for (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.'))
+ buf[j] = tmp[i];
+ buf[j] = 0;
+ *dp = atoi(tmp+i+1)+1;
+
+ return buf;
+}
diff --git a/system/lib/libc/musl/src/stdlib/fcvt.c b/system/lib/libc/musl/src/stdlib/fcvt.c
new file mode 100644
index 00000000..f90928fe
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/fcvt.c
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+char *fcvt(double x, int n, int *dp, int *sign)
+{
+ char tmp[1500];
+ int i, lz;
+
+ if (n > 1400U) n = 1400;
+ sprintf(tmp, "%.*f", n, x);
+ i = (tmp[0] == '-');
+ if (tmp[i] == '0') lz = strspn(tmp+i+2, "0");
+ else lz = -(int)strcspn(tmp+i, ".");
+
+ if (n<=lz) {
+ *sign = i;
+ *dp = 1;
+ if (n>14U) n = 14;
+ return "000000000000000"+14-n;
+ }
+
+ return ecvt(x, n-lz, dp, sign);
+}
diff --git a/system/lib/libc/musl/src/stdlib/gcvt.c b/system/lib/libc/musl/src/stdlib/gcvt.c
new file mode 100644
index 00000000..6c075e25
--- /dev/null
+++ b/system/lib/libc/musl/src/stdlib/gcvt.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+char *gcvt(double x, int n, char *b)
+{
+ sprintf(b, "%.*g", n, x);
+ return b;
+}
diff --git a/system/lib/libcextra.symbols b/system/lib/libcextra.symbols
index 42e66b51..a365271d 100644
--- a/system/lib/libcextra.symbols
+++ b/system/lib/libcextra.symbols
@@ -1,4 +1,7 @@
T btowc
+ T ecvt
+ T fcvt
+ T gcvt
T iswalnum
T iswalpha
T iswblank
diff --git a/tests/runner.py b/tests/runner.py
index c1924552..23ec07b9 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -16,7 +16,7 @@ so you may prefer to use fewer cores here.
'''
from subprocess import Popen, PIPE, STDOUT
-import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, re, difflib, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing, functools, stat
+import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, re, difflib, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing, functools, stat, string
if len(sys.argv) == 1:
print '''
@@ -355,6 +355,9 @@ process(sys.argv[1])
cache_name = name + str(Building.COMPILER_TEST_OPTS) + cache_name_extra + (self.env.get('EMCC_LLVM_TARGET') or '')
+ valid_chars = "_%s%s" % (string.ascii_letters, string.digits)
+ cache_name = ''.join([(c if c in valid_chars else '_') for c in cache_name])
+
if self.library_cache is not None:
if cache and self.library_cache.get(cache_name):
print >> sys.stderr, '<load %s from cache> ' % cache_name,
@@ -1984,6 +1987,24 @@ Succeeded!
self.do_run(src, "1.0 2.0 -1.0 -2.0 2.0 3.0 -2.0 -3.0 "
"1 2 -1 -2 2 2 -2 -2")
+ # This example borrowed from MSDN documentation
+ def test_fcvt(self):
+ src = '''
+ #include <stdlib.h>
+ #include <stdio.h>
+
+ int main() {
+ int decimal, sign;
+ char *buffer;
+ double source = 3.1415926535;
+
+ buffer = fcvt(source, 7, &decimal, &sign);
+ printf("source: %2.10f buffer: '%s' decimal: %d sign: %d\\n",
+ source, buffer, decimal, sign);
+ }
+ '''
+ self.do_run(src, "source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0");
+
def test_llrint(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2')
src = r'''
@@ -4062,17 +4083,11 @@ def process(filename):
self.do_run(src, 'Inline JS is very cool\n3.64')
- def zzztest_inlinejs2(self):
+ def test_inlinejs2(self):
if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm')
src = r'''
#include <stdio.h>
- double get() {
- double ret = 0;
- __asm __volatile__("Math.abs(-12/3.3)":"=r"(ret)); // write to a variable
- return ret;
- }
-
int mix(int x, int y) {
int ret;
asm("Math.pow(2, %0+%1+1)" : "=r"(ret) : "r"(x), "r"(y)); // read and write
@@ -4085,15 +4100,13 @@ def process(filename):
}
int main(int argc, char **argv) {
- asm("Module.print('Inline JS is very cool')");
- printf("%.2f\n", get());
printf("%d\n", mix(argc, argc/2));
mult();
return 0;
}
'''
- self.do_run(src, 'Inline JS is very cool\n3.64\nwaka\nzakai\n')
+ self.do_run(src, '4\n200\n')
def test_memorygrowth(self):
if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays')
@@ -7089,7 +7102,7 @@ def process(filename):
other.close()
src = open(path_from_root('tests', 'files.cpp'), 'r').read()
- self.do_run(src, 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\ntexte\n',
+ self.do_run(src, ('size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\ntexte\n', 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\n'),
post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h'])
def test_files_m(self):
@@ -7121,7 +7134,7 @@ def process(filename):
return 0;
}
'''
- self.do_run(src, 'got: 35\ngot: 45\ngot: 25\ngot: 15\nisatty? 0,0,1\n', post_build=post)
+ self.do_run(src, ('got: 35\ngot: 45\ngot: 25\ngot: 15\nisatty? 0,0,1\n', 'isatty? 0,0,1\ngot: 35\ngot: 45\ngot: 25\ngot: 15\n'), post_build=post)
def test_fwrite_0(self):
src = r'''
@@ -7764,6 +7777,8 @@ def process(filename):
self.do_run(src, '120.86.52.18\n120.86.52.18\n')
def test_inet4(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2')
+
src = r'''
#include <stdio.h>
#include <arpa/inet.h>
@@ -11041,6 +11056,24 @@ f.close()
voidfunc sidey(voidfunc f) { return f; }
''', 'hello from funcptr\n')
+ # function pointers with 'return' in the name
+ test('fp2', 'typedef void (*voidfunc)();', r'''
+ #include <stdio.h>
+ #include "header.h"
+ int sidey(voidfunc f);
+ void areturn0() { printf("hello 0\n"); }
+ void areturn1() { printf("hello 1\n"); }
+ void areturn2() { printf("hello 2\n"); }
+ int main(int argc, char **argv) {
+ voidfunc table[3] = { areturn0, areturn1, areturn2 };
+ table[sidey(NULL)]();
+ return 0;
+ }
+ ''', '''
+ #include "header.h"
+ int sidey(voidfunc f) { if (f) f(); return 1; }
+ ''', 'hello 1\n')
+
# Global initializer
test('global init', '', r'''
#include <stdio.h>
@@ -11646,6 +11679,39 @@ int main(int argc, char const *argv[])
self.assertContained('a\nb\n', run_js(os.path.join(self.get_dir(), 'a.out.js')))
+ def test_export_in_a(self):
+ export_name = 'this_is_an_entry_point'
+
+ open('export.c', 'w').write(r'''
+ #include <stdio.h>
+ void %s(void) {
+ printf("Hello, world!\n");
+ }
+ ''' % export_name)
+ Popen([PYTHON, EMCC, 'export.c', '-c', '-o', 'export.o']).communicate()
+ Popen([PYTHON, EMAR, 'rc', 'libexport.a', 'export.o']).communicate()
+
+ open('main.c', 'w').write(r'''
+ int main() {
+ return 0;
+ }
+ ''')
+
+ definition = 'function _%s(' % export_name
+
+ # Sanity check: the symbol should not be linked in if not requested.
+ Popen([PYTHON, EMCC, 'main.c', '-L.', '-lexport']).communicate()
+ self.assertNotContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
+ # Sanity check: exporting without a definition does not cause it to appear.
+ # Note: exporting main prevents emcc from warning that it generated no code.
+ Popen([PYTHON, EMCC, 'main.c', '-s', '''EXPORTED_FUNCTIONS=['_main', '_%s']''' % export_name]).communicate()
+ self.assertNotContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
+ # Actual test: defining symbol in library and exporting it causes it to appear in the output.
+ Popen([PYTHON, EMCC, 'main.c', '-L.', '-lexport', '-s', '''EXPORTED_FUNCTIONS=['_%s']''' % export_name]).communicate()
+ self.assertContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
def test_embed_file(self):
open(os.path.join(self.get_dir(), 'somefile.txt'), 'w').write('''hello from a file with lots of data and stuff in it thank you very much''')
open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r'''
diff --git a/tools/asm_module.py b/tools/asm_module.py
index e54cfc21..bf7fa71d 100644
--- a/tools/asm_module.py
+++ b/tools/asm_module.py
@@ -49,7 +49,7 @@ class AsmModule():
# tables and exports
post_js = self.js[self.end_funcs:self.end_asm]
- ret = post_js.find('return')
+ ret = post_js.find('return ')
self.tables_js = post_js[:ret]
self.exports_js = post_js[ret:]
self.tables = self.parse_tables(self.tables_js)
diff --git a/tools/shared.py b/tools/shared.py
index c0df227d..f6d0ff4f 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -360,8 +360,15 @@ def check_sanity(force=False):
# Tools/paths
-LLVM_ADD_VERSION = os.getenv('LLVM_ADD_VERSION')
-CLANG_ADD_VERSION = os.getenv('CLANG_ADD_VERSION')
+try:
+ LLVM_ADD_VERSION
+except NameError:
+ LLVM_ADD_VERSION = os.getenv('LLVM_ADD_VERSION')
+
+try:
+ CLANG_ADD_VERSION
+except NameError:
+ CLANG_ADD_VERSION = os.getenv('CLANG_ADD_VERSION')
# Some distributions ship with multiple llvm versions so they add
# the version to the binaries, cope with that
@@ -876,7 +883,10 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
@staticmethod
def link(files, target, force_archive_contents=False):
actual_files = []
- unresolved_symbols = set(['main']) # tracking unresolveds is necessary for .a linking, see below. (and main is always a necessary symbol)
+ # Tracking unresolveds is necessary for .a linking, see below.
+ # Specify all possible entry points to seed the linking process.
+ # For a simple application, this would just be "main".
+ unresolved_symbols = set([func[1:] for func in Settings.EXPORTED_FUNCTIONS])
resolved_symbols = set()
temp_dirs = []
files = map(os.path.abspath, files)