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