Skip to content
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

Fix handling of .. in jepath() (requires <filesystem> header) #170

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
74 changes: 22 additions & 52 deletions jsrc/jeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// utilities for JFE to load JE, initiallize, and run profile sentence
// JFEs are jconsole, jwdw, and jwdp
// TODO: Remove all void* where applicable when other parts of the code start being refactored
#include <filesystem>
#include <string>
#include <stdexcept>
#include <cstdint>
Expand Down Expand Up @@ -30,8 +31,8 @@ static JgaType jga;
static JGetLocaleType jgetlocale;
static JGetAType jgeta;
static JSetAType jseta;
std::string path;
std::string pathdll;
std::filesystem::path path;
std::filesystem::path pathdll;

auto
jedo(char const* sentence) -> int {
Expand Down Expand Up @@ -99,72 +100,41 @@ jepath(char* arg, char* lib) -> void {
uint32_t const sz = 4000;

// C strings need to be used for POSIX APIs and macOS APIs
auto arg2 = new char[sz];
auto arg3 = new char[sz];
auto path_temp = new char[sz];
// Return for readlinks
int n;
auto const arg2 = std::unique_ptr<char[]>(new char[sz]);
auto const arg3 = std::unique_ptr<char[]>(new char[sz]);

// try host dependent way to get path to executable
// use arg if they fail (arg command in PATH won't work)
#ifdef __MACH__
uint32_t len = sz; // Cant be const for function call _NSGetExecutablePath
// Returns 0 if path was copied, otherwise -1 if failed.
if (_NSGetExecutablePath(arg2, &len) != 0) strcat(arg2, arg);
if (uint32_t len = sz; _NSGetExecutablePath(arg2.get(), &len) != 0) strcat(arg2.get(), arg);
#else
n = readlink("/proc/self/exe", arg2, sz);
if (n == -1)
strcpy(arg2, arg);
else
arg2[n] = 0;
{
auto const n = readlink("/proc/self/exe", arg2, sz);
if (n == -1)
strcpy(arg2, arg);
else
arg2[n] = 0;
}
#endif
// arg2 is path (abs or relative) to executable or soft link
n = readlink(arg2, arg3, sz);

auto const n = readlink(arg2.get(), arg3.get(), sz);
if (n == -1)
strcpy(arg3, arg2);
strcpy(arg3.get(), arg2.get());
else
arg3[n] = 0;

if ('/' == *arg3)
strcpy(path_temp, arg3);
else {
if (!getcwd(path_temp, sizeof(path_temp))) path_temp[0] = 0;
strcat(path_temp, "/");
strcat(path_temp, arg3);
}
// Now append path_temp to path, as all POSIX and macOS API calls are done, and free up arg2, arg3, path_temp.
path.append(path_temp);
delete[] path_temp;
delete[] arg2;
delete[] arg3;
if ('/' == arg3[0])
path = arg3.get();
else
path = std::filesystem::current_path() / arg3.get();

// Remove everything after the last / as that would be the current executables name
path.erase(std::next(path.begin(), path.rfind('/')), path.end());
path.remove_filename();

// remove ./ and backoff ../
util::remove_all_occurrences(path, "../");
util::remove_all_occurrences(path, "./");

pathdll.append(path);
pathdll.append("/");
pathdll.append(JDLLNAME);

if (*lib) {
if ('/' != *lib) {
pathdll.append(path);
pathdll.append("/");
}
pathdll.append(lib);
}
}
path = path.lexically_normal();

// called by jwdp (java jnative.c) to set path
auto
jesetpath(char* arg) -> void {
pathdll.append(arg);
path.append(arg);
path.erase(std::next(path.begin(), path.rfind('/')), path.end());
pathdll = path / (*lib ? lib : JDLLNAME);
}

// build and run first sentence to set BINPATH, ARGV, and run profile
Expand Down
1 change: 0 additions & 1 deletion jsrc/jeload.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#pragma once

void jepath(char*, char*);
void jesetpath(char*);
void* jeload(void* callbacks); // returns J
A jegeta(int, char*);
I jeseta(I n, char* name, I x, char* d);
Expand Down