xref: /petsc/src/sys/fileio/grpath.c (revision c6a7a37075f8bf8d34d92c4910d42445b7a3482d)
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:
32811af0c4SBarry 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 @*/
42d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetRealPath(const char path[], char rpath[])
43d71ae5a4SJacob Faibussowitsch {
44e5c89e4eSSatish Balay   char      tmp3[PETSC_MAX_PATH_LEN];
45ace3abfcSBarry Smith   PetscBool flg;
46e5c89e4eSSatish Balay #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK)
47e5c89e4eSSatish Balay   char   tmp1[PETSC_MAX_PATH_LEN], tmp4[PETSC_MAX_PATH_LEN], *tmp2;
48*c6a7a370SJeremy L Thompson   size_t N, len1, len2;
49e5c89e4eSSatish Balay   int    n, m;
50e5c89e4eSSatish Balay #endif
51*c6a7a370SJeremy L Thompson   size_t len;
52e5c89e4eSSatish Balay 
53e5c89e4eSSatish Balay   PetscFunctionBegin;
54e5c89e4eSSatish Balay #if defined(PETSC_HAVE_REALPATH)
5508401ef6SPierre Jolivet   PetscCheck(realpath(path, rpath), PETSC_COMM_SELF, PETSC_ERR_LIB, "realpath()");
56e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_READLINK)
57e5c89e4eSSatish Balay   /* Algorithm: we move through the path, replacing links with the real paths.   */
58*c6a7a370SJeremy L Thompson   PetscCall(PetscStrlen(path, &N));
59*c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(rpath, path, N + 1)); /* assuming adequate buffer */
609566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(rpath, &N));
61e5c89e4eSSatish Balay   while (N) {
629566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(tmp1, rpath, N));
63e5c89e4eSSatish Balay     tmp1[N] = 0;
64e5c89e4eSSatish Balay     n       = readlink(tmp1, tmp3, PETSC_MAX_PATH_LEN);
65e5c89e4eSSatish Balay     if (n > 0) {
66e5c89e4eSSatish Balay       tmp3[n] = 0; /* readlink does not automatically add 0 to string end */
67e5c89e4eSSatish Balay       if (tmp3[0] != '/') {
689566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(tmp1, '/', &tmp2));
699566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(tmp1, &len1));
709566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(tmp2, &len2));
71e5c89e4eSSatish Balay         m = len1 - len2;
729566063dSJacob Faibussowitsch         PetscCall(PetscStrncpy(tmp4, tmp1, m));
73e5c89e4eSSatish Balay         tmp4[m] = 0;
749566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(tmp4, &len));
759566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(tmp4, "/", PETSC_MAX_PATH_LEN));
769566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(tmp4, tmp3, PETSC_MAX_PATH_LEN));
779566063dSJacob Faibussowitsch         PetscCall(PetscGetRealPath(tmp4, rpath));
789566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(rpath, path + N, PETSC_MAX_PATH_LEN));
79e5c89e4eSSatish Balay       } else {
809566063dSJacob Faibussowitsch         PetscCall(PetscGetRealPath(tmp3, tmp1));
819566063dSJacob Faibussowitsch         PetscCall(PetscStrncpy(rpath, tmp1, PETSC_MAX_PATH_LEN));
829566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(rpath, path + N, PETSC_MAX_PATH_LEN));
83e5c89e4eSSatish Balay       }
843ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
85e5c89e4eSSatish Balay     }
869566063dSJacob Faibussowitsch     PetscCall(PetscStrchr(tmp1, '/', &tmp2));
87e5c89e4eSSatish Balay     if (tmp2) {
889566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(tmp1, &len1));
899566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(tmp2, &len2));
90e5c89e4eSSatish Balay       N = len1 - len2;
91e5c89e4eSSatish Balay     } else {
929566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(tmp1, &N));
93e5c89e4eSSatish Balay     }
94e5c89e4eSSatish Balay   }
959566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(rpath, path, PETSC_MAX_PATH_LEN));
96e5c89e4eSSatish Balay #else /* Just punt */
97*c6a7a370SJeremy L Thompson   PetscCall(PetscStrlen(path, &len));
98*c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(rpath, path, len + 1)); /* assuming adequate buffer */
99e5c89e4eSSatish Balay #endif
100e5c89e4eSSatish Balay 
101e5c89e4eSSatish Balay   /* remove garbage some automounters put at the beginning of the path */
1029566063dSJacob Faibussowitsch   PetscCall(PetscStrncmp("/tmp_mnt/", rpath, 9, &flg));
103e5c89e4eSSatish Balay   if (flg) {
104*c6a7a370SJeremy L Thompson     PetscCall(PetscStrncpy(tmp3, rpath + 8, sizeof(tmp3)));
105*c6a7a370SJeremy L Thompson     PetscCall(PetscStrlen(tmp3, &len));
106*c6a7a370SJeremy L Thompson     PetscCall(PetscStrncpy(rpath, tmp3, len + 1));
107e5c89e4eSSatish Balay   }
1083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
109e5c89e4eSSatish Balay }
110