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