Skip to content

Commit

Permalink
os: add homedir()
Browse files Browse the repository at this point in the history
os.homedir() calls libuv's uv_os_homedir() to retrieve the current
user's home directory.

PR-URL: #1791
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
  • Loading branch information
cjihrig committed Jun 6, 2015
1 parent 02c3450 commit 6e78e5f
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 1 deletion.
4 changes: 4 additions & 0 deletions doc/api/os.markdown
Expand Up @@ -10,6 +10,10 @@ Use `require('os')` to access this module.

Returns the operating system's default directory for temporary files.

## os.homedir()

Returns the home directory of the current user.

## os.endianness()

Returns the endianness of the CPU. Possible values are `'BE'` for big endian
Expand Down
2 changes: 2 additions & 0 deletions lib/os.js
Expand Up @@ -13,6 +13,8 @@ exports.cpus = binding.getCPUs;
exports.type = binding.getOSType;
exports.release = binding.getOSRelease;
exports.networkInterfaces = binding.getInterfaceAddresses;
exports.homedir = binding.getHomeDirectory;


exports.arch = function() {
return process.arch;
Expand Down
21 changes: 21 additions & 0 deletions src/node_os.cc
Expand Up @@ -11,6 +11,7 @@
#endif // __MINGW32__

#ifdef __POSIX__
# include <limits.h> // PATH_MAX on Solaris.
# include <netdb.h> // MAXHOSTNAMELEN on Solaris.
# include <unistd.h> // gethostname, sysconf
# include <sys/param.h> // MAXHOSTNAMELEN on Linux and the BSDs.
Expand Down Expand Up @@ -271,6 +272,25 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
}


static void GetHomeDirectory(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
char buf[PATH_MAX];

size_t len = sizeof(buf);
const int err = uv_os_homedir(buf, &len);

if (err) {
return env->ThrowUVException(err, "uv_os_homedir");
}

Local<String> home = String::NewFromUtf8(env->isolate(),
buf,
String::kNormalString,
len);
args.GetReturnValue().Set(home);
}


void Initialize(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context) {
Expand All @@ -284,6 +304,7 @@ void Initialize(Handle<Object> target,
env->SetMethod(target, "getOSType", GetOSType);
env->SetMethod(target, "getOSRelease", GetOSRelease);
env->SetMethod(target, "getInterfaceAddresses", GetInterfaceAddresses);
env->SetMethod(target, "getHomeDirectory", GetHomeDirectory);
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "isBigEndian"),
Boolean::New(env->isolate(), IsBigEndian()));
}
Expand Down
1 change: 1 addition & 0 deletions test/common.js
Expand Up @@ -10,6 +10,7 @@ exports.fixturesDir = path.join(exports.testDir, 'fixtures');
exports.libDir = path.join(exports.testDir, '../lib');
exports.tmpDirName = 'tmp';
exports.PORT = +process.env.NODE_COMMON_PORT || 12346;
exports.isWindows = process.platform === 'win32';

if (process.env.TEST_THREAD_ID) {
// Distribute ports in parallel tests
Expand Down
30 changes: 30 additions & 0 deletions test/parallel/test-os-homedir-no-envvar.js
@@ -0,0 +1,30 @@
'use strict';
var common = require('../common');
var assert = require('assert');
var cp = require('child_process');
var os = require('os');
var path = require('path');


if (process.argv[2] === 'child') {
if (common.isWindows)
assert.equal(process.env.USERPROFILE, undefined);
else
assert.equal(process.env.HOME, undefined);

var home = os.homedir();

assert.ok(typeof home === 'string');
assert.ok(home.indexOf(path.sep) !== -1);
} else {
if (common.isWindows)
delete process.env.USERPROFILE;
else
delete process.env.HOME;

var child = cp.spawnSync(process.execPath, [__filename, 'child'], {
env: process.env
});

assert.equal(child.status, 0);
}
22 changes: 21 additions & 1 deletion test/parallel/test-os.js
Expand Up @@ -2,12 +2,13 @@
var common = require('../common');
var assert = require('assert');
var os = require('os');
var path = require('path');


process.env.TMPDIR = '/tmpdir';
process.env.TMP = '/tmp';
process.env.TEMP = '/temp';
if (process.platform === 'win32') {
if (common.isWindows) {
assert.equal(os.tmpdir(), '/temp');
process.env.TEMP = '';
assert.equal(os.tmpdir(), '/tmp');
Expand Down Expand Up @@ -101,3 +102,22 @@ switch (platform) {

var EOL = os.EOL;
assert.ok(EOL.length > 0);


var home = os.homedir();

console.log('homedir = ' + home);
assert.ok(typeof home === 'string');
assert.ok(home.indexOf(path.sep) !== -1);

if (common.isWindows && process.env.USERPROFILE) {
assert.equal(home, process.env.USERPROFILE);
delete process.env.USERPROFILE;
assert.ok(os.homedir().indexOf(path.sep) !== -1);
process.env.USERPROFILE = home;
} else if (!common.isWindows && process.env.HOME) {
assert.equal(home, process.env.HOME);
delete process.env.HOME;
assert.ok(os.homedir().indexOf(path.sep) !== -1);
process.env.HOME = home;
}

3 comments on commit 6e78e5f

@jorangreef
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test for Windows in common.js is not going to work on 64-bit windows:

exports.isWindows = process.platform === 'win32';

This should be used instead:

exports.isWindows = process.platform === 'win32' || process.platform === 'win64';

@bnoordhuis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jorangreef process.platform is always 'win32' on Windows, the 32/64 bits discriminator is process.arch.

@jorangreef
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thanks.

Please sign in to comment.