Browse Source

Initial implementation of process.execPath

Darwin, Linux, Solaris. FreeBSD still needs testing.

TODO: Amend the tests where we use spawn with argv[0].
v0.7.4-release
Marshall Culpepper 15 years ago
committed by Ryan Dahl
parent
commit
ca35ba640a
  1. 10
      src/node.cc
  2. 1
      src/platform.h
  3. 13
      src/platform_darwin.cc
  4. 12
      src/platform_freebsd.cc
  5. 7
      src/platform_linux.cc
  6. 4
      src/platform_none.cc
  7. 22
      src/platform_sunos.cc
  8. 19
      test/simple/test-executable-path.js

10
src/node.cc

@ -1732,6 +1732,16 @@ static void Load(int argc, char *argv[]) {
process->Set(String::NewSymbol("pid"), Integer::New(getpid())); process->Set(String::NewSymbol("pid"), Integer::New(getpid()));
size_t size = 2*PATH_MAX;
char execPath[size];
if (OS::GetExecutablePath(execPath, &size) != 0) {
// as a last ditch effort, fallback on argv[0] ?
process->Set(String::NewSymbol("execPath"), String::New(argv[0]));
} else {
process->Set(String::NewSymbol("execPath"), String::New(execPath));
}
// define various internal methods // define various internal methods
NODE_SET_METHOD(process, "loop", Loop); NODE_SET_METHOD(process, "loop", Loop);
NODE_SET_METHOD(process, "unloop", Unloop); NODE_SET_METHOD(process, "unloop", Unloop);

1
src/platform.h

@ -6,6 +6,7 @@ namespace node {
class OS { class OS {
public: public:
static int GetMemory(size_t *rss, size_t *vsize); static int GetMemory(size_t *rss, size_t *vsize);
static int GetExecutablePath(char* buffer, size_t* size);
}; };

13
src/platform_darwin.cc

@ -3,6 +3,7 @@
#include <mach/task.h> #include <mach/task.h>
#include <mach/mach_init.h> #include <mach/mach_init.h>
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
namespace node { namespace node {
@ -26,4 +27,16 @@ int OS::GetMemory(size_t *rss, size_t *vsize) {
} }
int OS::GetExecutablePath(char* buffer, size_t* size) {
uint32_t usize = *size;
int result = _NSGetExecutablePath(buffer, &usize);
if (result) return result;
char *path = realpath(buffer, NULL);
if (path == NULL) return -1;
strncpy(buffer, path, *size);
free(path);
*size = strlen(buffer);
return 0;
}
} // namespace node } // namespace node

12
src/platform_freebsd.cc

@ -41,5 +41,17 @@ error:
} }
int OS::GetExecutablePath(char* buffer, size_t* size) {
int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
if (sysctl(mib, 4, buffer, size, NULL, 0) == -1) {
return -1;
}
return 0;
}
} // namespace node } // namespace node

7
src/platform_linux.cc

@ -89,4 +89,11 @@ error:
} }
int OS::GetExecutablePath(char* buffer, size_t* size) {
*size = readlink("/proc/self/exe", buffer, *size - 1);
if (*size <= 0) return -1;
buffer[*size] = '\0';
return 0;
}
} // namespace node } // namespace node

4
src/platform_none.cc

@ -12,5 +12,9 @@ int OS::GetMemory(size_t *rss, size_t *vsize) {
return 0; return 0;
} }
int OS::GetExecutablePath(char *buffer, size_t* size) {
*size = 0;
return 0;
}
} // namespace node } // namespace node

22
src/platform_sunos.cc

@ -3,6 +3,9 @@
#include <unistd.h> /* getpagesize() */ #include <unistd.h> /* getpagesize() */
#include <stdlib.h> /* getexecname() */
#include <strings.h> /* strncpy() */
#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64) #if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
#define PROCFS_FILE_OFFSET_BITS_HACK 1 #define PROCFS_FILE_OFFSET_BITS_HACK 1
@ -48,5 +51,24 @@ int OS::GetMemory(size_t *rss, size_t *vsize) {
} }
int OS::GetExecutablePath(char* buffer, size_t* size) {
const char *execname = getexecname();
if (!execname) return -1;
if (execname[0] == '/') {
char *result = strncpy(buffer, execname, *size);
*size = strlen(result);
} else {
char *result = getcwd(buffer, *size);
if (!result) return -1;
result = strncat(buffer, "/", *size);
if (!result) return -1;
result = strncat(buffer, execname, *size);
if (!result) return -1;
*size = strlen(result);
}
return 0;
}
} // namespace node } // namespace node

19
test/simple/test-executable-path.js

@ -0,0 +1,19 @@
require("../common");
path = require("path");
isDebug = (process.version.indexOf('debug') >= 0);
nodePath = path.join(__dirname,
"..",
"..",
"build",
isDebug ? 'debug' : 'default',
isDebug ? 'node_g' : 'node');
nodePath = path.normalize(nodePath);
puts('nodePath: ' + nodePath);
puts('process.execPath: ' + process.execPath);
assert.equal(nodePath, process.execPath);
Loading…
Cancel
Save