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