Commit Graph

11275 Commits (f782824d4829d89b078aafcdcc3a1fa043b58f39)

Author SHA1 Message Date
Shigeki Ohtsu f782824d48 deps: refactor openssl.gyp
Updated gyp has "else if" syntax in condition. Use this for
target_arch and OS switches. Several sources, defines, rules and
libraries variables moved to gypi files.

PR-URL: https://github.com/iojs/io.js/pull/1325
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-04 12:37:26 +09:00
Shigeki Ohtsu eb459c8151 tools: fix gyp to work on MacOSX without XCode
This issue has already submitted to the upstream in
https://code.google.com/p/gyp/issues/detail?id=477
Use this commit until the upstream is to be fixed.

PR-URL: https://github.com/iojs/io.js/pull/1325
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-04 12:37:26 +09:00
Fedor Indutny 15f058f609 gyp: fix build with python 2.6
Fixes: https://github.com/joyent/node/issues/6859
PR-URL: https://github.com/iojs/io.js/pull/1325
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
2015-04-04 12:36:53 +09:00
Shigeki Ohtsu 21f4fb6215 deps: update gyp to e1c8fcf7
PR-URL: https://github.com/iojs/io.js/pull/1325
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-04 11:01:26 +09:00
Bert Belder efadffe861 win,node-gyp: optionally allow node.exe/iojs.exe to be renamed
On Windows, when node or io.js attempts to dynamically load a compiled
addon, the compiled addon tries to load node.exe or iojs.exe again -
depending on which import library the module used when it was linked.
This causes many compiled addons to break when node.exe or iojs.exe are
renamed, because when the binary has been renamed the addon DLL can't
find the (right) .exe file to load its imports from.

This patch gives compiled addon developers an option to overcome this
restriction by compiling a delay-load hook into their binary. The
delay-load hook ensures that whenever a module tries to load imports
from node.exe/iojs.exe, it'll just look at the process image, thereby
making the addon work regardless of what name the node/iojs binary has.

To enable this feature, the addon developer must set the
'win_delay_load_hook' option to 'true' in their binding.gyp file, like
this:

```
{
  'targets': [
    {
      'target_name': 'ernie',
      'win_delay_load_hook': 'true',
      ...
```

Bug: https://github.com/iojs/io.js/issues/751
Bug: https://github.com/iojs/io.js/issues/965
Upstream PR: https://github.com/TooTallNate/node-gyp/pull/599

PR-URL: https://github.com/iojs/io.js/pull/1251
Reviewed-By: Rod Vagg <rod@vagg.org>

PR-URL: https://github.com/iojs/io.js/pull/1266
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-03 17:11:21 -07:00
cjihrig dac903f9b6 deps: make node-gyp work with io.js
Every npm version bump requires a few patches to be floated on
node-gyp for io.js compatibility. These patches are found in
03d199276e,
5de334c230, and
da730c76e9. This commit squashes
them into a single commit.

PR-URL: https://github.com/iojs/io.js/pull/990
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-03 17:11:21 -07:00
Forrest L Norvell 5eb983e0b3 deps: upgrade npm to 2.7.5
PR-URL: https://github.com/iojs/io.js/pull/1337
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2015-04-03 17:09:21 -07:00
Fedor Indutny 416499c872 timers: remove redundant code
PR-URL: https://github.com/iojs/io.js/pull/1330
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
2015-04-04 02:31:51 +03:00
Fedor Indutny 6f72d87c27 test: add test for a unref'ed timer leak
PR-URL: https://github.com/iojs/io.js/pull/1330
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
2015-04-04 02:31:50 +03:00
Fedor Indutny d22b2a934a timers: do not restart the interval after close
Partially revert 776b73b243.

Following code crashes after backported timer leak fixes:

```javascript
var timer = setInterval(function() {
  clearInterval(timer);
}, 10);
timer.unref();
```

Note that this is actually tested in a `test-timers-unref.js`, and is
crashing only with 776b73b243.

Calling `clearInterval` leads to the crashes in case of `.unref()`ed
timers, and might lead to a extra timer spin in case of regular
intervals that was closed during the interval callback. All of these
happens because `.unref()`ed timer has it's own `_handle` and was used
after the `.close()`.

