Skip to content

Commit

Permalink
kernel: move SYS_DEFAULT_PATHS handling to main.c
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin committed Dec 2, 2022
1 parent afa8fbd commit 97b8a3f
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 155 deletions.
169 changes: 167 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,183 @@
*/

#include "common.h"
#include "sysfiles.h"
#include "sysroots.h"
#include "sysstr.h"
#include "system.h"

#ifdef HPCGAP
#include "hpc/thread.h"
#endif

#include "config.h"

extern int realmain(int argc, char *argv[]);
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
extern int realmain(int argc, char * argv[]);

/****************************************************************************
**
*F * * * * * * * * * * finding location of executable * * * * * * * * * * * *
*/

#ifdef SYS_DEFAULT_PATHS

static void SetupInitialGapRoot(const char * argv0)
{
SySetGapRootPath(SYS_DEFAULT_PATHS);
}

#else

/****************************************************************************
**
** The function 'find_yourself' is based on code (C) 2015 Mark Whitis, under
** the MIT License : https://stackoverflow.com/a/34271901/928031
*/
static void
find_yourself(const char * argv0, char * result, size_t resultsize)
{
GAP_ASSERT(resultsize >= GAP_PATH_MAX);

char tmpbuf[GAP_PATH_MAX];

// absolute path, like '/usr/bin/gap'
if (argv0[0] == '/') {
if (realpath(argv0, result) && !access(result, F_OK)) {
return; // success
}
}
// relative path, like 'bin/gap.sh'
else if (strchr(argv0, '/')) {
if (!getcwd(tmpbuf, sizeof(tmpbuf)))
return;
gap_strlcat(tmpbuf, "/", sizeof(tmpbuf));
gap_strlcat(tmpbuf, argv0, sizeof(tmpbuf));
if (realpath(tmpbuf, result) && !access(result, F_OK)) {
return; // success
}
}
// executable name, like 'gap'
else {
char pathenv[GAP_PATH_MAX], *saveptr, *pathitem;
gap_strlcpy(pathenv, getenv("PATH"), sizeof(pathenv));
pathitem = strtok_r(pathenv, ":", &saveptr);
for (; pathitem; pathitem = strtok_r(NULL, ":", &saveptr)) {
gap_strlcpy(tmpbuf, pathitem, sizeof(tmpbuf));
gap_strlcat(tmpbuf, "/", sizeof(tmpbuf));
gap_strlcat(tmpbuf, argv0, sizeof(tmpbuf));
if (realpath(tmpbuf, result) && !access(result, F_OK)) {
return; // success
}
}
}

*result = 0; // reset buffer after error
}

static void SetupGAPLocation(const char * argv0, char * GAPExecLocation)
{
// In the code below, we keep resetting locBuf, as some of the methods we
// try do not promise to leave the buffer empty on a failed return.
char locBuf[GAP_PATH_MAX] = "";
Int4 length = 0;

#if defined(__APPLE__) && defined(__MACH__)
uint32_t len = sizeof(locBuf);
if (_NSGetExecutablePath(locBuf, &len) != 0) {
*locBuf = 0; // reset buffer after error
}
#endif

// try Linux procfs
if (!*locBuf) {
ssize_t ret = readlink("/proc/self/exe", locBuf, sizeof(locBuf));
if (ret < 0)
*locBuf = 0; // reset buffer after error
}

// try FreeBSD / DragonFly BSD procfs
if (!*locBuf) {
ssize_t ret = readlink("/proc/curproc/file", locBuf, sizeof(locBuf));
if (ret < 0)
*locBuf = 0; // reset buffer after error
}

// try NetBSD procfs
if (!*locBuf) {
ssize_t ret = readlink("/proc/curproc/exe", locBuf, sizeof(locBuf));
if (ret < 0)
*locBuf = 0; // reset buffer after error
}

// if we are still failing, go and search the path
if (!*locBuf) {
find_yourself(argv0, locBuf, GAP_PATH_MAX);
}

// resolve symlinks (if present)
if (!realpath(locBuf, GAPExecLocation))
*GAPExecLocation = 0; // reset buffer after error

// now strip the executable name off
length = strlen(GAPExecLocation);
while (length > 0 && GAPExecLocation[length] != '/') {
GAPExecLocation[length] = 0;
length--;
}
}

/****************************************************************************
**
*F SySetInitialGapRootPaths( <string> ) . . . . . set the root directories
**
** Set up GAP's initial root paths, based on the location of the
** GAP executable.
*/
static void SySetInitialGapRootPaths(const char * GAPExecLocation)
{
if (GAPExecLocation[0] != 0) {
// GAPExecLocation might be a subdirectory of GAP root,
// so we will go and search for the true GAP root.
// We try stepping back up to two levels.
char pathbuf[GAP_PATH_MAX];
char initgbuf[GAP_PATH_MAX];
strxcpy(pathbuf, GAPExecLocation, sizeof(pathbuf));
for (Int i = 0; i < 3; ++i) {
strxcpy(initgbuf, pathbuf, sizeof(initgbuf));
strxcat(initgbuf, "lib/init.g", sizeof(initgbuf));

if (SyIsReadableFile(initgbuf) == 0) {
SySetGapRootPath(pathbuf);
// escape from loop
return;
}
// try up a directory level
strxcat(pathbuf, "../", sizeof(pathbuf));
}
}

// Set GAP root path to current directory, if we have no other
// idea, and for backwards compatibility.
// Note that GAPExecLocation must always end with a slash.
SySetGapRootPath("./");
}

static void SetupInitialGapRoot(const char * argv0)
{
char GAPExecLocation[GAP_PATH_MAX] = "";
SetupGAPLocation(argv0, GAPExecLocation);
SySetInitialGapRootPaths(GAPExecLocation);
}
#endif

