xref: /petsc/src/sys/fileio/grpath.c (revision 2f6eced2a19e978d64f27de66fbc6c26cc5c7934) !
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/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    Concepts: real path
41    Concepts: path^real
42 
43 .seealso: PetscGetFullPath()
44 @*/
45 PetscErrorCode  PetscGetRealPath(const char path[],char rpath[])
46 {
47   PetscErrorCode ierr;
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
55 
56   PetscFunctionBegin;
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   ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
62   ierr = PetscStrlen(rpath,&N);CHKERRQ(ierr);
63   while (N) {
64     ierr    = PetscStrncpy(tmp1,rpath,N);CHKERRQ(ierr);
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         ierr    = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
71         ierr    = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
72         ierr    = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
73         m       = len1 - len2;
74         ierr    = PetscStrncpy(tmp4,tmp1,m);CHKERRQ(ierr);
75         tmp4[m] = 0;
76         ierr    = PetscStrlen(tmp4,&len);CHKERRQ(ierr);
77         ierr    = PetscStrncat(tmp4,"/",PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
78         ierr    = PetscStrlen(tmp4,&len);CHKERRQ(ierr);
79         ierr    = PetscStrncat(tmp4,tmp3,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
80         ierr    = PetscGetRealPath(tmp4,rpath);CHKERRQ(ierr);
81         ierr    = PetscStrlen(rpath,&len);CHKERRQ(ierr);
82         ierr    = PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
83       } else {
84         ierr = PetscGetRealPath(tmp3,tmp1);CHKERRQ(ierr);
85         ierr = PetscStrncpy(rpath,tmp1,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
86         ierr = PetscStrlen(rpath,&len);CHKERRQ(ierr);
87         ierr = PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
88       }
89       PetscFunctionReturn(0);
90     }
91     ierr = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
92     if (tmp2) {
93       ierr = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
94       ierr = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
95       N    = len1 - len2;
96     } else {
97       ierr = PetscStrlen(tmp1,&N);CHKERRQ(ierr);
98     }
99   }
100   ierr = PetscStrncpy(rpath,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
101 #else /* Just punt */
102   ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
103 #endif
104 
105   /* remove garbage some automounters put at the beginning of the path */
106   ierr = PetscStrncmp("/tmp_mnt/",rpath,9,&flg);CHKERRQ(ierr);
107   if (flg) {
108     ierr = PetscStrcpy(tmp3,rpath + 8);CHKERRQ(ierr);
109     ierr = PetscStrcpy(rpath,tmp3);CHKERRQ(ierr);
110   }
111   PetscFunctionReturn(0);
112 }
113