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