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