From b9251eb4427db0a33e118ef72f2fd50c286e914e Mon Sep 17 00:00:00 2001 From: George Bosilca Date: Sun, 1 Jul 2007 17:53:19 +0000 Subject: [PATCH] On Windows accept networked path (i.e. starting with \\). Add a new function opal_find_absolute_path which take as argument a executable name and return the absolute path if possible. This commit was SVN r15255. --- opal/util/path.c | 52 +++++++++++++--- opal/util/path.h | 159 ++++++++++++++++++++++++++--------------------- 2 files changed, 131 insertions(+), 80 deletions(-) diff --git a/opal/util/path.c b/opal/util/path.c index cced8a6556..1256b099dc 100644 --- a/opal/util/path.c +++ b/opal/util/path.c @@ -34,16 +34,15 @@ static char *list_env_get(char *var, char **list); bool opal_path_is_absolute( const char *path ) { #if defined(__WINDOWS__) - /* On Windows an absolute path always start with [a-z]:\ */ - if( ':' == path[1] ) { - return true; - } + /* On Windows an absolute path always start with [a-z]:\ or with \\ */ + if( (isalpha(path[0]) && (':' == path[1])) || + ('\' == path[0]) && ('\' == path[1]) ) return true; #else if( OPAL_PATH_SEP[0] == *path ) { return true; } #endif /* defined(__WINDOWS__) */ - return false; + return false; } /** @@ -176,8 +175,7 @@ char *opal_path_access(char *fname, char *path, int mode) /* Allocate space for the full pathname. */ if( NULL == path ) { fullpath = opal_os_path( false, fname, NULL ); - } - else { + } else { fullpath = opal_os_path( false, path, fname, NULL ); } if( NULL == fullpath ) @@ -219,7 +217,7 @@ static void path_env_load(char *path, int *pargc, char ***pargv) while ('\0' != *path) { - /* Locate the delimiter. */ + /* Locate the delimiter. */ for (p = path; *p && (*p != OPAL_ENV_SEP); ++p) { continue; @@ -272,3 +270,41 @@ static char *list_env_get(char *var, char **list) return getenv(var); } +/** + * Try to figure out the absolute path based on the application name + * (usually argv[0]). If the path is already absolute return a copy, if + * it start with . look into the current directory, if not dig into + * the $PATH. + * In case of error or if executable was not found (as an example if + * the application did a cwd between the start and this call), the + * function will return NULL. Otherwise, an newly allocated string + * will be returned. + */ +char* opal_find_absolute_path( char* app_name ) +{ + char* abs_app_name; + + if( opal_path_is_absolute(app_name) ) { /* already absolute path */ + abs_app_name = app_name; + } else if( '.' == app_name[0] ) { /* the app is in the current directory */ + char cwd[PATH_MAX], *pcwd; + pcwd = getcwd( cwd, PATH_MAX ); + if( NULL == pcwd ) { + /* too bad there is no way we can get the app absolute name */ + return NULL; + } + abs_app_name = opal_os_path( false, pcwd, app_name, NULL ); + } else { + /* Otherwise try to search for the application in the PATH ... */ + abs_app_name = opal_path_findv( app_name, X_OK, NULL, NULL ); + } + + if( NULL != abs_app_name ) { + char resolved_path[PATH_MAX]; + + realpath( abs_app_name, resolved_path ); + if( abs_app_name != app_name ) free(abs_app_name); + return strdup(resolved_path); + } + return NULL; +} diff --git a/opal/util/path.h b/opal/util/path.h index 91d0cbfa15..a62a91852b 100644 --- a/opal/util/path.h +++ b/opal/util/path.h @@ -23,80 +23,95 @@ #include "opal_config.h" -#if defined(c_plusplus) || defined(__cplusplus) -extern "C" { -#endif +BEGIN_C_DECLS - /** - * Locates a file with certain permissions - * - * @param fname File name - * @param pathv Array of search directories - * @param mode Permissions which must be satisfied (see access(2)) - * @param envv Pointer to string containing environment - * - * @retval Full pathname of located file Success - * @retval NULL Failure - * - * Environment variables can appear in the form $variable at the - * start of a prefix path and will be replaced by the environment - * value if it is defined; otherwise the whole prefix is ignored. - * Environment variables must be followed by a path delimiter or - * end-of-string. - * - * The caller is responsible for freeing the returned string. - */ - OPAL_DECLSPEC char *opal_path_find(char *fname, char **pathv, int mode, - char **envv); +/** + * Locates a file with certain permissions + * + * @param fname File name + * @param pathv Array of search directories + * @param mode Permissions which must be satisfied (see access(2)) + * @param envv Pointer to string containing environment + * + * @retval Full pathname of located file Success + * @retval NULL Failure + * + * Environment variables can appear in the form $variable at the + * start of a prefix path and will be replaced by the environment + * value if it is defined; otherwise the whole prefix is ignored. + * Environment variables must be followed by a path delimiter or + * end-of-string. + * + * The caller is responsible for freeing the returned string. + */ +OPAL_DECLSPEC char *opal_path_find(char *fname, char **pathv, int mode, + char **envv); - /** - * Locates a file with certain permissions from a list of search - * paths - * - * @param fname File name - * @param mode Target permissions which must be satisfied (see access(2)) - * @param envv Pointer to environment list - * @param wrkdir Working directory - * - * @retval Full pathname of located file Success - * @retval NULL Failure - * - * Locates a file with certain permissions from the list of paths - * given by the $PATH environment variable. Replaces "." in the - * path with the working dir. - * - * The caller is responsible for freeing the returned string. - */ - OPAL_DECLSPEC char *opal_path_findv(char *fname, int mode, - char **envv, char *wrkdir); - /** - * Detect if the requested path is absolute or relative. - * - * @param path File name - * - * @retval true if the path is absolute - * @retval false otherwise - * - * Detect if a path is absolute or relative. Handle Windows - * with special care as an absolute path on Windows starts - * with [A-Za-z]: instead of the usual / on UNIX. - */ - OPAL_DECLSPEC bool opal_path_is_absolute( const char *path ); +/** + * Locates a file with certain permissions from a list of search + * paths + * + * @param fname File name + * @param mode Target permissions which must be satisfied (see access(2)) + * @param envv Pointer to environment list + * @param wrkdir Working directory + * + * @retval Full pathname of located file Success + * @retval NULL Failure + * + * Locates a file with certain permissions from the list of paths + * given by the $PATH environment variable. Replaces "." in the + * path with the working dir. + * + * The caller is responsible for freeing the returned string. + */ +OPAL_DECLSPEC char *opal_path_findv(char *fname, int mode, + char **envv, char *wrkdir); +/** + * Detect if the requested path is absolute or relative. + * + * @param path File name + * + * @retval true if the path is absolute + * @retval false otherwise + * + * Detect if a path is absolute or relative. Handle Windows + * with special care as an absolute path on Windows starts + * with [A-Za-z]: or \\ instead of the usual / on UNIX. + */ +OPAL_DECLSPEC bool opal_path_is_absolute( const char *path ); - /** - * Forms a complete pathname and checks it for existance and - * permissions - * - * @param fname File name - * @param path Path prefix, if NULL then fname is an absolute path - * @param mode Target permissions which must be satisfied (see access(2)) - * - * @retval NULL Failure - * @retval Full pathname of the located file on Success - */ - OPAL_DECLSPEC char *opal_path_access(char *fname, char *path, int mode); +/** + * Find the absolute path for an executable and return it. + * + * @param app_name Executable name + * + * @retval The absolute path if the application can be reached, + * @retval NULL otherwise. + * + * Try to figure out the absolute path based on the application name + * (usually argv[0]). If the path is already absolute return a copy, if + * it start with . look into the current directory, if not dig into + * the $PATH. + * In case of error or if executable was not found (as an example if + * the application did a cwd between the start and this call), the + * function will return NULL. Otherwise, an newly allocated string + * will be returned. + */ +OPAL_DECLSPEC char* opal_find_absolute_path( char* app_name ); -#if defined(c_plusplus) || defined(__cplusplus) -} -#endif +/** + * Forms a complete pathname and checks it for existance and + * permissions + * + * @param fname File name + * @param path Path prefix, if NULL then fname is an absolute path + * @param mode Target permissions which must be satisfied (see access(2)) + * + * @retval NULL Failure + * @retval Full pathname of the located file on Success + */ +OPAL_DECLSPEC char *opal_path_access(char *fname, char *path, int mode); + +END_C_DECLS #endif /* OPAL_PATH_H */