1 #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for lstat() */ 2 #include <petscsys.h> 3 #include <sys/stat.h> 4 #if defined(PETSC_HAVE_DIRECT_H) 5 #include <direct.h> 6 #endif 7 #if defined(PETSC_HAVE_IO_H) 8 #include <io.h> 9 #endif 10 #if defined (PETSC_HAVE_STDINT_H) 11 #include <stdint.h> 12 #endif 13 #if defined(PETSC_HAVE_UNISTD_H) /* for mkdtemp */ 14 #include <unistd.h> 15 #endif 16 17 PetscErrorCode PetscPathJoin(const char dname[],const char fname[],size_t n,char fullname[]) 18 { 19 size_t l1,l2; 20 PetscFunctionBegin; 21 CHKERRQ(PetscStrlen(dname,&l1)); 22 CHKERRQ(PetscStrlen(fname,&l2)); 23 PetscCheckFalse((l1+l2+2)>n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Path length is greater than buffer size"); 24 CHKERRQ(PetscStrncpy(fullname,dname,n)); 25 CHKERRQ(PetscStrlcat(fullname,"/",n)); 26 CHKERRQ(PetscStrlcat(fullname,fname,n)); 27 PetscFunctionReturn(0); 28 } 29 30 PetscErrorCode PetscMkdir(const char dir[]) 31 { 32 int err; 33 PetscBool flg; 34 35 PetscFunctionBegin; 36 CHKERRQ(PetscTestDirectory(dir,'w',&flg)); 37 if (flg) PetscFunctionReturn(0); 38 #if defined(PETSC_HAVE__MKDIR) && defined(PETSC_HAVE_DIRECT_H) 39 err = _mkdir(dir); 40 #else 41 err = mkdir(dir,S_IRWXU|S_IRGRP|S_IXGRP); 42 #endif 43 PetscCheckFalse(err,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not create dir: %s",dir); 44 PetscFunctionReturn(0); 45 } 46 47 #if defined(PETSC_USING_DARWIN) 48 /* 49 Apple's mkdtemp() crashes under Valgrind so this replaces it with a version that does not crash under valgrind 50 */ 51 #include "apple_fdir.h" 52 #endif 53 54 /*@C 55 PetscMkdtemp - Create a folder with a unique name given a filename template. 56 57 Not Collective 58 59 Input Parameters: 60 . dir - file name template, the last six characters must be 'XXXXXX', and they will be modified upon return 61 62 Level: developer 63 64 .seealso: PetscMkdir() 65 @*/ 66 PetscErrorCode PetscMkdtemp(char dir[]) 67 { 68 PetscFunctionBegin; 69 #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_IO_H) && defined(PETSC_HAVE__MKDIR) && defined(PETSC_HAVE_DIRECT_H) 70 { 71 int err = 1; 72 char name[PETSC_MAX_PATH_LEN]; 73 PetscInt i = 0,max_retry = 26; 74 size_t len; 75 PetscErrorCode ierr; 76 77 while (err && i < max_retry) { 78 CHKERRQ(PetscStrncpy(name,dir,sizeof(name))); 79 CHKERRQ(PetscStrlen(name,&len)); 80 err = _mktemp_s(name,len+1); 81 PetscCheckFalse(err,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not generate a unique name using the template: %s",dir); 82 err = _mkdir(name); 83 i++; 84 } 85 PetscCheckFalse(err,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Exceeds maximum retry time when creating temporary dir using the template: %s",dir); 86 CHKERRQ(PetscStrncpy(dir,name,len+1)); 87 } 88 #else 89 dir = mkdtemp(dir); 90 PetscCheckFalse(!dir,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not create temporary dir"); 91 #endif 92 PetscFunctionReturn(0); 93 } 94 95 #if defined(PETSC_HAVE_DIRECT_H) 96 PetscErrorCode PetscRMTree(const char dir[]) 97 { 98 PetscErrorCode ierr; 99 struct _finddata_t data; 100 char loc[PETSC_MAX_PATH_LEN]; 101 PetscBool flg1, flg2; 102 #if defined (PETSC_HAVE_STDINT_H) 103 intptr_t handle; 104 #else 105 long handle; 106 #endif 107 108 PetscFunctionBegin; 109 CHKERRQ(PetscPathJoin(dir,"*",PETSC_MAX_PATH_LEN,loc)); 110 handle = _findfirst(loc, &data); 111 if (handle == -1) { 112 PetscBool flg; 113 CHKERRQ(PetscTestDirectory(loc,'r',&flg)); 114 PetscCheckFalse(flg,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Cannot access directory to delete: %s",dir); 115 CHKERRQ(PetscTestFile(loc,'r',&flg)); 116 PetscCheckFalse(flg,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Specified path is a file - not a dir: %s",dir); 117 PetscFunctionReturn(0); /* perhaps the dir was not yet created */ 118 } 119 while (_findnext(handle, &data) != -1) { 120 CHKERRQ(PetscStrcmp(data.name, ".",&flg1)); 121 CHKERRQ(PetscStrcmp(data.name, "..",&flg2)); 122 if (flg1 || flg2) continue; 123 CHKERRQ(PetscPathJoin(dir,data.name,PETSC_MAX_PATH_LEN,loc)); 124 if (data.attrib & _A_SUBDIR) { 125 CHKERRQ(PetscRMTree(loc)); 126 } else{ 127 PetscCheckFalse(remove(loc),PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete file: %s",loc); 128 } 129 } 130 _findclose(handle); 131 PetscCheckFalse(_rmdir(dir),PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete dir: %s",dir); 132 PetscFunctionReturn(0); 133 } 134 #else 135 #include <dirent.h> 136 #include <unistd.h> 137 PetscErrorCode PetscRMTree(const char dir[]) 138 { 139 struct dirent *data; 140 char loc[PETSC_MAX_PATH_LEN]; 141 PetscBool flg1, flg2; 142 DIR *dirp; 143 struct stat statbuf; 144 145 PetscFunctionBegin; 146 dirp = opendir(dir); 147 if (!dirp) { 148 PetscBool flg; 149 CHKERRQ(PetscTestDirectory(dir,'r',&flg)); 150 PetscCheckFalse(flg,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Cannot access directory to delete: %s",dir); 151 CHKERRQ(PetscTestFile(dir,'r',&flg)); 152 PetscCheckFalse(flg,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Specified path is a file - not a dir: %s",dir); 153 PetscFunctionReturn(0); /* perhaps the dir was not yet created */ 154 } 155 while ((data = readdir(dirp))) { 156 CHKERRQ(PetscStrcmp(data->d_name, ".",&flg1)); 157 CHKERRQ(PetscStrcmp(data->d_name, "..",&flg2)); 158 if (flg1 || flg2) continue; 159 CHKERRQ(PetscPathJoin(dir,data->d_name,PETSC_MAX_PATH_LEN,loc)); 160 PetscCheckFalse(lstat(loc,&statbuf) <0,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"cannot run lstat() on: %s",loc); 161 if (S_ISDIR(statbuf.st_mode)) { 162 CHKERRQ(PetscRMTree(loc)); 163 } else { 164 PetscCheckFalse(unlink(loc),PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete file: %s",loc); 165 } 166 } 167 closedir(dirp); 168 PetscCheckFalse(rmdir(dir),PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete dir: %s",dir); 169 PetscFunctionReturn(0); 170 } 171 #endif 172