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