You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.9 KiB

module.exports = which
which.sync = whichSync
var path = require("path")
, fs
, COLON = process.platform === "win32" ? ";" : ":"
, isExe
try {
fs = require("graceful-fs")
} catch (ex) {
fs = require("fs")
}
if (process.platform == "win32") {
// On windows, there is no good way to check that a file is executable
isExe = function isExe () { return true }
} else {
isExe = function isExe (mod, uid, gid) {
//console.error(mod, uid, gid);
//console.error("isExe?", (mod & 0111).toString(8))
var ret = (mod & 0001)
|| (mod & 0010) && process.getgid && gid === process.getgid()
|| (mod & 0100) && process.getuid && uid === process.getuid()
//console.error("isExe?", ret)
return ret
}
Merge remote-tracking branch 'ry/v0.6' into v0.6-merge Conflicts: ChangeLog Makefile deps/npm/AUTHORS deps/npm/html/api/bin.html deps/npm/html/api/bugs.html deps/npm/html/api/commands.html deps/npm/html/api/config.html deps/npm/html/api/deprecate.html deps/npm/html/api/docs.html deps/npm/html/api/edit.html deps/npm/html/api/explore.html deps/npm/html/api/help-search.html deps/npm/html/api/init.html deps/npm/html/api/install.html deps/npm/html/api/link.html deps/npm/html/api/load.html deps/npm/html/api/ls.html deps/npm/html/api/npm.html deps/npm/html/api/outdated.html deps/npm/html/api/owner.html deps/npm/html/api/pack.html deps/npm/html/api/prefix.html deps/npm/html/api/prune.html deps/npm/html/api/publish.html deps/npm/html/api/rebuild.html deps/npm/html/api/restart.html deps/npm/html/api/root.html deps/npm/html/api/run-script.html deps/npm/html/api/search.html deps/npm/html/api/shrinkwrap.html deps/npm/html/api/start.html deps/npm/html/api/stop.html deps/npm/html/api/submodule.html deps/npm/html/api/tag.html deps/npm/html/api/test.html deps/npm/html/api/uninstall.html deps/npm/html/api/unpublish.html deps/npm/html/api/update.html deps/npm/html/api/version.html deps/npm/html/api/view.html deps/npm/html/api/whoami.html deps/npm/html/doc/README.html deps/npm/html/doc/adduser.html deps/npm/html/doc/bin.html deps/npm/html/doc/bugs.html deps/npm/html/doc/build.html deps/npm/html/doc/bundle.html deps/npm/html/doc/cache.html deps/npm/html/doc/changelog.html deps/npm/html/doc/coding-style.html deps/npm/html/doc/completion.html deps/npm/html/doc/config.html deps/npm/html/doc/deprecate.html deps/npm/html/doc/developers.html deps/npm/html/doc/disputes.html deps/npm/html/doc/docs.html deps/npm/html/doc/edit.html deps/npm/html/doc/explore.html deps/npm/html/doc/faq.html deps/npm/html/doc/folders.html deps/npm/html/doc/help-search.html deps/npm/html/doc/help.html deps/npm/html/doc/index.html deps/npm/html/doc/init.html deps/npm/html/doc/install.html deps/npm/html/doc/json.html deps/npm/html/doc/link.html deps/npm/html/doc/list.html deps/npm/html/doc/npm.html deps/npm/html/doc/outdated.html deps/npm/html/doc/owner.html deps/npm/html/doc/pack.html deps/npm/html/doc/prefix.html deps/npm/html/doc/prune.html deps/npm/html/doc/publish.html deps/npm/html/doc/rebuild.html deps/npm/html/doc/registry.html deps/npm/html/doc/removing-npm.html deps/npm/html/doc/restart.html deps/npm/html/doc/root.html deps/npm/html/doc/run-script.html deps/npm/html/doc/scripts.html deps/npm/html/doc/search.html deps/npm/html/doc/semver.html deps/npm/html/doc/shrinkwrap.html deps/npm/html/doc/star.html deps/npm/html/doc/start.html deps/npm/html/doc/stop.html deps/npm/html/doc/submodule.html deps/npm/html/doc/tag.html deps/npm/html/doc/test.html deps/npm/html/doc/uninstall.html deps/npm/html/doc/unpublish.html deps/npm/html/doc/update.html deps/npm/html/doc/version.html deps/npm/html/doc/view.html deps/npm/html/doc/whoami.html deps/npm/man/man1/npm.1 deps/npm/man/man3/npm.3 deps/npm/package.json doc/api/url.markdown lib/http.js src/node_version.h test/simple/test-fs-sync-fd-leak.js
13 years ago
}
function which (cmd, cb) {
if (isAbsolute(cmd)) return cb(null, cmd)
var pathEnv = (process.env.PATH || "").split(COLON)
, pathExt = [""]
if (process.platform === "win32") {
pathEnv.push(process.cwd())
pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
if (cmd.indexOf(".") !== -1) pathExt.unshift("")
}
//console.error("pathEnv", pathEnv)
;(function F (i, l) {
if (i === l) return cb(new Error("not found: "+cmd))
var p = path.resolve(pathEnv[i], cmd)
;(function E (ii, ll) {
if (ii === ll) return F(i + 1, l)
var ext = pathExt[ii]
//console.error(p + ext)
fs.stat(p + ext, function (er, stat) {
if (!er &&
stat &&
stat.isFile() &&
isExe(stat.mode, stat.uid, stat.gid)) {
//console.error("yes, exe!", p + ext)
return cb(null, p + ext)
}
return E(ii + 1, ll)
})
})(0, pathExt.length)
})(0, pathEnv.length)
}
function whichSync (cmd) {
if (isAbsolute(cmd)) return cmd
var pathEnv = (process.env.PATH || "").split(COLON)
, pathExt = [""]
if (process.platform === "win32") {
pathEnv.push(process.cwd())
pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
if (cmd.indexOf(".") !== -1) pathExt.unshift("")
}
for (var i = 0, l = pathEnv.length; i < l; i ++) {
var p = path.join(pathEnv[i], cmd)
for (var j = 0, ll = pathExt.length; j < ll; j ++) {
var cur = p + pathExt[j]
var stat
try { stat = fs.statSync(cur) } catch (ex) {}
if (stat &&
stat.isFile() &&
isExe(stat.mode, stat.uid, stat.gid)) return cur
}
}
throw new Error("not found: "+cmd)
}
var isAbsolute = process.platform === "win32" ? absWin : absUnix
function absWin (p) {
if (absUnix(p)) return true
// pull off the device/UNC bit from a windows path.
// from node's lib/path.js
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
, result = splitDeviceRe.exec(p)
, device = result[1] || ''
, isUnc = device && device.charAt(1) !== ':'
, isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
return isAbsolute
}
function absUnix (p) {
return p.charAt(0) === "/" || p === ""
}