Actual source code: grpath.c
petsc-3.8.4 2018-03-24
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: Concepts: real path
41: Concepts: path^real
43: .seealso: PetscGetFullPath()
44: @*/
45: PetscErrorCode PetscGetRealPath(const char path[],char rpath[])
46: {
48: char tmp3[PETSC_MAX_PATH_LEN];
49: PetscBool flg;
50: #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK)
51: char tmp1[PETSC_MAX_PATH_LEN],tmp4[PETSC_MAX_PATH_LEN],*tmp2;
52: size_t N,len,len1,len2;
53: int n,m;
54: #endif
57: #if defined(PETSC_HAVE_REALPATH)
58: if (!realpath(path,rpath)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"realpath()");
59: #elif defined(PETSC_HAVE_READLINK)
60: /* Algorithm: we move through the path, replacing links with the real paths. */
61: PetscStrcpy(rpath,path);
62: PetscStrlen(rpath,&N);
63: while (N) {
64: PetscStrncpy(tmp1,rpath,N);
65: tmp1[N] = 0;
66: n = readlink(tmp1,tmp3,PETSC_MAX_PATH_LEN);
67: if (n > 0) {
68: tmp3[n] = 0; /* readlink does not automatically add 0 to string end */
69: if (tmp3[0] != '/') {
70: PetscStrchr(tmp1,'/',&tmp2);
71: PetscStrlen(tmp1,&len1);
72: PetscStrlen(tmp2,&len2);
73: m = len1 - len2;
74: PetscStrncpy(tmp4,tmp1,m);
75: tmp4[m] = 0;
76: PetscStrlen(tmp4,&len);
77: PetscStrncat(tmp4,"/",PETSC_MAX_PATH_LEN - len);
78: PetscStrlen(tmp4,&len);
79: PetscStrncat(tmp4,tmp3,PETSC_MAX_PATH_LEN - len);
80: PetscGetRealPath(tmp4,rpath);
81: PetscStrlen(rpath,&len);
82: PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);
83: } else {
84: PetscGetRealPath(tmp3,tmp1);
85: PetscStrncpy(rpath,tmp1,PETSC_MAX_PATH_LEN);
86: PetscStrlen(rpath,&len);
87: PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);
88: }
89: return(0);
90: }
91: PetscStrchr(tmp1,'/',&tmp2);
92: if (tmp2) {
93: PetscStrlen(tmp1,&len1);
94: PetscStrlen(tmp2,&len2);
95: N = len1 - len2;
96: } else {
97: PetscStrlen(tmp1,&N);
98: }
99: }
100: PetscStrncpy(rpath,path,PETSC_MAX_PATH_LEN);
101: #else /* Just punt */
102: PetscStrcpy(rpath,path);
103: #endif
105: /* remove garbage some automounters put at the beginning of the path */
106: PetscStrncmp("/tmp_mnt/",rpath,9,&flg);
107: if (flg) {
108: PetscStrcpy(tmp3,rpath + 8);
109: PetscStrcpy(rpath,tmp3);
110: }
111: return(0);
112: }