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