xref: /petsc/src/sys/fileio/grpath.c (revision 84df9cb40eca90ea9b18a456fab7a4ecc7f6c1a4)
1 
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
21 
22 #undef __FUNCT__
23 #define __FUNCT__ "PetscGetRealPath"
24 /*@C
25    PetscGetRealPath - Get the path without symbolic links etc. and in absolute form.
26 
27    Not Collective
28 
29    Input Parameter:
30 .  path - path to resolve
31 
32    Output Parameter:
33 .  rpath - resolved path
34 
35    Level: developer
36 
37    Notes:
38    rpath is assumed to be of length PETSC_MAX_PATH_LEN.
39 
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.
45 
46    Concepts: real path
47    Concepts: path^real
48 
49 .seealso: PetscGetFullPath()
50 @*/
51 PetscErrorCode  PetscGetRealPath(const char path[],char rpath[])
52 {
53   PetscErrorCode ierr;
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
61 
62   PetscFunctionBegin;
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   ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
68   ierr = PetscStrlen(rpath,&N);CHKERRQ(ierr);
69   while (N) {
70     ierr = PetscStrncpy(tmp1,rpath,N);CHKERRQ(ierr);
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         ierr = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
77         ierr = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
78         ierr = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
79         m    = len1 - len2;
80         ierr = PetscStrncpy(tmp4,tmp1,m);CHKERRQ(ierr);
81         tmp4[m] = 0;
82         ierr = PetscStrlen(tmp4,&len);CHKERRQ(ierr);
83         ierr = PetscStrncat(tmp4,"/",PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
84         ierr = PetscStrlen(tmp4,&len);CHKERRQ(ierr);
85         ierr = PetscStrncat(tmp4,tmp3,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
86         ierr = PetscGetRealPath(tmp4,rpath);CHKERRQ(ierr);
87         ierr = PetscStrlen(rpath,&len);CHKERRQ(ierr);
88         ierr = PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
89       } else {
90         ierr = PetscGetRealPath(tmp3,tmp1);CHKERRQ(ierr);
91         ierr = PetscStrncpy(rpath,tmp1,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
92         ierr = PetscStrlen(rpath,&len);CHKERRQ(ierr);
93         ierr = PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
94       }
95       PetscFunctionReturn(0);
96     }
97     ierr = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
98     if (tmp2) {
99       ierr = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
100       ierr = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
101       N    = len1 - len2;
102     } else {
103       ierr = PetscStrlen(tmp1,&N);CHKERRQ(ierr);
104     }
105   }
106   ierr = PetscStrncpy(rpath,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
107 #else /* Just punt */
108   ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
109 #endif
110 
111   /* remove garbage some automounters put at the beginning of the path */
112   ierr = PetscStrncmp("/tmp_mnt/",rpath,9,&flg);CHKERRQ(ierr);
113   if (flg) {
114     ierr = PetscStrcpy(tmp3,rpath + 8);CHKERRQ(ierr);
115     ierr = PetscStrcpy(rpath,tmp3);CHKERRQ(ierr);
116   }
117   PetscFunctionReturn(0);
118 }
119