PR-URL: https://github.com/iojs/io.js/pull/1330
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
2015-04-04 02:31:47 +03:00
Julien Gilli cca5efb086 timers: don't close interval timers when unrefd
This change fixes a regression introduced by commit
0d051238be, which contained a typo that
would cause every unrefd interval to fire only once.

Fixes: https://github.com/joyent/node/issues/8900
Reviewed-By: Timothy J Fontaine <tjfontaine@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
2015-04-04 02:30:33 +03:00
Trevor Norris 0e061975d7 timers: fix unref() memory leak
The destructor isn't being called for timers that have been unref'd.

Fixes: https://github.com/joyent/node/issues/8364
PR-URL: https://github.com/iojs/io.js/pull/1330
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2015-04-04 02:29:57 +03:00
Ali Ijaz Sheikh b6e22c4bd5 src: setup cluster workers before preloading
We need to process cluster workers before any preload modules is
executed. Otherwise, the child processes are not correctly disovered
as clustered workers inside the preloaded modules.

Fixes: https://github.com/iojs/io.js/issues/1269
PR-URL: https://github.com/iojs/io.js/pull/1314
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
2015-04-04 00:53:45 +02:00
Giovanny Andres Gongora Granada 65d4d25f52 build: default to armv7+vfpv3 for android
Also add Android build instructions to the README.

PR-URL: https://github.com/iojs/io.js/pull/1307
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-04 00:53:03 +02:00
Aria Stewart ad937752ee doc,src: remove references to --max-stack-size
Remove obsolete references to the removed --max-stack-size switch.

PR-URL: https://github.com/iojs/io.js/pull/1327
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-04 00:30:30 +02:00
Ben Noordhuis 4a801c211c src: drop homegrown thread pool, use libplatform
Drop the homegrown thread pool that was introduced in commit 50839a0
("v8_platform: provide default v8::Platform impl") and use one from
V8's libplatform library.  Performance is comparable and it removes
a few hundred lines of code.

The calls to v8::platform::PumpMessageLoop() are currently no-ops
because V8 does not (yet?) use v8::Platform::CallOnForegroundThread().

Packagers that link against a shared libv8 now also need to make
libv8_platform available.

PR-URL: https://github.com/iojs/io.js/pull/1329
Reviewed-By: Fedor Indutny <fedor@indutny.com>
2015-04-04 00:21:39 +02:00
Kohei TAKATA 87053e8aee doc: add back quote to boolean variable 'true'
PR-URL: https://github.com/iojs/io.js/pull/1338
Reviewed-By: Roman Reiss <me@silverwind.io>
2015-04-03 16:10:37 +02:00
Johan Bergström 6a134f7d70 build: avoid passing private flags from pmake
pmake introduces private flags (-J) when passing certain arguments
to it (such as -j). Filter these out before passing to gmake.

PR-URL: https://github.com/iojs/io.js/pull/1334
Reviewed-By: Fedor Indutny <fedor@indutny.com>
2015-04-03 19:38:33 +11:00
Brian White a081c7c522 benchmark: fix chunky client benchmark execution
This commit fixes a few things for this benchmark:

1. Ensures the temporary directory for the unix socket exists.
2. Prevents the client code from being run directly because the
server script is the one that calls out the client code.
3. Ensures the server is closed once the client benchmarks have
finished.
4. Since this is an http benchmark, it should be moved to the http
benchmarks subdirectory.

PR-URL: https://github.com/iojs/io.js/pull/1257
Reviewed-By: Roman Reiss <me@silverwind.io>
2015-04-03 00:56:45 -04:00
Johan Bergström f1e5a13516 src: wrap MIN definition in infdef
Some platforms already define this; avoid redefining if that's
the case. Found on OpenBSD 5.6.

PR-URL: https://github.com/iojs/io.js/pull/1322
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-02 11:08:54 +11:00
Ben Noordhuis 008078862e deps: check in gtest, add util unit test
Check in a gypified gtest and add a simple unit test to show that the
basic infrastructure is in place.

PR-URL: https://github.com/iojs/io.js/pull/1199
Refs: https://github.com/iojs/io.js/issues/1193
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
2015-04-01 22:35:56 +02:00
Ben Noordhuis 382bd9d2e0 v8: back-port openbsd/amd64 build fix
Cherry-pick https://codereview.chromium.org/856553002 from upstream.

Makes V8 on OpenBSD/amd64 pick up the right V8_INT64_C and V8_UINT64_C
macros.

