From 6a29c552abbe0c60dad3f86b64483487ab566079 Mon Sep 17 00:00:00 2001 From: Caleb James DeLisle Date: Fri, 2 Oct 2020 23:54:28 +0200 Subject: [PATCH] Separation of concerns between builder and cjdns-specific build stuff --- node_build/Codestyle.js | 2 +- node_build/Cp.js | 2 +- node_build/HasFunction.js | 36 --- node_build/builder.js | 404 ++++++++++++-------------- node_build/make.js | 82 ++---- node_modules/nthen/package.json | 12 +- node_modules/saferphore/.flowconfig | 7 + node_modules/saferphore/.jshintignore | 1 + node_modules/saferphore/.jshintrc | 16 + node_modules/saferphore/.travis.yml | 12 + node_modules/saferphore/index.js | 50 ++++ node_modules/saferphore/package.json | 51 ++++ node_modules/saferphore/readme.md | 30 ++ node_modules/saferphore/test.js | 54 ++++ package-lock.json | 225 +------------- package.json | 6 +- tools/lib/Semaphore.js | 69 +++-- tools/lib/cjdnsadmin/cjdnsadmin.js | 2 +- 18 files changed, 505 insertions(+), 556 deletions(-) delete mode 100644 node_build/HasFunction.js create mode 100644 node_modules/saferphore/.flowconfig create mode 100644 node_modules/saferphore/.jshintignore create mode 100644 node_modules/saferphore/.jshintrc create mode 100644 node_modules/saferphore/.travis.yml create mode 100644 node_modules/saferphore/index.js create mode 100644 node_modules/saferphore/package.json create mode 100644 node_modules/saferphore/readme.md create mode 100644 node_modules/saferphore/test.js diff --git a/node_build/Codestyle.js b/node_build/Codestyle.js index 0fb8770c..2a6b5f20 100644 --- a/node_build/Codestyle.js +++ b/node_build/Codestyle.js @@ -15,7 +15,7 @@ 'use strict'; var Fs = require('fs'); var nThen = require('nthen'); -var Semaphore = require('../tools/lib/Semaphore'); +var Semaphore = require('saferphore'); var Child = require('child_process'); var headerLines = [ diff --git a/node_build/Cp.js b/node_build/Cp.js index 708867f4..c7395794 100644 --- a/node_build/Cp.js +++ b/node_build/Cp.js @@ -1,6 +1,6 @@ 'use strict'; var Fs = require("fs"); -var Semaphore = require('../tools/lib/Semaphore'); +var Semaphore = require('saferphore'); var nThen = require('nthen'); var sema = Semaphore.create(64); diff --git a/node_build/HasFunction.js b/node_build/HasFunction.js deleted file mode 100644 index a3074700..00000000 --- a/node_build/HasFunction.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; -var nThen = require("nthen"); -var Fs = require("fs"); - -module.exports.check = function (builder, func, ldflags, callback) { - - var file = builder.tmpFile(); - var outputFile = builder.tmpFile(); - - nThen(function (waitFor) { - - Fs.writeFile(file, "int main() { " + func + "(); }", waitFor(function (err, ret) { - if (err) { - waitFor.abort(); - callback(err); - } - })); - - }).nThen(function (waitFor) { - - var flags = []; - flags.push.apply(flags, ["-x", "c", "-o", outputFile, file]); - flags.push.apply(flags, ldflags); - - builder.cc(flags, waitFor(function (ret, out, err) { - if (ret && /undefined reference/.test(err)) { - callback(undefined, false); - } else if (ret) { - callback(new Error(err)); - } else { - callback(undefined, true); - } - })); - - }); -}; diff --git a/node_build/builder.js b/node_build/builder.js index 39900725..5b8a68d1 100644 --- a/node_build/builder.js +++ b/node_build/builder.js @@ -19,136 +19,7 @@ const Fs = require('fs'); const Spawn = require('child_process').spawn; const nThen = require('nthen'); const Crypto = require('crypto'); -const Semaphore = require('../tools/lib/Semaphore'); -const GetVersion = require('./GetVersion'); - -/* - * Why hello dear packager, - * - * I suppose you have found this place as you are trying to figure out how to work this into your - * build system. You're probably faced with a decision between getting node.js into your build and - * "fixing" this build process so it doesn't need such a silly thing. A 500 line script is certainly - * not unapproachable, right? - * The reason why I am speaking to you now is because I care about you. I want you to be happy - * and live a carefree life, and because you are standing on the precipice of a cavern so dark and - * deep that while you may well make it out alive, your personal pride and innocence almost - * certainly will not. Imagine yourself after months of sleepless nights wallowing in the quicksand, - * forever trying to slay the dragon which is always so close yet and so far away. Imagine the deep - * hatred you will have for humanity, code, and the creator of this doomsday machine. I beg you to - * turn back now while there is still hope. You need not die here, your life is important, and - * whether you close this file now or not, in the end you will still end up including node.js in - * your build. - * - * The Creator - */ - -// Since many of the compile operations are short, the best -// performance seems to be when running 1.25x the number of jobs as -// cpu cores. On BSD and iphone systems, os.cpus() is not reliable so -// if it returns undefined let's just assume 1 -const cpus = Os.cpus(); // workaround, nodejs seems to be broken on openbsd (undefined result after second call) -const PROCESSORS = Math.floor((typeof cpus === 'undefined' ? 1 : cpus.length) * 1.25); - -const error = function (message) /*:Error*/ { - try { - throw new Error(message); - } catch (e) { - return e; - } -}; - -const throwIfErr = function(err) { - if (err) { - throw new Error(err); - } -}; - -const expandArgs = function (args) { - const out = []; - for (let i = 0; i < args.length; i++) { - if (typeof(args[i]) === 'object') { - if (Array.isArray(args[i])) { - out.push.apply(out, expandArgs(args[i])); - } else { - throw new Error("object in arguments [" + args.join() + "]"); - } - } else { - out.push(args[i]); - } - } - return out; -}; - -const sema = Semaphore.create(PROCESSORS); -const compiler = function ( - compilerPath /*:string*/, - args /*:string[]*/, - callback /*:(number, string, string)=>bool|void*/, - content /*:string*/ -) { - let stop = false; - args = expandArgs(args); - sema.take(function (returnAfter) { - if (stop) { - return returnAfter(function (ret) { - callback(1, '', 'interrupted'); - }); - } - if (process.env.VERBOSE) { - console.log(compilerPath + ' ' + args.join(' ')); - } - const gcc = Spawn(compilerPath, args); - let err = ''; - let out = ''; - - gcc.stdout.on('data', function (dat) { out += dat.toString(); }); - gcc.stderr.on('data', function (dat) { err += dat.toString(); }); - gcc.on('close', returnAfter(function (ret) { - if (callback(ret, out, err)) { stop = true; } - })); - - gcc.on('error', function (err) { - if (err.code === 'ENOENT') { - console.error('\x1b[1;31mError: ' + compilerPath + ' is required!\x1b[0m'); - } else { - console.error( - '\x1b[1;31mFail run ' + process.cwd() + ': ' + compilerPath + ' ' - + args.join(' ') + '\x1b[0m' - ); - console.error('Message:' + err); - } - - // handle the error safely - console.log(args); - }); - - if (content) { - gcc.stdin.write(content, function (err) { - if (err) { throw err; } - gcc.stdin.end(); - }); - } - }); -}; - -const cc = function ( - gcc /*:string*/, - args /*:string[]*/, - callback /*:(?Error, ?string)=>bool|void*/, - content /*:string*/ -) { - compiler(gcc, args, function (ret, out, err) { - if (ret) { - return callback(error("gcc " + args.map(String).join(' ') + "\n\n" + err)); - } - - if (err !== '') { - //process.stdout.write(err); - } - - return callback(undefined, out); - }, content); -}; +const Saferphore = require('saferphore'); /*:: export type Builder_File_t = {| @@ -184,34 +55,26 @@ export type Builder_t = {| lintFiles: (Builder_Linter_t)=>void, config: Builder_Config_t, tmpFile: (?string)=>string, - compilerType: () => Builder_Compiler_t, - processors: number, + compilerType: () => Builder_Compiler_t |}; export type Builder_BaseConfig_t = {| - systemName: string, - crossCompiling: bool, - gcc: string, - tempDir: string, - optimizeLevel: string, - logLevel: string, - buildDir?: string, + systemName?: ?string, + gcc?: ?string, + buildDir?: ?string, |}; export type Builder_Config_t = { systemName: string, - crossCompiling: bool, gcc: string, buildDir: string, - tempDir: string, - optimizeLevel: string, - logLevel: string, includeDirs: string[], cflags: string[], ldflags: string[], libs: string[], - version: string, + jobs: number, fileCflags: {[string]: string[]}, } & {[string]:any}; import type { Nthen_WaitFor_t } from 'nthen'; +import type { Saferphore_t } from 'saferphore'; export type Builder_Stage_t = (Builder_t, Nthen_WaitFor_t)=>void; export type Builder_CompileJob_t = { cFile: string, outputFile: ?string }; export type Builder_PreCtx_t = { @@ -228,12 +91,108 @@ export type Builder_PreCtx_t = { tests: Array<(Builder_TestRunnerCb_t)=>void>, toCompile: { [string]: Builder_File_t }, config: Builder_Config_t, + sema: Saferphore_t, }; export type Builder_Ctx_t = Builder_PreCtx_t & { builder: Builder_t, state: Builder_State_t, }; */ + +const error = function (message) /*:Error*/ { + try { + throw new Error(message); + } catch (e) { + return e; + } +}; + +const expandArgs = function (args) { + const out = []; + for (let i = 0; i < args.length; i++) { + if (typeof(args[i]) === 'object') { + if (Array.isArray(args[i])) { + out.push.apply(out, expandArgs(args[i])); + } else { + throw new Error("object in arguments [" + args.join() + "]"); + } + } else { + out.push(args[i]); + } + } + return out; +}; + +const compiler = function ( + ctx /*:Builder_Ctx_t*/, + args /*:string[]*/, + callback /*:(number, string, string)=>bool|void*/, + content /*:string*/ +) { + let stop = false; + args = expandArgs(args); + ctx.sema.take(function (returnAfter) { + if (stop) { + return void returnAfter(function (ret) { + callback(1, '', 'interrupted'); + }); + } + if (process.env.VERBOSE) { + console.log(ctx.config.gcc + ' ' + args.join(' ')); + } + const gcc = Spawn(ctx.config.gcc, args); + let err = ''; + let out = ''; + + gcc.stdout.on('data', function (dat) { out += dat.toString(); }); + gcc.stderr.on('data', function (dat) { err += dat.toString(); }); + gcc.on('close', returnAfter(function (ret) { + if (callback(ret, out, err)) { stop = true; } + })); + + gcc.on('error', function (err) { + if (err.code === 'ENOENT') { + console.error('\x1b[1;31mError: ' + ctx.config.gcc + ' is required!\x1b[0m'); + } else { + console.error( + '\x1b[1;31mFail run ' + process.cwd() + ': ' + ctx.config.gcc + ' ' + + args.join(' ') + '\x1b[0m' + ); + console.error('Message:' + err); + } + + // handle the error safely + console.log(args); + }); + + if (content) { + gcc.stdin.write(content, function (err) { + if (err) { throw err; } + gcc.stdin.end(); + }); + } + }); +}; + +const cc = function ( + ctx /*:Builder_Ctx_t*/, + args /*:string[]*/, + callback /*:(?Error, ?string)=>bool|void*/, + content /*:string*/ +) { + compiler(ctx, args, function (ret, out, err) { + if (ret) { + return callback(error("gcc " + args.map(String).join(' ') + "\n\n" + err)); + } + + if (err !== '') { + //process.stdout.write(err); + } + + return callback(undefined, out); + }, content); +}; + const getStatePrototype = function () /*:Builder_State_t*/ { return { rebuildIfChanges: [], @@ -253,7 +212,7 @@ const getStatePrototype = function () /*:Builder_State_t*/ { const tmpFile = function (ctx /*:Builder_Ctx_t*/, name) { name = name || ''; - return ctx.config.tempDir + '/jsmake-' + name + Crypto.pseudoRandomBytes(10).toString('hex'); + return ctx.config.buildDir + '/tmp/' + name + Crypto.pseudoRandomBytes(10).toString('hex'); }; const finalizeCtx = function ( @@ -264,7 +223,7 @@ const finalizeCtx = function ( ctx.state = state; ctx.builder = (Object.freeze({ cc: function (args, callback) { - compiler(ctx.builder.config.gcc, args, callback, ''); + compiler(ctx, args, callback, ''); }, buildExecutable: function (cFile, outputFile) { @@ -293,8 +252,6 @@ const finalizeCtx = function ( compilerType: () => JSON.parse(JSON.stringify(ctx.state.compilerType)), - // Concurrency... - processors: PROCESSORS }) /*:Builder_t*/); return ctx; }; @@ -500,7 +457,7 @@ const preprocessFile = function (cFile, ctx, callback) nThen((w) => { //debug("CPP"); - cc(ctx.config.gcc, ['-E', ...cflags, cFile], w(function (err, output) { + cc(ctx, ['-E', ...cflags, cFile], w(function (err, output) { if (err) { throw err; } fileContent = output; return false; @@ -635,25 +592,12 @@ const makeTime = function () { const link = function (cFile, callback, ctx /*:Builder_Ctx_t*/) { const state = ctx.state; - let tempDir; - const temp = getTempExe(ctx, cFile); - - nThen(function (waitFor) { - - tempDir = tmpFile(ctx); - Fs.mkdir(tempDir, {}, waitFor(function (err) { - if (err) { throw err; } - })); - // TODO delete all other tmp files - - }).nThen(function (waitFor) { - + nThen((waitFor) => { const linkOrder = getLinkOrder(cFile, state.cFiles); for (let i = 0; i < linkOrder.length; i++) { linkOrder[i] = getOFile(ctx, linkOrder[i]); } - const fileObj = state.cFiles[cFile]; const ldArgs = [] .concat(ctx.config.ldflags) @@ -662,37 +606,11 @@ const link = function (cFile, callback, ctx /*:Builder_Ctx_t*/) { .concat(linkOrder) .concat(ctx.config.libs); debug('\x1b[1;31mLinking C executable ' + cFile + '\x1b[0m'); - - cc(ctx.config.gcc, ldArgs, waitFor(function (err, ret) { + cc(ctx, ldArgs, waitFor(function (err, ret) { if (err) { throw err; } return false; }), ''); - - }).nThen(function (waitFor) { - - Fs.readdir(tempDir, waitFor(function (err, files) { - if (err) { throw err; } - - files.forEach(function (file) { - Fs.unlink(tempDir + '/' + file, waitFor(function (err) { - if (err) { throw err; } - })); - }); - })); - - }).nThen(function (waitFor) { - - Fs.rmdir(tempDir, waitFor(function (err) { - if (err) { throw err; } - })); - - }).nThen(function (waitFor) { - - if (callback) { - callback(); - } - - }); + }).nThen((_) => callback()); }; const compile = function (ctx, cFile, done) { @@ -700,7 +618,7 @@ const compile = function (ctx, cFile, done) { const file = ctx.state.cFiles[cFile]; const oFile = getOFile(ctx, cFile); const iFile = getIFile(ctx, cFile); - cc(ctx.config.gcc, ['-c', '-x', 'cpp-output', '-o', oFile, ...file.cflags, iFile], (err) => { + cc(ctx, ['-c', '-x', 'cpp-output', '-o', oFile, ...file.cflags, iFile], (err) => { done(err); return typeof(err) !== 'undefined'; }, ''); @@ -753,7 +671,7 @@ const probeCompiler = function (ctx /*:Builder_Ctx_t*/, callback) { isGCC: false, version: '' }; - compiler(ctx.config.gcc, ['-v'], waitFor(function (ret, out, err) { + compiler(ctx, ['-v'], waitFor(function (ret, out, err) { // TODO(cjd): afl-clang-fast errors when called with -v //if (ret !== 0) { throw new Error("Failed to probe compiler ret[" + ret + "]\n" + err); } if (/Apple LLVM version /.test(err)) { @@ -788,7 +706,7 @@ const probeCompiler = function (ctx /*:Builder_Ctx_t*/, callback) { compilerType.isGCC = true; compilerType.version = err.match(/gcc version ([^ ]+) /)[1]; } - console.log(JSON.stringify(compilerType)); + //console.log(JSON.stringify(compilerType)); }), ''); }).nThen(callback); }; @@ -804,6 +722,34 @@ const deepFreeze = (obj) => { } }; +const sweep = (path, done) => { + let files = []; + nThen((w) => { + Fs.readdir(path, w((err, fls) => { + if (err) { throw err; } + files = fls; + })); + }).nThen((w) => { + files.forEach((f) => { + const file = path + '/' + f; + Fs.stat(file, w((err, st) => { + if (err) { throw err; } + if (st.isDirectory()) { + sweep(file, w(() => { + Fs.rmdir(file, w((err) => { + if (err) { throw err; } + })); + })); + } else { + Fs.unlink(file, w((err) => { + if (err) { throw err; } + })); + } + })); + }); + }).nThen((_) => done()); +}; + module.exports.configure = function ( params /*:Builder_BaseConfig_t*/, configFunc /*:(Builder_t, Nthen_WaitFor_t)=>void*/ @@ -813,11 +759,27 @@ module.exports.configure = function ( const time = makeTime(); time(); - if (typeof(params.systemName) !== 'string') { - throw new Error("system not specified"); + const systemName = params.systemName || process.platform; + const buildDir = params.buildDir || 'build_' + systemName; + + let gcc; + if (params.gcc) { + gcc = params.gcc; + } else if (systemName === 'openbsd') { + gcc = 'egcc'; + } else if (systemName === 'freebsd') { + gcc = 'clang'; + } else { + gcc = 'gcc'; } - const buildDir = params.buildDir = params.buildDir || 'build_' + params.systemName; + // Since many of the compile operations are short, the best + // performance seems to be when running 1.25x the number of jobs as + // cpu cores. On BSD and iphone systems, os.cpus() is not reliable so + // if it returns undefined let's just assume 1 + // workaround, nodejs seems to be broken on openbsd (undefined result after second call) + const cpus = Os.cpus(); + const jobs = Math.floor((typeof cpus === 'undefined' ? 1 : cpus.length) * 1.25); const pctx /*:Builder_PreCtx_t*/ = { buildStage: (_x,_y)=>{}, @@ -832,15 +794,12 @@ module.exports.configure = function ( executables: [], tests: [], toCompile: {}, + sema: Saferphore.create(1), config: { - crossCompiling: params.crossCompiling, buildDir, - gcc: params.gcc, - logLevel: params.logLevel, - optimizeLevel: params.optimizeLevel, - systemName: params.systemName, - tempDir: params.tempDir, + gcc, + systemName, version: '', includeDirs: ['.'], @@ -848,6 +807,7 @@ module.exports.configure = function ( ldflags: [], libs: [], fileCflags: {}, + jobs, }, }; let state = getStatePrototype(); @@ -865,6 +825,18 @@ module.exports.configure = function ( })); })); + }).nThen(function (waitFor) { + + Fs.exists(buildDir + '/tmp', waitFor(function (exists) { + if (exists) { + sweep(buildDir + '/tmp', waitFor()); + } else { + Fs.mkdir(buildDir + '/tmp', {}, waitFor(function (err) { + if (err) { throw err; } + })); + } + })); + }).nThen(function (waitFor) { // read out the state if it exists @@ -905,19 +877,21 @@ module.exports.configure = function ( //if (!ctx.builder) { throw new Error(); } configFunc(ctx.builder, waitFor); - }).nThen(function (waitFor) { + }).nThen(function (_) { + ctx.sema = Saferphore.create(ctx.config.jobs); - if (!ctx.config.version) { - GetVersion(waitFor(function(err, data) { - if (err === null) { - ctx.config.version = ('' + data).replace(/(\r\n|\n|\r)/gm, ""); - } else { - ctx.config.version = 'unknown'; - } - })); + if (ctx.config.systemName !== systemName) { + throw new Error("systemName cannot be changed in configure phase " + + "it must be specified in the initial configuration " + + `initial systemName = ${systemName}, changed to ${ctx.config.systemName}`); + } + + if (ctx.config.gcc !== gcc) { + throw new Error("gcc cannot be changed in configure phase " + + "it must be specified in the initial configuration " + + `initial gcc = ${gcc}, changed to ${ctx.config.gcc}`); } - }).nThen(function (_) { deepFreeze(ctx.config); debug("Configure " + time() + "ms"); @@ -1070,7 +1044,6 @@ const postConfigure = (ctx /*:Builder_Ctx_t*/, time) => { deepFreeze(state); })); }).nThen(function (w) { - Object.keys(ctx.toCompile).forEach((cFile) => { compile(ctx, cFile, w((err) => { if (err) { @@ -1105,7 +1078,7 @@ const postConfigure = (ctx /*:Builder_Ctx_t*/, time) => { debug("Checking codestyle"); - const sema = Semaphore.create(64); + const sema = Saferphore.create(64); Object.keys(ctx.toCompile).forEach(function (cFile) { sema.take(waitFor(function (returnAfter) { @@ -1177,5 +1150,6 @@ const postConfigure = (ctx /*:Builder_Ctx_t*/, time) => { ctx.completeStage(ctx.builder, waitFor); + sweep(ctx.config.buildDir + '/tmp', waitFor()); }); }; diff --git a/node_build/make.js b/node_build/make.js index 0dfc5e86..e14ce025 100644 --- a/node_build/make.js +++ b/node_build/make.js @@ -19,40 +19,24 @@ var nThen = require('nthen'); var Codestyle = require('./Codestyle'); var Cp = require('./Cp'); var Spawn = require('child_process').spawn; -var Os = require('os'); var FindPython = require('./FindPython'); -var CanCompile = require('./CanCompile'); var Builder = require('./builder'); var TestRunner = require('./TestRunner'); const CjdnsTest = require('./CjdnsTest'); +const GetVersion = require('./GetVersion'); -// ['linux','darwin','sunos','win32','freebsd','openbsd','netbsd'] -var SYSTEM = process.env['SYSTEM'] || process.platform; -var GCC = process.env['CC']; var CFLAGS = process.env['CFLAGS']; var LDFLAGS = process.env['LDFLAGS']; - var NO_MARCH_FLAG = ['arm', 'ppc', 'ppc64']; -if (GCC) { - // Already specified. -} else if (SYSTEM === 'openbsd') { - GCC = 'egcc'; -} else if (SYSTEM === 'freebsd') { - GCC = 'clang'; -} else { - GCC = 'gcc'; -} - Builder.configure({ - systemName: SYSTEM, - crossCompiling: process.env['CROSS'] !== undefined, - gcc: GCC, - tempDir: process.env['CJDNS_BUILD_TMPDIR'] || '/tmp', - optimizeLevel: '-O3', - logLevel: process.env['Log_LEVEL'] || 'DEBUG' + systemName: process.env['SYSTEM'] || process.platform, + gcc: process.env['CC'], }, function (builder, waitFor) { + builder.config.crossCompiling = process.env['CROSS'] !== undefined; + let optimizeLevel = '-O3'; + builder.config.cflags.push( '-std=c99', '-Wall', @@ -62,11 +46,10 @@ Builder.configure({ '-Wmissing-prototypes', '-pedantic', '-D', builder.config.systemName + '=1', - '-D', 'CJD_PACKAGE_VERSION="' + builder.config.version + '"', '-Wno-unused-parameter', '-fomit-frame-pointer', - '-D', 'Log_' + builder.config.logLevel, + '-D', 'Log_' + (process.env['Log_LEVEL'] || 'DEBUG'), '-g', @@ -164,18 +147,17 @@ Builder.configure({ var cflags = CFLAGS.split(' '); cflags.forEach(function(flag) { if (/^\-O[^02s]$/.test(flag)) { - console.log("Skipping " + flag + ", assuming " + - builder.config.optimizeLevel + " instead."); + console.log("Skipping " + flag + ", assuming " + optimizeLevel + " instead."); } else if (/^\-O[02s]$/.test(flag)) { - builder.config.optimizeLevel = flag; + optimizeLevel = flag; } else { [].push.apply(builder.config.cflags, cflags); } }); } - builder.config.cflags.push(builder.config.optimizeLevel); - if (!/^\-O0$/.test(builder.config.optimizeLevel)) { + builder.config.cflags.push(optimizeLevel); + if (!/^\-O0$/.test(optimizeLevel)) { builder.config.cflags.push('-D_FORTIFY_SOURCE=2'); } @@ -189,25 +171,6 @@ Builder.configure({ builder.config.cflags.push('-Dandroid=1'); } - if (process.env.NO_LTO) { - console.log("Link time optimization disabled"); - } else { - CanCompile.check(builder, - 'int main() { return 0; }\n', - [ builder.config.cflags, '-flto', '-x', 'c' ], - waitFor(function (err, can) { - if (can) { - console.log("Compiler supports link time optimization"); - builder.config.ldflags.push( - '-flto', - builder.config.optimizeLevel - ); - } else { - console.log("Link time optimization not supported [" + err + "]"); - } - })); - } - var uclibc = process.env['UCLIBC'] == '1'; var libssp; switch (process.env['SSP_SUPPORT']) { @@ -257,6 +220,19 @@ Builder.configure({ CjdnsTest.generate(builder, process.env['SUBNODE'] !== '', waitFor()); } + nThen((w) => { + if (builder.config.version) { return; } + GetVersion(w(function(err, data) { + if (!err) { + builder.config.version = ('' + data).replace(/(\r\n|\n|\r)/gm, ""); + } else { + builder.config.version = 'unknown'; + } + })); + }).nThen((w) => { + builder.config.cflags.push('-D', 'CJD_PACKAGE_VERSION="' + builder.config.version + '"'); + }).nThen(waitFor()); + var dependencyDir = builder.config.buildDir + '/dependencies'; var libuvLib = dependencyDir + '/libuv/out/Release/libuv.a'; if (['win32', 'netbsd'].indexOf(builder.config.systemName) >= 0) {//this might be needed for other BSDs @@ -295,9 +271,9 @@ Builder.configure({ args.unshift('-fPIC'); } - args.unshift(builder.config.optimizeLevel, '-fomit-frame-pointer'); + args.unshift(optimizeLevel, '-fomit-frame-pointer'); - if (!/^\-O0$/.test(builder.config.optimizeLevel)) { + if (!/^\-O0$/.test(optimizeLevel)) { args.unshift('-D_FORTIFY_SOURCE=2'); } @@ -408,16 +384,16 @@ Builder.configure({ }); gyp.on('close', waitFor(function () { var args = [ - '-j', ''+builder.processors, + '-j', ''+builder.config.jobs, '-C', 'out', 'BUILDTYPE=Release', 'CC=' + builder.config.gcc, 'CXX=' + builder.config.gcc, 'V=1' ]; - var cflags = [builder.config.optimizeLevel, '-DNO_EMFILE_TRICK=1']; + var cflags = [optimizeLevel, '-DNO_EMFILE_TRICK=1']; - if (!/^\-O0$/.test(builder.config.optimizeLevel)) { + if (!/^\-O0$/.test(optimizeLevel)) { cflags.push('-D_FORTIFY_SOURCE=2'); } diff --git a/node_modules/nthen/package.json b/node_modules/nthen/package.json index 9db0ca0e..b1eface6 100644 --- a/node_modules/nthen/package.json +++ b/node_modules/nthen/package.json @@ -1,4 +1,10 @@ { + "_args": [ + [ + "nthen@0.2.1", + "/Users/user/wrk/cjdns" + ] + ], "_from": "nthen@0.2.1", "_id": "nthen@0.2.1", "_inBundle": false, @@ -16,12 +22,10 @@ "fetchSpec": "0.2.1" }, "_requiredBy": [ - "#USER", "/" ], "_resolved": "https://registry.npmjs.org/nthen/-/nthen-0.2.1.tgz", - "_shasum": "cf665cada4afd773f2443d77c5d77e79a965531f", - "_spec": "nthen@0.2.1", + "_spec": "0.2.1", "_where": "/Users/user/wrk/cjdns", "author": { "name": "Caleb James DeLisle" @@ -29,8 +33,6 @@ "bugs": { "url": "https://github.com/cjdelisle/nthen/issues" }, - "bundleDependencies": false, - "deprecated": false, "description": "Simple intuitive asynchronous control flow.", "devDependencies": { "flow-bin": "^0.106.2", diff --git a/node_modules/saferphore/.flowconfig b/node_modules/saferphore/.flowconfig new file mode 100644 index 00000000..4a58bdcd --- /dev/null +++ b/node_modules/saferphore/.flowconfig @@ -0,0 +1,7 @@ +[ignore] + +[include] + +[libs] + +[options] diff --git a/node_modules/saferphore/.jshintignore b/node_modules/saferphore/.jshintignore new file mode 100644 index 00000000..c2658d7d --- /dev/null +++ b/node_modules/saferphore/.jshintignore @@ -0,0 +1 @@ +node_modules/ diff --git a/node_modules/saferphore/.jshintrc b/node_modules/saferphore/.jshintrc new file mode 100644 index 00000000..5998ee31 --- /dev/null +++ b/node_modules/saferphore/.jshintrc @@ -0,0 +1,16 @@ +{ + "laxcomma": true, + "laxbreak": true, + "node": true, + "browser": true, + "sub": true, + "curly": true, + "eqeqeq": true, + "iterator": true, + "latedef": true, + "nocomma": true, + "notypeof": true, + "shadow": false, + "undef": true, + "unused": false +} diff --git a/node_modules/saferphore/.travis.yml b/node_modules/saferphore/.travis.yml new file mode 100644 index 00000000..aff2492d --- /dev/null +++ b/node_modules/saferphore/.travis.yml @@ -0,0 +1,12 @@ +language: node_js + +node_js: + - '6' + - '5' + - '4' + - '0.12' + +script: + - npm run-script test + - npm run-script lint + - npm run-script flow diff --git a/node_modules/saferphore/index.js b/node_modules/saferphore/index.js new file mode 100644 index 00000000..1006bf3d --- /dev/null +++ b/node_modules/saferphore/index.js @@ -0,0 +1,50 @@ +/*@flow*/ +/*:: +export type Saferphore_ReturnAfter_t = ((...any)=>void)=>(...any)=>void; +export type Saferphore_t = { + take: ((Saferphore_ReturnAfter_t)=>void)=>void, +}; +*/ +;(function () { +"use strict"; +var create = function (resourceCount /*:number*/) /*:Saferphore_t*/ { + var queue = []; + var check; + var mkRa = function () /*:Saferphore_ReturnAfter_t*/ { + var outerCalled = 0; + return function (func) { + if (outerCalled++) { throw new Error("returnAfter() called multiple times"); } + var called = 0; + return function () { + if (called++) { + throw new Error("returnAfter wrapped callback called multiple times"); + } + if (func) { func.apply(null, arguments); } + resourceCount++; + check(); + }; + }; + }; + check = function () { + if (resourceCount < 0) { throw new Error("(resourceCount < 0) should never happen"); } + if (resourceCount === 0 || queue.length === 0) { return; } + resourceCount--; + queue.shift()(mkRa()); + }; + return { + take: function (func) { + queue.push(func); + check(); + } + }; +}; +if (typeof(window) === 'object') { + if (window.define && window.define.amd) { + window.define({ create: create }); + } else { + window.Saferphore = { create: create }; + } +} else if (typeof(module) === 'object' && module.exports) { + module.exports.create = create; +} +}()); diff --git a/node_modules/saferphore/package.json b/node_modules/saferphore/package.json new file mode 100644 index 00000000..b92d1be7 --- /dev/null +++ b/node_modules/saferphore/package.json @@ -0,0 +1,51 @@ +{ + "_args": [ + [ + "saferphore@0.0.2", + "/Users/user/wrk/cjdns" + ] + ], + "_from": "saferphore@0.0.2", + "_id": "saferphore@0.0.2", + "_inBundle": false, + "_integrity": "sha512-gjdCGXxrSKi1oSWJH0vx99WtB2wkjbXPQf6ALHEskLo0e4Vgd57txhracaeLlPt2r4rUiJBe+thriuxS85q7JA==", + "_location": "/saferphore", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "saferphore@0.0.2", + "name": "saferphore", + "escapedName": "saferphore", + "rawSpec": "0.0.2", + "saveSpec": null, + "fetchSpec": "0.0.2" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/saferphore/-/saferphore-0.0.2.tgz", + "_spec": "0.0.2", + "_where": "/Users/user/wrk/cjdns", + "bugs": { + "url": "https://github.com/cjdelisle/saferphore/issues" + }, + "description": "Node Semaphore which has protection against double-returning", + "devDependencies": { + "flow-bin": "^0.115.0", + "jshint": "~2.9.1" + }, + "homepage": "https://github.com/cjdelisle/saferphore#readme", + "license": "MIT", + "name": "saferphore", + "repository": { + "type": "git", + "url": "git+https://github.com/cjdelisle/saferphore.git" + }, + "scripts": { + "flow": "flow", + "lint": "jshint --verbose --config .jshintrc --exclude-path .jshintignore .", + "test": "node test" + }, + "version": "0.0.2" +} diff --git a/node_modules/saferphore/readme.md b/node_modules/saferphore/readme.md new file mode 100644 index 00000000..068b035d --- /dev/null +++ b/node_modules/saferphore/readme.md @@ -0,0 +1,30 @@ +# Saferphore - Node semaphore with protection against double-returning + + # node + npm install --save saferphore + + # Browser + bower install --save saferphore + + +```javascript +const Saferphore = require('saferphore'); + +var sem = Saferphore.create(4); +for (var i = 0; i < 10000; i++) { + sem.take(function (returnAfter) { + Fs.writeFile('file_' + i, 'hi', returnAfter(function (err) { + if (err) { throw err; } + }); + }); +} +``` + +You can only return what you take, if you try to call returnAfter() twice then it will throw a +clear error instead of creating a leaky semaphore. + +```javascript +sem.take(function (returnAfter) { + stream.on('data', returnAfter(processData)); // BZZZZZZZT error when it's called more than once +}); +``` diff --git a/node_modules/saferphore/test.js b/node_modules/saferphore/test.js new file mode 100644 index 00000000..860ee4c9 --- /dev/null +++ b/node_modules/saferphore/test.js @@ -0,0 +1,54 @@ +'use strict'; +var Saferphore = require('./index'); +var assert = function (x) { if (!x) { throw new Error(); } }; + +var basicTest = function () { + var sem = Saferphore.create(4); + var out = []; + (new Array(10)).join().split(',').forEach(function (x,y) { + sem.take(function (returnAfter) { + out.push(y); + setTimeout(returnAfter(function () { + if (out.length === 10) { + if (out.join() !== "0,1,2,3,4,5,6,7,8,9") { throw new Error(); } + } + })); + }); + }); + if (out.join() !== "0,1,2,3") { + throw new Error(out.join()); + } +}; + +var doubleCallTest = function () { + var sem = Saferphore.create(4); + var catcher = setTimeout(function () { + throw new Error(); + }, 1000); + sem.take(function (returnAfter) { + setTimeout(returnAfter(function () { + setTimeout(function () { + clearTimeout(catcher); + try { returnAfter()(); } catch (e) { return; } + throw new Error(); + }); + })); + }); +}; + +var doubleCallbackTest = function () { + var sem = Saferphore.create(4); + var catcher = setTimeout(function () { + throw new Error(); + }, 1000); + sem.take(function (returnAfter) { + var wrapped = returnAfter(); + wrapped(); + try { wrapped(); } catch (e) { clearTimeout(catcher); return; } + throw new Error(); + }); +}; + +basicTest(); +doubleCallTest(); +doubleCallbackTest(); diff --git a/package-lock.json b/package-lock.json index 8a1b4c12..2b69fc7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,233 +1,18 @@ { "name": "cjdns", - "version": "0.17.2", + "version": "0.17.3", "lockfileVersion": 1, "requires": true, "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", - "requires": { - "exit": "0.1.2", - "glob": "^7.1.1" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "requires": { - "date-now": "^0.1.4" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.2.tgz", - "integrity": "sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA==" - }, - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" - } - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "requires": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "jshint": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.12.0.tgz", - "integrity": "sha512-TwuuaUDmra0JMkuqvqy+WGo2xGHSNjv1BA1nTIgtH2K5z1jHuAEeAgp7laaR+hLRmajRjcrM71+vByBDanCyYA==", - "requires": { - "cli": "~1.0.0", - "console-browserify": "1.1.x", - "exit": "0.1.x", - "htmlparser2": "3.8.x", - "lodash": "~4.17.19", - "minimatch": "~3.0.2", - "shelljs": "0.3.x", - "strip-json-comments": "1.0.x" - } - }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, "nthen": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/nthen/-/nthen-0.2.1.tgz", "integrity": "sha512-QW3p6gxOaHHLFM+2HcytugGUiji4pNpLkNAtPQi2gX2+hSmndnNSDYbDSUdIEy7vGJ+LkocZ3EvgwxeKfToZGg==" }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "saferphore": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/saferphore/-/saferphore-0.0.2.tgz", + "integrity": "sha512-gjdCGXxrSKi1oSWJH0vx99WtB2wkjbXPQf6ALHEskLo0e4Vgd57txhracaeLlPt2r4rUiJBe+thriuxS85q7JA==" } } } diff --git a/package.json b/package.json index 60cdf977..529c59ef 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "cjdns", - "version": "0.17.2", + "version": "0.17.3", "dependencies": { - "jshint": "^2.12.0", - "nthen": "^0.2.1" + "nthen": "^0.2.1", + "saferphore": "0.0.2" } } diff --git a/tools/lib/Semaphore.js b/tools/lib/Semaphore.js index 7e93564f..6eb14e30 100644 --- a/tools/lib/Semaphore.js +++ b/tools/lib/Semaphore.js @@ -1,24 +1,51 @@ -module.exports.create = function (resourceCount) { - var queue = []; - var returnAfter = function (func) { - var called = 0; - return function () { - if (called++) { throw new Error("Function called multiple times"); } - if (func) { func.apply(null, arguments); } - resourceCount++; - check(); +/*@flow*/ +/*:: +export type Saferphore_ReturnAfter_t = ((...any)=>void)=>(...any)=>void; +export type Saferphore_t = { + take: ((Saferphore_ReturnAfter_t)=>void)=>void, +}; +*/ +;(function () { + "use strict"; + var create = function (resourceCount /*:number*/) /*:Saferphore_t*/ { + var queue = []; + var check; + var mkRa = function () /*:Saferphore_ReturnAfter_t*/ { + var outerCalled = 0; + return function (func) { + if (outerCalled++) { throw new Error("returnAfter() called multiple times"); } + var called = 0; + return function () { + if (called++) { + throw new Error("returnAfter wrapped callback called multiple times"); + } + if (func) { func.apply(null, arguments); } + resourceCount++; + check(); + }; + }; + }; + check = function () { + if (resourceCount < 0) { throw new Error("(resourceCount < 0) should never happen"); } + if (resourceCount === 0 || queue.length === 0) { return; } + resourceCount--; + queue.shift()(mkRa()); + }; + return { + take: function (func) { + queue.push(func); + check(); + } }; }; - var check = function () { - if (resourceCount < 0) { throw new Error("(resourceCount < 0) should never happen"); } - if (resourceCount === 0 || queue.length === 0) { return; } - resourceCount--; - queue.shift()(returnAfter); - }; - return { - take: function (func) { - queue.push(func); - check(); + if (typeof(window) === 'object') { + if (window.define && window.define.amd) { + window.define({ create: create }); + } else { + window.Saferphore = { create: create }; } - }; -}; + } else if (typeof(module) === 'object' && module.exports) { + module.exports.create = create; + } + }()); + \ No newline at end of file diff --git a/tools/lib/cjdnsadmin/cjdnsadmin.js b/tools/lib/cjdnsadmin/cjdnsadmin.js index 07898558..3a391966 100644 --- a/tools/lib/cjdnsadmin/cjdnsadmin.js +++ b/tools/lib/cjdnsadmin/cjdnsadmin.js @@ -18,7 +18,7 @@ var Bencode = require('./bencode'); var Crypto = require('crypto'); var Fs = require('fs'); var nThen = require('nthen'); -var Semaphore = require('../Semaphore.js'); +var Semaphore = require('saferphore'); var TIMEOUT_MILLISECONDS = 10000;