os: add userInfo() method
os.userInfo() calls libuv's uv_os_get_passwd() function. It returns an object containing the current effective user's username, uid, gid, shell, and home directory. On Windows, the uid and gid are -1, and the shell is null. Refs: https://github.com/nodejs/node/issues/5582 PR-URL: https://github.com/nodejs/node/pull/6104 Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
aba035fb27
commit
d6e56fd843
@ -182,5 +182,21 @@ on OS X and `'Windows_NT'` on Windows.
|
||||
|
||||
Returns the system uptime in seconds.
|
||||
|
||||
## os.userInfo([options])
|
||||
|
||||
* `options` {Object}
|
||||
* `encoding` {String} Character encoding used to interpret resulting strings.
|
||||
If `encoding` is set to `'buffer'`, the `username`, `shell`, and `homedir`
|
||||
values will be `Buffer` instances. (Default: 'utf8')
|
||||
|
||||
Returns a subset of the password file entry for the current effective user. The
|
||||
returned object includes the `username`, `uid`, `gid`, `shell`, and `homedir`.
|
||||
On Windows, the `uid` and `gid` fields are `-1`, and `shell` is `null`.
|
||||
|
||||
The value of `homedir` returned by `userInfo()` comes directly from the
|
||||
operating system. This differs from the result of `os.homedir()`, which queries
|
||||
several environment variables for the home directory before falling back to the
|
||||
operating system response.
|
||||
|
||||
[`process.arch`]: process.html#process_process_arch
|
||||
[`process.platform`]: process.html#process_process_platform
|
||||
|
@ -14,6 +14,7 @@ exports.type = binding.getOSType;
|
||||
exports.release = binding.getOSRelease;
|
||||
exports.networkInterfaces = binding.getInterfaceAddresses;
|
||||
exports.homedir = binding.getHomeDirectory;
|
||||
exports.userInfo = binding.getUserInfo;
|
||||
|
||||
|
||||
exports.arch = function() {
|
||||
|
@ -94,6 +94,7 @@ namespace node {
|
||||
V(exchange_string, "exchange") \
|
||||
V(idle_string, "idle") \
|
||||
V(irq_string, "irq") \
|
||||
V(encoding_string, "encoding") \
|
||||
V(enter_string, "enter") \
|
||||
V(env_pairs_string, "envPairs") \
|
||||
V(env_string, "env") \
|
||||
@ -121,6 +122,7 @@ namespace node {
|
||||
V(handle_string, "handle") \
|
||||
V(heap_total_string, "heapTotal") \
|
||||
V(heap_used_string, "heapUsed") \
|
||||
V(homedir_string, "homedir") \
|
||||
V(hostmaster_string, "hostmaster") \
|
||||
V(ignore_string, "ignore") \
|
||||
V(immediate_callback_string, "_immediateCallback") \
|
||||
@ -206,6 +208,7 @@ namespace node {
|
||||
V(service_string, "service") \
|
||||
V(servername_string, "servername") \
|
||||
V(session_id_string, "sessionId") \
|
||||
V(shell_string, "shell") \
|
||||
V(signal_string, "signal") \
|
||||
V(size_string, "size") \
|
||||
V(sni_context_err_string, "Invalid SNI context") \
|
||||
@ -235,6 +238,7 @@ namespace node {
|
||||
V(uid_string, "uid") \
|
||||
V(unknown_string, "<unknown>") \
|
||||
V(user_string, "user") \
|
||||
V(username_string, "username") \
|
||||
V(uv_string, "uv") \
|
||||
V(valid_from_string, "valid_from") \
|
||||
V(valid_to_string, "valid_to") \
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "v8.h"
|
||||
#include "env.h"
|
||||
#include "env-inl.h"
|
||||
#include "string_bytes.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
@ -32,6 +33,7 @@ using v8::Context;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::Integer;
|
||||
using v8::Local;
|
||||
using v8::Null;
|
||||
using v8::Number;
|
||||
using v8::Object;
|
||||
using v8::String;
|
||||
@ -290,6 +292,72 @@ static void GetHomeDirectory(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
|
||||
|
||||
static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
uv_passwd_t pwd;
|
||||
enum encoding encoding;
|
||||
|
||||
if (args[0]->IsObject()) {
|
||||
Local<Object> options = args[0].As<Object>();
|
||||
Local<Value> encoding_opt = options->Get(env->encoding_string());
|
||||
encoding = ParseEncoding(env->isolate(), encoding_opt, UTF8);
|
||||
} else {
|
||||
encoding = UTF8;
|
||||
}
|
||||
|
||||
const int err = uv_os_get_passwd(&pwd);
|
||||
|
||||
if (err) {
|
||||
return env->ThrowUVException(err, "uv_os_get_passwd");
|
||||
}
|
||||
|
||||
Local<Value> uid = Number::New(env->isolate(), pwd.uid);
|
||||
Local<Value> gid = Number::New(env->isolate(), pwd.gid);
|
||||
Local<Value> username = StringBytes::Encode(env->isolate(),
|
||||
pwd.username,
|
||||
encoding);
|
||||
Local<Value> homedir = StringBytes::Encode(env->isolate(),
|
||||
pwd.homedir,
|
||||
encoding);
|
||||
Local<Value> shell;
|
||||
|
||||
if (pwd.shell == NULL)
|
||||
shell = Null(env->isolate());
|
||||
else
|
||||
shell = StringBytes::Encode(env->isolate(), pwd.shell, encoding);
|
||||
|
||||
uv_os_free_passwd(&pwd);
|
||||
|
||||
if (username.IsEmpty()) {
|
||||
return env->ThrowUVException(UV_EINVAL,
|
||||
"uv_os_get_passwd",
|
||||
"Invalid character encoding for username");
|
||||
}
|
||||
|
||||
if (homedir.IsEmpty()) {
|
||||
return env->ThrowUVException(UV_EINVAL,
|
||||
"uv_os_get_passwd",
|
||||
"Invalid character encoding for homedir");
|
||||
}
|
||||
|
||||
if (shell.IsEmpty()) {
|
||||
return env->ThrowUVException(UV_EINVAL,
|
||||
"uv_os_get_passwd",
|
||||
"Invalid character encoding for shell");
|
||||
}
|
||||
|
||||
Local<Object> entry = Object::New(env->isolate());
|
||||
|
||||
entry->Set(env->uid_string(), uid);
|
||||
entry->Set(env->gid_string(), gid);
|
||||
entry->Set(env->username_string(), username);
|
||||
entry->Set(env->homedir_string(), homedir);
|
||||
entry->Set(env->shell_string(), shell);
|
||||
|
||||
args.GetReturnValue().Set(entry);
|
||||
}
|
||||
|
||||
|
||||
void Initialize(Local<Object> target,
|
||||
Local<Value> unused,
|
||||
Local<Context> context) {
|
||||
@ -304,6 +372,7 @@ void Initialize(Local<Object> target,
|
||||
env->SetMethod(target, "getOSRelease", GetOSRelease);
|
||||
env->SetMethod(target, "getInterfaceAddresses", GetInterfaceAddresses);
|
||||
env->SetMethod(target, "getHomeDirectory", GetHomeDirectory);
|
||||
env->SetMethod(target, "getUserInfo", GetUserInfo);
|
||||
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "isBigEndian"),
|
||||
Boolean::New(env->isolate(), IsBigEndian()));
|
||||
}
|
||||
|
@ -125,3 +125,27 @@ if (common.isWindows && process.env.USERPROFILE) {
|
||||
assert.ok(os.homedir().indexOf(path.sep) !== -1);
|
||||
process.env.HOME = home;
|
||||
}
|
||||
|
||||
const pwd = os.userInfo();
|
||||
const pwdBuf = os.userInfo({ encoding: 'buffer' });
|
||||
|
||||
if (common.isWindows) {
|
||||
assert.strictEqual(pwd.uid, -1);
|
||||
assert.strictEqual(pwd.gid, -1);
|
||||
assert.strictEqual(pwd.shell, null);
|
||||
assert.strictEqual(pwdBuf.uid, -1);
|
||||
assert.strictEqual(pwdBuf.gid, -1);
|
||||
assert.strictEqual(pwdBuf.shell, null);
|
||||
} else {
|
||||
assert.strictEqual(typeof pwd.uid, 'number');
|
||||
assert.strictEqual(typeof pwd.gid, 'number');
|
||||
assert.notStrictEqual(pwd.shell.indexOf(path.sep), -1);
|
||||
assert.strictEqual(pwd.uid, pwdBuf.uid);
|
||||
assert.strictEqual(pwd.gid, pwdBuf.gid);
|
||||
assert.strictEqual(pwd.shell, pwdBuf.shell.toString('utf8'));
|
||||
}
|
||||
|
||||
assert.strictEqual(typeof pwd.username, 'string');
|
||||
assert.notStrictEqual(pwd.homedir.indexOf(path.sep), -1);
|
||||
assert.strictEqual(pwd.username, pwdBuf.username.toString('utf8'));
|
||||
assert.strictEqual(pwd.homedir, pwdBuf.homedir.toString('utf8'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user