Actual source code: grpath.c
petsc-3.5.4 2015-05-23
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
20: /*@C
21: PetscGetRealPath - Get the path without symbolic links etc. and in absolute form.
23: Not Collective
25: Input Parameter:
26: . path - path to resolve
28: Output Parameter:
29: . rpath - resolved path
31: Level: developer
33: Notes:
34: rpath is assumed to be of length PETSC_MAX_PATH_LEN.
36: Systems that use the automounter often generate absolute paths
37: of the form "/tmp_mnt....". However, the automounter will fail to
38: mount this path if it is not already mounted, so we remove this from
39: the head of the line. This may cause problems if, for some reason,
40: /tmp_mnt is valid and not the result of the automounter.
42: Concepts: real path
43: Concepts: path^real
45: .seealso: PetscGetFullPath()
46: @*/
47: PetscErrorCode PetscGetRealPath(const char path[],char rpath[])
48: {
50: char tmp3[PETSC_MAX_PATH_LEN];
51: PetscBool flg;
52: #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK)
53: char tmp1[PETSC_MAX_PATH_LEN],tmp4[PETSC_MAX_PATH_LEN],*tmp2;
54: size_t N,len,len1,len2;
55: int n,m;
56: #endif
59: #if defined(PETSC_HAVE_REALPATH)
60: if (!realpath(path,rpath)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"realpath()");
61: #elif defined(PETSC_HAVE_READLINK)
62: /* Algorithm: we move through the path, replacing links with the real paths. */
63: PetscStrcpy(rpath,path);
64: PetscStrlen(rpath,&N);
65: while (N) {
66: PetscStrncpy(tmp1,rpath,N);
67: tmp1[N] = 0;
68: n = readlink(tmp1,tmp3,PETSC_MAX_PATH_LEN);
69: if (n > 0) {
70: tmp3[n] = 0; /* readlink does not automatically add 0 to string end */
71: if (tmp3[0] != '/') {
72: PetscStrchr(tmp1,'/',&tmp2);
73: PetscStrlen(tmp1,&len1);
74: PetscStrlen(tmp2,&len2);
75: m = len1 - len2;
76: PetscStrncpy(tmp4,tmp1,m);
77: tmp4[m] = 0;
78: PetscStrlen(tmp4,&len);
79: PetscStrncat(tmp4,"/",PETSC_MAX_PATH_LEN - len);
80: PetscStrlen(tmp4,&len);
81: PetscStrncat(tmp4,tmp3,PETSC_MAX_PATH_LEN - len);
82: PetscGetRealPath(tmp4,rpath);
83: PetscStrlen(rpath,&len);
84: PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);
85: } else {
86: PetscGetRealPath(tmp3,tmp1);
87: PetscStrncpy(rpath,tmp1,PETSC_MAX_PATH_LEN);
88: PetscStrlen(rpath,&len);
89: PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);
90: }
91: return(0);
92: }
93: PetscStrchr(tmp1,'/',&tmp2);
94: if (tmp2) {
95: PetscStrlen(tmp1,&len1);
96: PetscStrlen(tmp2,&len2);
97: N = len1 - len2;
98: } else {
99: PetscStrlen(tmp1,&N);
100: }
101: }
102: PetscStrncpy(rpath,path,PETSC_MAX_PATH_LEN);
103: #else /* Just punt */
104: PetscStrcpy(rpath,path);
105: #endif
107: /* remove garbage some automounters put at the beginning of the path */
108: PetscStrncmp("/tmp_mnt/",rpath,9,&flg);
109: if (flg) {
110: PetscStrcpy(tmp3,rpath + 8);
111: PetscStrcpy(rpath,tmp3);
112: }
113: return(0);
114: }