PR-URL: https://github.com/iojs/io.js/pull/1318
Refs: https://github.com/iojs/io.js/pull/1312
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
2015-04-02 00:28:25 +02:00
Rod Vagg 634e9629a0 doc: add TC meeting minutes 2015-03-04
PR-URL: https://github.com/iojs/io.js/pull/1123
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2015-04-01 23:33:22 +11:00
Johan Bergström 5094a0fde3 build: Pass BSDmakefile args to gmake
Minor convenience for platforms that doesn't have gmake installed
but prefer the habit of writing make instead of gmake.

test needs to live in .PHONY to get passed on to gmake.

PR-URL: https://github.com/iojs/io.js/pull/1298
Reviewed-By: Fedor Indutny <fedor@indutny.com>
2015-04-01 11:00:58 +11:00
Brian White 4dc6ae2181 lib: remove unused variables
PR-URL: https://github.com/iojs/io.js/pull/1290
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-31 15:58:42 -04:00
Jeremiah Senkpiel 245ba1d658 doc: fix util.isObject documentation
Proposed functionality fix containing prior discussion:
https://github.com/iojs/io.js/pull/822

Fixes: https://github.com/iojs/io.js/issues/743
PR-URL: https://github.com/iojs/io.js/pull/1295
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Brendan Ashworth <brendan.ashworth@me.com>
2015-03-31 10:51:23 -04:00
Rod Vagg 0bd4fe943a Working on v1.6.4 2015-03-31 22:45:25 +11:00
Rod Vagg 4845f9c209 2015-03-31 io.js v1.6.3 Release
Notable changes:

 * fs: corruption can be caused by fs.writeFileSync() and append-mode
   fs.writeFile() and fs.writeFileSync() under certain circumstances,
   reported in #1058, fixed in #1063 (Olov Lassus).
 * iojs: an "internal modules" API has been introduced to allow core
   code to share JavaScript modules internally only without having to
   expose them as a public API, this feature is for core-only #848
   (Vladimir Kurchatkin).
 * timers: two minor problems with timers have been fixed:
   - Timer#close() is now properly idempotent #1288 (Petka Antonov).
   - setTimeout() will only run the callback once now after an
     unref() during the callback #1231 (Roman Reiss).
 * Windows: a "delay-load hook" has been added for compiled add-ons
   on Windows that should alleviate some of the problems that Windows
   users may be experiencing with add-ons in io.js #1251
   (Bert Belder).
 * V8: minor bug-fix upgrade for V8 to 4.1.0.27.
 * npm: upgrade npm to 2.7.4. See npm CHANGELOG.md for details.
2015-03-31 22:45:08 +11:00
Bert Belder ba93c583bc win,node-gyp: optionally allow node.exe/iojs.exe to be renamed
On Windows, when node or io.js attempts to dynamically load a compiled
addon, the compiled addon tries to load node.exe or iojs.exe again -
depending on which import library the module used when it was linked.
This causes many compiled addons to break when node.exe or iojs.exe are
renamed, because when the binary has been renamed the addon DLL can't
find the (right) .exe file to load its imports from.

This patch gives compiled addon developers an option to overcome this
restriction by compiling a delay-load hook into their binary. The
delay-load hook ensures that whenever a module tries to load imports
from node.exe/iojs.exe, it'll just look at the process image, thereby
making the addon work regardless of what name the node/iojs binary has.

To enable this feature, the addon developer must set the
'win_delay_load_hook' option to 'true' in their binding.gyp file, like
this:

```
{
  'targets': [
    {
      'target_name': 'ernie',
      'win_delay_load_hook': 'true',
      ...
```

Bug: https://github.com/iojs/io.js/issues/751
Bug: https://github.com/iojs/io.js/issues/965
Upstream PR: https://github.com/TooTallNate/node-gyp/pull/599

PR-URL: https://github.com/iojs/io.js/pull/1251
Reviewed-By: Rod Vagg <rod@vagg.org>

PR-URL: https://github.com/iojs/io.js/pull/1266
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-30 14:48:12 -07:00
cjihrig 2752da4b64 deps: make node-gyp work with io.js
Every npm version bump requires a few patches to be floated on
node-gyp for io.js compatibility. These patches are found in
03d199276e,
5de334c230, and
da730c76e9. This commit squashes
them into a single commit.

