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