int main(int argc, char * argv[])
{
InstallBacktraceHandlers();
SetupInitialGapRoot(argv[0]);

#ifdef HPCGAP
RunThreadedMain(realmain, argc, argv);
Expand Down
153 changes: 0 additions & 153 deletions src/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,152 +275,6 @@ void Panic_(const char * file, int line, const char * fmt, ...)
}


/****************************************************************************
**
*F * * * * * * * * * * finding location of executable * * * * * * * * * * * *
*/

#ifndef SYS_DEFAULT_PATHS
/****************************************************************************
** The function 'find_yourself' is based on code (C) 2015 Mark Whitis, under
** the MIT License : https://stackoverflow.com/a/34271901/928031
*/

static void
find_yourself(const char * argv0, char * result, size_t resultsize)
{
GAP_ASSERT(resultsize >= GAP_PATH_MAX);

char tmpbuf[GAP_PATH_MAX];

// absolute path, like '/usr/bin/gap'
if (argv0[0] == '/') {
if (realpath(argv0, result) && !access(result, F_OK)) {
return; // success
}
}
// relative path, like 'bin/gap.sh'
else if (strchr(argv0, '/')) {
if (!getcwd(tmpbuf, sizeof(tmpbuf)))
return;
gap_strlcat(tmpbuf, "/", sizeof(tmpbuf));
gap_strlcat(tmpbuf, argv0, sizeof(tmpbuf));
if (realpath(tmpbuf, result) && !access(result, F_OK)) {
return; // success
}
}
// executable name, like 'gap'
else {
char pathenv[GAP_PATH_MAX], *saveptr, *pathitem;
gap_strlcpy(pathenv, getenv("PATH"), sizeof(pathenv));
pathitem = strtok_r(pathenv, ":", &saveptr);
for (; pathitem; pathitem = strtok_r(NULL, ":", &saveptr)) {
gap_strlcpy(tmpbuf, pathitem, sizeof(tmpbuf));
gap_strlcat(tmpbuf, "/", sizeof(tmpbuf));
gap_strlcat(tmpbuf, argv0, sizeof(tmpbuf));
if (realpath(tmpbuf, result) && !access(result, F_OK)) {
return; // success
}
}
}

*result = 0; // reset buffer after error
}


static char GAPExecLocation[GAP_PATH_MAX] = "";

static void SetupGAPLocation(const char * argv0)
{
// In the code below, we keep resetting locBuf, as some of the methods we
// try do not promise to leave the buffer empty on a failed return.
char locBuf[GAP_PATH_MAX] = "";
Int4 length = 0;

#if defined(__APPLE__) && defined(__MACH__)
uint32_t len = sizeof(locBuf);
if (_NSGetExecutablePath(locBuf, &len) != 0) {
*locBuf = 0; // reset buffer after error
}
#endif

// try Linux procfs
if (!*locBuf) {
ssize_t ret = readlink("/proc/self/exe", locBuf, sizeof(locBuf));
if (ret < 0)
*locBuf = 0; // reset buffer after error
}

// try FreeBSD / DragonFly BSD procfs
if (!*locBuf) {
ssize_t ret = readlink("/proc/curproc/file", locBuf, sizeof(locBuf));
if (ret < 0)
*locBuf = 0; // reset buffer after error
}

// try NetBSD procfs
if (!*locBuf) {
ssize_t ret = readlink("/proc/curproc/exe", locBuf, sizeof(locBuf));
if (ret < 0)
*locBuf = 0; // reset buffer after error
}

// if we are still failing, go and search the path
if (!*locBuf) {
find_yourself(argv0, locBuf, GAP_PATH_MAX);
}

// resolve symlinks (if present)
if (!realpath(locBuf, GAPExecLocation))
*GAPExecLocation = 0; // reset buffer after error

// now strip the executable name off
length = strlen(GAPExecLocation);
while (length > 0 && GAPExecLocation[length] != '/') {
GAPExecLocation[length] = 0;
length--;
}
}


/****************************************************************************
**
*F SySetInitialGapRootPaths( <string> ) . . . . . set the root directories
**
** Set up GAP's initial root paths, based on the location of the
** GAP executable.
*/
static void SySetInitialGapRootPaths(void)
{
if (GAPExecLocation[0] != 0) {
// GAPExecLocation might be a subdirectory of GAP root,
// so we will go and search for the true GAP root.
// We try stepping back up to two levels.
char pathbuf[GAP_PATH_MAX];
char initgbuf[GAP_PATH_MAX];
strxcpy(pathbuf, GAPExecLocation, sizeof(pathbuf));
for (Int i = 0; i < 3; ++i) {
strxcpy(initgbuf, pathbuf, sizeof(initgbuf));
strxcat(initgbuf, "lib/init.g", sizeof(initgbuf));

if (SyIsReadableFile(initgbuf) == 0) {
SySetGapRootPath(pathbuf);
// escape from loop
return;
}
// try up a directory level
strxcat(pathbuf, "../", sizeof(pathbuf));
}
}

// Set GAP root path to current directory, if we have no other
// idea, and for backwards compatibility.
// Note that GAPExecLocation must always end with a slash.
SySetGapRootPath("./");
}
#endif


/****************************************************************************
**
*F SyDotGapPath()
Expand Down Expand Up @@ -746,13 +600,6 @@ void InitSystem (
SyInstallAnswerIntr();
}

#if defined(SYS_DEFAULT_PATHS)
SySetGapRootPath( SYS_DEFAULT_PATHS );
#else
SetupGAPLocation(argv[0]);
SySetInitialGapRootPaths();
#endif

/* save the original command line for export to GAP */
SyOriginalArgc = argc;
SyOriginalArgv = argv;
Expand Down

0 comments on commit 97b8a3f

Please sign in to comment.