PR-URL: https://github.com/iojs/io.js/pull/990
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-30 14:34:40 -07:00
Forrest L Norvell f166cdecf1 deps: upgrade npm to 2.7.4 2015-03-30 14:34:39 -07:00
Farrin Reid 73de13511d doc: add WG links in WORKING_GROUPS.md & fix nits
Related to https://github.com/iojs/evangelism/issues/24

PR-URL: https://github.com/iojs/io.js/pull/1113
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Mikeal Rogers <mikeal.rogers@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
2015-03-30 13:40:16 -04:00
Ben Noordhuis 8d1c87ea0a test: fix race in parallel/test-vm-debug-context
Fix a race condition in parallel/test-vm-debug-context where the 'exit'
event for the child process is emitted before the first and only 'data'
event for the child process's stderr stream.

I considered deferring the 'exit' event in lib/child_process.js until
all stdio streams have been closed but I realized that's not going to
work when the child process spins off grandchildren that keep the stdio
file descriptors alive.

Fixes: https://github.com/iojs/io.js/issues/1291
PR-URL: https://github.com/iojs/io.js/pull/1294
Reviewed-By: Brendan Ashworth <brendan.ashworth@me.com>
2015-03-30 00:29:28 +02:00
Ben Noordhuis ea37ac04f4 src: ignore ENOTCONN on shutdown race with child
On AIX, OS X and the BSDs, calling shutdown() on one end of a pipe
when the other end has closed the connection fails with ENOTCONN.

The sequential/test-child-process-execsync test failed sporadically
because of a race between the parent and the child where one closed
its end of the pipe before the other got around to calling shutdown()
on its end of the pipe.

Libuv is not the right place to handle that because it can't tell if
the ENOTCONN error is genuine but io.js can.

Refs: https://github.com/libuv/libuv/pull/268
PR-URL: https://github.com/iojs/io.js/pull/1214
Reviewed-By: Bert Belder <bertbelder@gmail.com>
2015-03-28 13:26:29 +01:00
Ali Ijaz Sheikh f06b16f2e9 src: fix minor memleak in preload-modules
Free the preload_modules array once we are done with it.

PR-URL: https://github.com/iojs/io.js/pull/1265
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-28 12:43:18 +01:00
Roman Reiss 19641b17be doc: decouple sidebar scrolling
This lets the doc sidebar have its own scrolling container, making the
page easier to navigate in cases where previously the menu was scrolled
far off.

PR-URL: https://github.com/iojs/io.js/pull/1274
Reviewed-by: Chris Dickinson <christopher.s.dickinson@gmail.com>
Reviewed-By: Brendan Ashworth <brendan.ashworth@me.com>
2015-03-28 12:31:23 +01:00
Ben Noordhuis 318d9d8fd7 deps: upgrade v8 to 4.1.0.27
PR-URL: https://github.com/iojs/io.js/pull/1289
Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
2015-03-27 23:42:05 +01:00
Brendan Ashworth c8fa8ccdbc streams: use strict on _stream_wrap
A Mostly Harmless™ change to enable 'use strict' mode in _stream_wrap, bringing it in line with /all/ the other modules.

PR-URL: https://github.com/iojs/io.js/pull/1279
Reviewed-By: Brian White (@mscdex) <mscdex@mscdex.net>
Reviewed-By: Roman Reiss (@silverwind) <me@silverwind.io>
Reviewed-By: Yosuke Furukawa (@yosuke-furukawa)
<yosuke.furukawa@gmail.com>
2015-03-28 04:06:01 +09:00
Petka Antonov 77c2da10fd timers: make Timer.close idempotent
fixes #1287

PR-URL: https://github.com/iojs/io.js/pull/1288
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-27 20:50:09 +02:00
Phillip Lamplugh dbccf8d3ed doc: fix spelling error in feature flags
PR-URL: https://github.com/iojs/io.js/pull/1286
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-27 18:37:17 +01:00
Jackson Tian a2ea16838f debugger: don't spawn child process in remote mode
When debug in remote mode with host:port or pid, the interface
spawn child process also. If the debugger agent is running, will
get following output:

```
< Error: listen EADDRINUSE :::5858
<     at Object.exports._errnoException (util.js:734:11)
<     at exports._exceptionWithHostPort (util.js:757:20)
<     at Agent.Server._listen2 (net.js:1155:14)
<     at listen (net.js:1181:10)
<     at Agent.Server.listen (net.js:1268:5)
<     at Object.start (_debug_agent.js:21:9)
<     at startup (node.js:68:9)
<     at node.js:799:3
```

