You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
4.5 KiB

/*
* Copyright 2002-2019 Intel Corporation.
*
* This software is provided to you as Sample Source Code as defined in the accompanying
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
* section 1.L.
*
* This software and the related documents are provided as is, with no express or implied
* warranties, other than those that are expressly stated in the License.
*/
#include "utils.h"
#if defined(PIN_CRT) && defined(TARGET_LINUX)
# include "pincrt_file_utils.h"
#endif
#define PATH_MAX_SIZE 4096
/*
* Only on linux the launcher_u linked with PinCRT which implements strnlen_s.
* Instead on macOS* uses the system library function strnlen.
*/
size_t get_strlen(const char* str)
{
size_t len;
#if defined(PIN_CRT) && defined(TARGET_LINUX)
len = strnlen_s(str, PATH_MAX_SIZE);
#else
len = strnlen(str, PATH_MAX_SIZE);
#endif
assert(len > 0);
return len;
}
char* appendPath(const char* s1, const char* s2, const char* s3)
{
int n = 1;
char* p = 0;
if (s1)
n += get_strlen(s1);
if (s2)
n += get_strlen(s2);
if (s3)
n += get_strlen(s3);
p = (char*) malloc(sizeof(char) * n);
if( p == NULL )
abort();
if (s1)
strcpy(p, s1);
if (s2)
strcat(p, s2);
if (s3)
strcat(p, s3);
return p;
}
void check_retval(int retval, const char* str)
{
if (retval != 0)
{
perror(str);
exit(1);
}
}
/*!
* @brief Checks if the file exist and readable.
* @param fn The file path
* @return True if exist, readable and executable
*/
unsigned int check_file_exists(const char* fn)
{
unsigned int okay = 1;
if (access(fn, R_OK ) == -1)
okay = 0;
return okay;
}
/*!
* @brief Checks for file properties and prints an error message is requirements are not met.
* @param fn The file path
*/
void check_file(const char* fn)
{
unsigned int okay = check_file_exists(fn);
if (!okay)
{
fprintf(stderr, "Error. File doesn't exist (%s)\n\n",fn );
exit(1);
}
}
/*!
* Check if the file path is a directory
* @param fn The file path
* @return 1 if the file path is not a directory
*/
unsigned int check_not_directory(const char* fn)
{
#if defined(PIN_CRT) && defined(TARGET_LINUX)
return is_directory_file(fn);
#else
unsigned int okay = 1;
struct stat st;
if (stat(fn, &st) == -1 || !S_ISREG(st.st_mode))
okay = 0;
return okay;
#endif
}
/*!
* Checks that a file exists in the directory and that it is not a directory.
* @param fn The file path to be checked
* @param dir The directory path to be checked in
* @param buff A buffer to create the complete path
* @return 1 if file exist and not a directory
*/
unsigned int check_file_in_dir(const char* fn, const char *dir, char *buff)
{
buff = appendPath(dir, "/", fn);
return check_file_exists(buff) && check_not_directory(buff);
}
/*!
* Searches for the given executable in the directories list at the PATH environment variable,
* and returns the directory it was found in.
* @param exename The executable path
* @return The directory it was found in, or null if not found.
*/
char *search_in_path(const char *exename)
{
const char dirsepchar = ':';
char* env_path;
char* syspath;
char* buff;
char* dir;
char* dirsep;
char *path = 0;
env_path = getenv("PATH");
assert(env_path != NULL);
syspath = strdup(env_path);
assert(syspath != NULL);
buff = (char*) malloc(get_strlen(syspath) + get_strlen(exename) + 2);
assert(buff != NULL);
dir = syspath;
dirsep = strchr(dir, dirsepchar);
while (dirsep)
{
*dirsep = 0;
if (check_file_in_dir(exename, dir, buff))
{
path = strdup(dir);
free(syspath);
free(buff);
return path;
}
dir = dirsep + 1;
dirsep = strchr(dir, dirsepchar);
}
if (check_file_in_dir(exename, dir, buff))
{
path = strdup(dir);
}
free(syspath);
free(buff);
return path;
}
/*!
* Finds the base path (containing directory) of the given executable.
* @param filename The file path
* @return The base path
*/
char* find_base_path(char* filename)
{
char* x;
char* path = strdup(filename);
x = strrchr(path, '/');
if (x)
{
*x = 0;
}
else
{
x = search_in_path(filename);
if (x)
{
free(path);
return x;
}
}
return path;
}