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