This fix won't spawn child process and no more error message was
shown.

When use `iojs debug`, the tip information just like this:

```
Usage: iojs debug script.js
```

This fix will display the advance usage also:

```
Usage: iojs debug script.js
       iojs debug <host>:<port>
       iojs debug -p <pid>
```

Fixes: https://github.com/iojs/io.js/issues/889
PR-URL: https://github.com/iojs/io.js/pull/1282
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-27 17:28:48 +01:00
Roman Reiss 955c1508da test: reduce sequential/test-fs-watch flakiness
The fs.watch test's write events sometimes aren't produced on OS X,
possibly because of a fsevents race condition. This patch gives delays
the writing a total of 20ms, which makes the test pass consistently.

PR-URL: https://github.com/iojs/io.js/pull/1275
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-27 17:08:07 +01:00
Ben Noordhuis 36f017afaf js2c: fix module id generation on windows
Fix a regression that was introduced in commit 2db758c ("iojs: introduce
internal modules") where the computed id for "config.gypi" on Windows
was not "config" but an empty string.

With an empty string, the build succeeds but the binary is unusable:
startup.processConfig() in src/node.js chokes on the missing .config
property.

PR-URL: https://github.com/iojs/io.js/pull/1281
Reviewed-By: Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
2015-03-27 11:10:25 +01:00
Ben Noordhuis 2903410aa8 src: don't lazy-load timer globals
Don't lazy-load setInterval(), setTimeout(), etc.  Most applications are
going to need them and routing every call through NativeModule.require()
and Function#apply() is not exactly efficient.

PR-URL: https://github.com/iojs/io.js/pull/1280
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2015-03-27 00:07:06 +01:00
Jeremiah Senkpiel 5e609e9324 Revert "doc: clarify real name requirement"
This reverts commit 4e9bf93e9c.

PR-URL: https://github.com/iojs/io.js/pull/1276
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Rod Vagg <rod@vagg.org>
2015-03-26 17:50:45 -04:00
Bert Belder 08acf1352c win,node-gyp: make delay-load hook optional
The delay-load hook that was landed in 3d46fef to make compiled addons
work on Windows regardless of the iojs.exe/node.exe filename causes
issues with a small amount of compiled addons.

Therefore this patch makes it an opt-in feature. An addon may set the
'win_delay_load_hook' option to 'true' in its binding.gyp to enable this
feature.

Example:

```
{
  'targets': [
    {
      'target_name': 'ernie',
      'win_delay_load_hook': 'true',
      ...
```

Refs: https://github.com/iojs/io.js/pull/1251
PR-URL: https://github.com/iojs/io.js/pull/1266
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-26 13:32:06 -07:00
Jeremiah Senkpiel 776b73b243 timers: cleanup interval handling
Uses `null` as the false-y value for `_repeat` as like other properties.
Removes un-reachable statement in setInterval’s `wrapper()`.

PR-URL: https://github.com/iojs/io.js/pull/1272
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-26 14:17:56 -04:00
Roman Reiss caf0b36de3 timers: assure setTimeout callback only runs once
Calling this.unref() during the callback of SetTimeout caused the
callback to get executed twice because unref() didn't expect to be
called during that time and did not stop the ref()ed Timeout but
did start a new timer. This commit prevents the new timer creation
when the callback was already called.

Fixes: https://github.com/iojs/io.js/issues/1191
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
PR-URL: https://github.com/iojs/io.js/pull/1231
2015-03-26 17:31:20 +01:00
Fedor Indutny 2ccc8f3970 tls_wrap: fix this incredibly stupid leak
Always call `Done` on the WriteWrap, and ensure that `EncOut` will
consume all data in clear_in_ and invoke queued callbacks.

Fix: https://github.com/iojs/io.js/issues/1075
PR-URL: https://github.com/iojs/io.js/pull/1244
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-25 17:51:05 -05:00
Fedor Indutny e74b5d278c tls_wrap: fix BIO leak on SSL error
Fix: https://github.com/iojs/io.js/issues/1075
PR-URL: https://github.com/iojs/io.js/pull/1244
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-03-25 17:50:50 -05:00