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
17
18 /*@C
19 PetscGetRealPath - Get the path without symbolic links etc. and in absolute form.
20
21 Not Collective
22
23 Input Parameter:
24 . path - path to resolve
25
26 Output Parameter:
27 . rpath - resolved path
28
29 Level: developer
30
31 Notes:
32 rpath is assumed to be of length PETSC_MAX_PATH_LEN.
33
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.
39
40
41 .seealso: PetscGetFullPath()
42 @*/
PetscGetRealPath(const char path[],char rpath[])43 PetscErrorCode PetscGetRealPath(const char path[],char rpath[])
44 {
45 PetscErrorCode ierr;
46 char tmp3[PETSC_MAX_PATH_LEN];
47 PetscBool flg;
48 #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK)
49 char tmp1[PETSC_MAX_PATH_LEN],tmp4[PETSC_MAX_PATH_LEN],*tmp2;
50 size_t N,len,len1,len2;
51 int n,m;
52 #endif
53
54 PetscFunctionBegin;
55 #if defined(PETSC_HAVE_REALPATH)
56 if (!realpath(path,rpath)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"realpath()");
57 #elif defined(PETSC_HAVE_READLINK)
58 /* Algorithm: we move through the path, replacing links with the real paths. */
59 ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
60 ierr = PetscStrlen(rpath,&N);CHKERRQ(ierr);
61 while (N) {
62 ierr = PetscStrncpy(tmp1,rpath,N);CHKERRQ(ierr);
63 tmp1[N] = 0;
64 n = readlink(tmp1,tmp3,PETSC_MAX_PATH_LEN);
65 if (n > 0) {
66 tmp3[n] = 0; /* readlink does not automatically add 0 to string end */
67 if (tmp3[0] != '/') {
68 ierr = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
69 ierr = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
70 ierr = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
71 m = len1 - len2;
72 ierr = PetscStrncpy(tmp4,tmp1,m);CHKERRQ(ierr);
73 tmp4[m] = 0;
74 ierr = PetscStrlen(tmp4,&len);CHKERRQ(ierr);
75 ierr = PetscStrlcat(tmp4,"/",PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
76 ierr = PetscStrlcat(tmp4,tmp3,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
77 ierr = PetscGetRealPath(tmp4,rpath);CHKERRQ(ierr);
78 ierr = PetscStrlcat(rpath,path+N,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
79 } else {
80 ierr = PetscGetRealPath(tmp3,tmp1);CHKERRQ(ierr);
81 ierr = PetscStrncpy(rpath,tmp1,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
82 ierr = PetscStrlcat(rpath,path+N,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
83 }
84 PetscFunctionReturn(0);
85 }
86 ierr = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
87 if (tmp2) {
88 ierr = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
89 ierr = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
90 N = len1 - len2;
91 } else {
92 ierr = PetscStrlen(tmp1,&N);CHKERRQ(ierr);
93 }
94 }
95 ierr = PetscStrncpy(rpath,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
96 #else /* Just punt */
97 ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
98 #endif
99
100 /* remove garbage some automounters put at the beginning of the path */
101 ierr = PetscStrncmp("/tmp_mnt/",rpath,9,&flg);CHKERRQ(ierr);
102 if (flg) {
103 ierr = PetscStrcpy(tmp3,rpath + 8);CHKERRQ(ierr);
104 ierr = PetscStrcpy(rpath,tmp3);CHKERRQ(ierr);
105 }
106 PetscFunctionReturn(0);
107 }
108