10039db0dSBarry Smith #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for realpath() */ 2c6db04a5SJed Brown #include <petscsys.h> 3e5c89e4eSSatish Balay #if defined(PETSC_HAVE_PWD_H) 4e5c89e4eSSatish Balay #include <pwd.h> 5e5c89e4eSSatish Balay #endif 6e5c89e4eSSatish Balay #include <ctype.h> 7e5c89e4eSSatish Balay #include <sys/stat.h> 8e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H) 9e5c89e4eSSatish Balay #include <unistd.h> 10e5c89e4eSSatish Balay #endif 11e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_UTSNAME_H) 12e5c89e4eSSatish Balay #include <sys/utsname.h> 13e5c89e4eSSatish Balay #endif 14e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H) 15e5c89e4eSSatish Balay #include <sys/systeminfo.h> 16e5c89e4eSSatish Balay #endif 17e5c89e4eSSatish Balay 18e5c89e4eSSatish Balay /*@C 19e5c89e4eSSatish Balay PetscGetRealPath - Get the path without symbolic links etc. and in absolute form. 20e5c89e4eSSatish Balay 21e5c89e4eSSatish Balay Not Collective 22e5c89e4eSSatish Balay 23e5c89e4eSSatish Balay Input Parameter: 24e5c89e4eSSatish Balay . path - path to resolve 25e5c89e4eSSatish Balay 26e5c89e4eSSatish Balay Output Parameter: 27e5c89e4eSSatish Balay . rpath - resolved path 28e5c89e4eSSatish Balay 29e5c89e4eSSatish Balay Level: developer 30e5c89e4eSSatish Balay 31e5c89e4eSSatish Balay Notes: 32*811af0c4SBarry Smith rpath is assumed to be of length `PETSC_MAX_PATH_LEN`. 33e5c89e4eSSatish Balay 34e5c89e4eSSatish Balay Systems that use the automounter often generate absolute paths 35e5c89e4eSSatish Balay of the form "/tmp_mnt....". However, the automounter will fail to 36e5c89e4eSSatish Balay mount this path if it is not already mounted, so we remove this from 37e5c89e4eSSatish Balay the head of the line. This may cause problems if, for some reason, 38e5c89e4eSSatish Balay /tmp_mnt is valid and not the result of the automounter. 39e5c89e4eSSatish Balay 40db781477SPatrick Sanan .seealso: `PetscGetFullPath()` 41e5c89e4eSSatish Balay @*/ 429371c9d4SSatish Balay PetscErrorCode PetscGetRealPath(const char path[], char rpath[]) { 43e5c89e4eSSatish Balay char tmp3[PETSC_MAX_PATH_LEN]; 44ace3abfcSBarry Smith PetscBool flg; 45e5c89e4eSSatish Balay #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK) 46e5c89e4eSSatish Balay char tmp1[PETSC_MAX_PATH_LEN], tmp4[PETSC_MAX_PATH_LEN], *tmp2; 47e5c89e4eSSatish Balay size_t N, len, len1, len2; 48e5c89e4eSSatish Balay int n, m; 49e5c89e4eSSatish Balay #endif 50e5c89e4eSSatish Balay 51e5c89e4eSSatish Balay PetscFunctionBegin; 52e5c89e4eSSatish Balay #if defined(PETSC_HAVE_REALPATH) 5308401ef6SPierre Jolivet PetscCheck(realpath(path, rpath), PETSC_COMM_SELF, PETSC_ERR_LIB, "realpath()"); 54e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_READLINK) 55e5c89e4eSSatish Balay /* Algorithm: we move through the path, replacing links with the real paths. */ 569566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(rpath, path)); 579566063dSJacob Faibussowitsch PetscCall(PetscStrlen(rpath, &N)); 58e5c89e4eSSatish Balay while (N) { 599566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(tmp1, rpath, N)); 60e5c89e4eSSatish Balay tmp1[N] = 0; 61e5c89e4eSSatish Balay n = readlink(tmp1, tmp3, PETSC_MAX_PATH_LEN); 62e5c89e4eSSatish Balay if (n > 0) { 63e5c89e4eSSatish Balay tmp3[n] = 0; /* readlink does not automatically add 0 to string end */ 64e5c89e4eSSatish Balay if (tmp3[0] != '/') { 659566063dSJacob Faibussowitsch PetscCall(PetscStrchr(tmp1, '/', &tmp2)); 669566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmp1, &len1)); 679566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmp2, &len2)); 68e5c89e4eSSatish Balay m = len1 - len2; 699566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(tmp4, tmp1, m)); 70e5c89e4eSSatish Balay tmp4[m] = 0; 719566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmp4, &len)); 729566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(tmp4, "/", PETSC_MAX_PATH_LEN)); 739566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(tmp4, tmp3, PETSC_MAX_PATH_LEN)); 749566063dSJacob Faibussowitsch PetscCall(PetscGetRealPath(tmp4, rpath)); 759566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(rpath, path + N, PETSC_MAX_PATH_LEN)); 76e5c89e4eSSatish Balay } else { 779566063dSJacob Faibussowitsch PetscCall(PetscGetRealPath(tmp3, tmp1)); 789566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(rpath, tmp1, PETSC_MAX_PATH_LEN)); 799566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(rpath, path + N, PETSC_MAX_PATH_LEN)); 80e5c89e4eSSatish Balay } 81e5c89e4eSSatish Balay PetscFunctionReturn(0); 82e5c89e4eSSatish Balay } 839566063dSJacob Faibussowitsch PetscCall(PetscStrchr(tmp1, '/', &tmp2)); 84e5c89e4eSSatish Balay if (tmp2) { 859566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmp1, &len1)); 869566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmp2, &len2)); 87e5c89e4eSSatish Balay N = len1 - len2; 88e5c89e4eSSatish Balay } else { 899566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmp1, &N)); 90e5c89e4eSSatish Balay } 91e5c89e4eSSatish Balay } 929566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(rpath, path, PETSC_MAX_PATH_LEN)); 93e5c89e4eSSatish Balay #else /* Just punt */ 949566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(rpath, path)); 95e5c89e4eSSatish Balay #endif 96e5c89e4eSSatish Balay 97e5c89e4eSSatish Balay /* remove garbage some automounters put at the beginning of the path */ 989566063dSJacob Faibussowitsch PetscCall(PetscStrncmp("/tmp_mnt/", rpath, 9, &flg)); 99e5c89e4eSSatish Balay if (flg) { 1009566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(tmp3, rpath + 8)); 1019566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(rpath, tmp3)); 102e5c89e4eSSatish Balay } 103e5c89e4eSSatish Balay PetscFunctionReturn(0); 104e5c89e4eSSatish Balay } 105