2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 13:22:11 +00:00

Add a default exec path logic.

This adds default/fallback logic to determine the b2 exec absolute path
as possible. It uses the arg0 and current dir or path to construct the
liekliest path.

fixes #25
This commit is contained in:
Rene Rivera
2021-05-29 22:09:13 -05:00
parent ecaa7a9bda
commit 91fd728f3e
4 changed files with 116 additions and 75 deletions

View File

@@ -28,9 +28,10 @@
*/
#include "jam.h"
#include "pathsys.h"
#include "cwd.h"
#include "filesys.h"
#include "pathsys.h"
#include <stdlib.h>
#include <time.h>
@@ -364,3 +365,105 @@ std::string b2::paths::normalize(const std::string &p)
return result;
}
/*
* executable_path()
*/
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
char * executable_path( char const * argv0 )
{
char buf[ 1024 ];
DWORD const ret = GetModuleFileNameA( NULL, buf, sizeof( buf ) );
return ( !ret || ret == sizeof( buf ) ) ? NULL : strdup( buf );
}
#elif defined(__APPLE__) /* Not tested */
# include <mach-o/dyld.h>
char *executable_path( char const * argv0 )
{
char buf[ 1024 ];
uint32_t size = sizeof( buf );
return _NSGetExecutablePath( buf, &size ) ? NULL : strdup( buf );
}
#elif defined(sun) || defined(__sun) /* Not tested */
# include <stdlib.h>
char * executable_path( char const * argv0 )
{
const char * execname = getexecname();
return execname ? strdup( execname ) : NULL;
}
#elif defined(__FreeBSD__)
# include <sys/sysctl.h>
char * executable_path( char const * argv0 )
{
int mib[ 4 ] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
char buf[ 1024 ];
size_t size = sizeof( buf );
sysctl( mib, 4, buf, &size, NULL, 0 );
return ( !size || size == sizeof( buf ) ) ? NULL : strndup( buf, size );
}
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__GNU__)
# include <unistd.h>
char * executable_path( char const * argv0 )
{
char buf[ 1024 ];
ssize_t const ret = readlink( "/proc/self/exe", buf, sizeof( buf ) );
return ( !ret || ret == sizeof( buf ) ) ? NULL : strndup( buf, ret );
}
#elif defined(OS_VMS)
# include <unixlib.h>
char * executable_path( char const * argv0 )
{
char * vms_path = NULL;
char * posix_path = NULL;
char * p;
/* On VMS argv[0] shows absolute path to the image file.
* So, just remove VMS file version and translate path to POSIX-style.
*/
vms_path = strdup( argv0 );
if ( vms_path && ( p = strchr( vms_path, ';') ) ) *p = '\0';
posix_path = decc$translate_vms( vms_path );
if ( vms_path ) free( vms_path );
return posix_path > 0 ? strdup( posix_path ) : NULL;
}
#else
char * executable_path( char const * argv0 )
{
char * result = nullptr;
/* If argv0 is an absolute path, assume it is the right absolute path. */
if (!result && b2::paths::is_rooted(argv0))
result = strdup( argv0 );
// If argv0 is a relative path, we can compute the absolute one from the
// current working dir.
if (!result && b2::paths::is_relative(argv0))
{
auto p = b2::paths::normalize(b2::cwd_str()+"/"+argv0);
result = strdup( p.c_str() );
}
// If it's a bare basename, search the PATH for a match.
if (!result)
{
std::string path_env = getenv( "PATH" );
std::string::size_type i = 0;
while (i != std::string::npos)
{
std::string::size_type e = path_env.find_first_of(':', i);
std::string p = e == std::string::npos
? path_env.substr(i)
: path_env.substr(i, e-i);
if (b2::filesys::is_file(p+"/"+argv0))
{
result = strdup( (p+"/"+argv0).c_str() );
break;
}
i = e == std::string::npos ? e : e+1;
}
}
return result;
}
#endif