Actual source code: grpath.c
1: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for realpath() */
2: #include <petscsys.h>
3: #if defined(PETSC_HAVE_PWD_H)
4: #include <pwd.h>
5: #endif
6: #include <ctype.h>
7: #include <sys/stat.h>
8: #if defined(PETSC_HAVE_UNISTD_H)
9: #include <unistd.h>
10: #endif
11: #if defined(PETSC_HAVE_SYS_UTSNAME_H)
12: #include <sys/utsname.h>
13: #endif
14: #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
15: #include <sys/systeminfo.h>
16: #endif
18: /*@C
19: PetscGetRealPath - Get the path without symbolic links etc. and in absolute form.
21: Not Collective
23: Input Parameter:
24: . path - path to resolve
26: Output Parameter:
27: . rpath - resolved path
29: Level: developer
31: Notes:
32: rpath is assumed to be of length `PETSC_MAX_PATH_LEN`.
34: Systems that use the automounter often generate absolute paths
35: of the form "/tmp_mnt....". However, the automounter will fail to
36: mount this path if it is not already mounted, so we remove this from
37: the head of the line. This may cause problems if, for some reason,
38: /tmp_mnt is valid and not the result of the automounter.
40: .seealso: `PetscGetFullPath()`
41: @*/
42: PetscErrorCode PetscGetRealPath(const char path[], char rpath[])
43: {
44: char tmp3[PETSC_MAX_PATH_LEN];
45: PetscBool flg;
46: #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK)
47: char tmp1[PETSC_MAX_PATH_LEN], tmp4[PETSC_MAX_PATH_LEN], *tmp2;
48: size_t N, len, len1, len2;
49: int n, m;
50: #endif
52: PetscFunctionBegin;
53: #if defined(PETSC_HAVE_REALPATH)
54: PetscCheck(realpath(path, rpath), PETSC_COMM_SELF, PETSC_ERR_LIB, "realpath()");
55: #elif defined(PETSC_HAVE_READLINK)
56: /* Algorithm: we move through the path, replacing links with the real paths. */
57: PetscCall(PetscStrcpy(rpath, path));
58: PetscCall(PetscStrlen(rpath, &N));
59: while (N) {
60: PetscCall(PetscStrncpy(tmp1, rpath, N));
61: tmp1[N] = 0;
62: n = readlink(tmp1, tmp3, PETSC_MAX_PATH_LEN);
63: if (n > 0) {
64: tmp3[n] = 0; /* readlink does not automatically add 0 to string end */
65: if (tmp3[0] != '/') {
66: PetscCall(PetscStrchr(tmp1, '/', &tmp2));
67: PetscCall(PetscStrlen(tmp1, &len1));
68: PetscCall(PetscStrlen(tmp2, &len2));
69: m = len1 - len2;
70: PetscCall(PetscStrncpy(tmp4, tmp1, m));
71: tmp4[m] = 0;
72: PetscCall(PetscStrlen(tmp4, &len));
73: PetscCall(PetscStrlcat(tmp4, "/", PETSC_MAX_PATH_LEN));
74: PetscCall(PetscStrlcat(tmp4, tmp3, PETSC_MAX_PATH_LEN));
75: PetscCall(PetscGetRealPath(tmp4, rpath));
76: PetscCall(PetscStrlcat(rpath, path + N, PETSC_MAX_PATH_LEN));
77: } else {
78: PetscCall(PetscGetRealPath(tmp3, tmp1));
79: PetscCall(PetscStrncpy(rpath, tmp1, PETSC_MAX_PATH_LEN));
80: PetscCall(PetscStrlcat(rpath, path + N, PETSC_MAX_PATH_LEN));
81: }
82: PetscFunctionReturn(PETSC_SUCCESS);
83: }
84: PetscCall(PetscStrchr(tmp1, '/', &tmp2));
85: if (tmp2) {
86: PetscCall(PetscStrlen(tmp1, &len1));
87: PetscCall(PetscStrlen(tmp2, &len2));
88: N = len1 - len2;
89: } else {
90: PetscCall(PetscStrlen(tmp1, &N));
91: }
92: }
93: PetscCall(PetscStrncpy(rpath, path, PETSC_MAX_PATH_LEN));
94: #else /* Just punt */
95: PetscCall(PetscStrcpy(rpath, path));
96: #endif
98: /* remove garbage some automounters put at the beginning of the path */
99: PetscCall(PetscStrncmp("/tmp_mnt/", rpath, 9, &flg));
100: if (flg) {
101: PetscCall(PetscStrcpy(tmp3, rpath + 8));
102: PetscCall(PetscStrcpy(rpath, tmp3));
103: }
104: PetscFunctionReturn(PETSC_SUCCESS);
105: }