Skip to content

Add os.exePath #1029

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions cutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#include <windows.h>
#include <process.h> // _beginthread
#endif
#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif

#include "cutils.h"

Expand Down Expand Up @@ -1201,6 +1204,109 @@ int64_t js__gettimeofday_us(void) {
return ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec;
}

#if defined(_WIN32)
int js_exepath(char *buffer, size_t *size_ptr) {
int utf8_len, utf16_buffer_len, utf16_len;
WCHAR* utf16_buffer;

if (buffer == NULL || size_ptr == NULL || *size_ptr == 0)
return -1;

if (*size_ptr > 32768) {
/* Windows paths can never be longer than this. */
utf16_buffer_len = 32768;
} else {
utf16_buffer_len = (int)*size_ptr;
}

utf16_buffer = malloc(sizeof(WCHAR) * utf16_buffer_len);
if (!utf16_buffer)
return -1;

/* Get the path as UTF-16. */
utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
if (utf16_len <= 0)
goto error;

/* Convert to UTF-8 */
utf8_len = WideCharToMultiByte(CP_UTF8,
0,
utf16_buffer,
-1,
buffer,
(int)*size_ptr,
NULL,
NULL);
if (utf8_len == 0)
goto error;

free(utf16_buffer);

/* utf8_len *does* include the terminating null at this point, but the
* returned size shouldn't. */
*size_ptr = utf8_len - 1;
return 0;

error:
free(utf16_buffer);
return -1;
}
#elif defined(__APPLE__)
int js_exepath(char *buffer, size_t *size) {
/* realpath(exepath) may be > PATH_MAX so double it to be on the safe side. */
char abspath[PATH_MAX * 2 + 1];
char exepath[PATH_MAX + 1];
uint32_t exepath_size;
size_t abspath_size;

if (buffer == NULL || size == NULL || *size == 0)
return -1;

exepath_size = sizeof(exepath);
if (_NSGetExecutablePath(exepath, &exepath_size))
return -1;

if (realpath(exepath, abspath) != abspath)
return -1;

abspath_size = strlen(abspath);
if (abspath_size == 0)
return -1;

*size -= 1;
if (*size > abspath_size)
*size = abspath_size;

memcpy(buffer, abspath, *size);
buffer[*size] = '\0';

return 0;
}
#elif defined(__linux__)
int js_exepath(char *buffer, size_t *size) {
ssize_t n;

if (buffer == NULL || size == NULL || *size == 0)
return -1;

n = *size - 1;
if (n > 0)
n = readlink("/proc/self/exe", buffer, n);

if (n == -1)
return n;

buffer[n] = '\0';
*size = n;

return 0;
}
#else
int js_exepath(char* buffer, size_t* size_ptr) {
return -1;
}
#endif

/*--- Cross-platform threading APIs. ----*/

#if JS_HAVE_THREADS
Expand Down
14 changes: 14 additions & 0 deletions cutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ extern "C" {
#include <errno.h>
#include <pthread.h>
#endif
#if !defined(_WIN32)
#include <limits.h>
#include <unistd.h>
#endif

#if defined(_MSC_VER) && !defined(__clang__)
# define likely(x) (x)
Expand Down Expand Up @@ -118,6 +122,14 @@ extern "C" {
#endif
#endif

#if defined(PATH_MAX)
# define JS__PATH_MAX PATH_MAX
#elif defined(_WIN32)
# define JS__PATH_MAX 32767
#else
# define JS__PATH_MAX 8192
#endif

void js__pstrcpy(char *buf, int buf_size, const char *str);
char *js__pstrcat(char *buf, int buf_size, const char *s);
int js__strstart(const char *str, const char *val, const char **ptr);
Expand Down Expand Up @@ -581,6 +593,8 @@ static inline size_t js__malloc_usable_size(const void *ptr)
#endif
}

int js_exepath(char* buffer, size_t* size);

/* Cross-platform threading APIs. */

#if defined(EMSCRIPTEN) || defined(__wasi__)
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/stdlib.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ pathname of `path` and `err` the error code.
Return `[str, err]` where `str` is the current working directory
and `err` the error code.

### `exePath()`

Returns the full path of the current executable or `undefined` if not available / supported.

### `chdir(path)`

Change the current directory. Return 0 if OK or `-errno`.
Expand Down
Loading