Adds uv_get_exepath API

Only works on Linux, Mac, Windows currently.
This commit is contained in:
Igor Zinkovsky 2011-05-20 18:05:37 -07:00 committed by Ryan Dahl
parent d91b5012bd
commit 9fc8a7f167
10 changed files with 115 additions and 4 deletions

View File

@ -147,6 +147,7 @@
<ClCompile Include="..\test\test-delayed-accept.c" />
<ClCompile Include="..\test\test-callback-stack.c" />
<ClCompile Include="..\test\test-connection-fail.c" />
<ClCompile Include="..\test\test-get-currentexe.c" />
<ClCompile Include="..\test\test-fail-always.c" />
<ClCompile Include="..\test\test-loop-handles.c" />
<ClCompile Include="..\test\test-pass-always.c" />

View File

@ -37,10 +37,6 @@
#include <sys/select.h>
#include <pthread.h>
#define PATHMAX 1024
static char executable_path[PATHMAX] = { '\0' };
#ifdef __APPLE__
#include <mach-o/dyld.h> /* _NSGetExecutablePath */

View File

@ -47,6 +47,8 @@ void platform_init(int argc, char **argv) {
/* Disable stdio output buffering. */
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
strcpy(executable_path, argv[0]);
}

View File

@ -24,6 +24,7 @@
#include "runner.h"
#include "task.h"
char executable_path[PATHMAX] = { '\0' };
/* Start a specific process declared by TEST_ENTRY or TEST_HELPER. */
/* Returns the exit code of the specific process. */

View File

@ -79,6 +79,8 @@ int run_task(task_entry_t *test, int timeout, int benchmark_output);
#define TEST_HELPER HELPER_ENTRY
#define BENCHMARK_HELPER HELPER_ENTRY
#define PATHMAX 1024
extern char executable_path[PATHMAX];
/*
* Include platform-dependent definitions

View File

@ -0,0 +1,53 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "../uv.h"
#include "task.h"
#include <string.h>
#define PATHMAX 1024
extern char executable_path[];
TEST_IMPL(get_currentexe) {
char buffer[PATHMAX];
size_t size;
char* match;
int r;
size = sizeof(buffer) / sizeof(buffer[0]);
r = uv_get_exepath(buffer, &size);
ASSERT(!r);
match = strstr(buffer, executable_path);
/* Verify that the path returned from uv_get_exepath is a subdirectory of executable_path */
ASSERT(match && !strcmp(match, executable_path));
ASSERT(size == strlen(buffer));
/* Negative tests */
size = sizeof(buffer) / sizeof(buffer[0]);
r = uv_get_exepath(NULL, &size);
ASSERT(r == -1);
r = uv_get_exepath(buffer, NULL);
ASSERT(r == -1);
return 0;
}

View File

@ -38,6 +38,7 @@ TEST_DECLARE (async_ref)
TEST_DECLARE (prepare_ref)
TEST_DECLARE (check_ref)
TEST_DECLARE (async)
TEST_DECLARE (get_currentexe)
TEST_DECLARE (fail_always)
TEST_DECLARE (pass_always)
HELPER_DECLARE (echo_server)
@ -80,6 +81,8 @@ TASK_LIST_START
TEST_ENTRY (async)
TEST_ENTRY (get_currentexe)
#if 0
/* These are for testing the test runner. */
TEST_ENTRY (fail_always)

View File

@ -31,7 +31,11 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <limits.h> /* PATH_MAX */
#if defined(__APPLE__)
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
#endif
static uv_err_t last_err;
static uv_alloc_cb alloc_cb;
@ -1204,3 +1208,34 @@ int64_t uv_timer_get_repeat(uv_handle_t* handle) {
return (int64_t)(1000 * handle->timer_watcher.repeat);
}
int uv_get_exepath(char* buffer, size_t* size) {
if (!buffer || !size) {
return -1;
}
#if defined(__APPLE__)
uint32_t usize = *size;
int result = _NSGetExecutablePath(buffer, &usize);
if (result) return result;
char *path = (char*)malloc(2 * PATH_MAX);
char *fullpath = realpath(buffer, path);
if (fullpath == NULL) {
free(path);
return -1;
}
strncpy(buffer, fullpath, *size);
free(fullpath);
*size = strlen(buffer);
return 0;
#elif defined(__linux__)
*size = readlink("/proc/self/exe", buffer, *size - 1);
if (*size <= 0) return -1;
buffer[*size] = '\0';
return 0;
#else
assert(0 && "implement me");
/* Need to return argv[0] */
#endif
}

View File

@ -1626,3 +1626,18 @@ void uv_ref() {
void uv_unref() {
uv_refs_--;
}
int uv_get_exepath(char* buffer, size_t* size) {
if (!buffer || !size) {
return -1;
}
*size = GetModuleFileName(NULL, buffer, *size - 1);
if (*size <= 0) {
uv_set_sys_error(GetLastError());
return -1;
}
buffer[*size] = '\0';
return 0;
}

3
uv.h
View File

@ -291,6 +291,9 @@ int uv_close(uv_handle_t* handle);
/* Utility */
struct sockaddr_in uv_ip4_addr(char* ip, int port);
/* Gets the executable path */
int uv_get_exepath(char* buffer, size_t* size);
#ifdef __cplusplus
}
#endif