Actual source code: fdir.c

petsc-3.12.5 2020-03-29
Report Typos and Errors
  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

 17: PetscErrorCode PetscPathJoin(const char dname[],const char fname[],size_t n,char fullname[])
 18: {
 20:   size_t         l1,l2;
 22:   PetscStrlen(dname,&l1);
 23:   PetscStrlen(fname,&l2);
 24:   if ((l1+l2+2)>n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Path length is greater than buffer size");
 25:   PetscStrncpy(fullname,dname,n);
 26:   PetscStrlcat(fullname,"/",n);
 27:   PetscStrlcat(fullname,fname,n);
 28:   return(0);
 29: }

 31: PetscErrorCode PetscMkdir(const char dir[])
 32: {
 33:   int            err;
 35:   PetscBool      flg;

 38:   PetscTestDirectory(dir,'w',&flg);
 39:   if (flg) return(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:   return(0);
 47: }

 49: /*@C
 50:   PetscMkdtemp - Create a folder with a unique name given a filename template.

 52:   Not Collective

 54:   Input Parameters:
 55: . dir - file name template, the last six characters must be 'XXXXXX', and they will be modified upon return

 57:   Level: developer

 59: .seealso: PetscMkdir()
 60: @*/
 61: PetscErrorCode PetscMkdtemp(char dir[])
 62: {
 64: #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_IO_H) && defined(PETSC_HAVE__MKDIR) && defined(PETSC_HAVE_DIRECT_H)
 65:   {
 66:     int            err = 1;
 67:     char           name[PETSC_MAX_PATH_LEN];
 68:     PetscInt       i = 0,max_retry = 26;
 69:     size_t         len;

 72:     while (err && i < max_retry) {
 73:       PetscStrncpy(name,dir,sizeof(name));
 74:       PetscStrlen(name,&len);
 75:       err = _mktemp_s(name,len+1);
 76:       if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not generate a unique name using the template: %s",dir);
 77:       err = _mkdir(name);
 78:       i++;
 79:     }
 80:     if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Exceeds maximum retry time when creating temporary dir using the template: %s",dir);
 81:     PetscStrncpy(dir,name,len+1);
 82:   }
 83: #else
 84:   dir = mkdtemp(dir);
 85:   if(!dir) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not create temporary dir using the template: %s",dir);
 86: #endif
 87:   return(0);
 88: }

 90: #if defined(PETSC_HAVE_DIRECT_H)
 91: PetscErrorCode PetscRMTree(const char dir[])
 92: {
 94:   struct _finddata_t data;
 95:   char loc[PETSC_MAX_PATH_LEN];
 96:   PetscBool flg1, flg2;
 97: #if defined (PETSC_HAVE_STDINT_H)
 98:   intptr_t handle;
 99: #else
100:   long handle;
101:   #endif

104:   PetscPathJoin(dir,"*",PETSC_MAX_PATH_LEN,loc);
105:   handle = _findfirst(loc, &data);
106:   if (handle == -1) {
107:     PetscBool flg;
108:     PetscTestDirectory(loc,'r',&flg);
109:     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Cannot access directory to delete: %s",dir);
110:     PetscTestFile(loc,'r',&flg);
111:     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Specified path is a file - not a dir: %s",dir);
112:     return(0); /* perhaps the dir was not yet created */
113:   }
114:   while (_findnext(handle, &data) != -1) {
115:     PetscStrcmp(data.name, ".",&flg1);
116:     PetscStrcmp(data.name, "..",&flg2);
117:     if (flg1 || flg2) continue;
118:     PetscPathJoin(dir,data.name,PETSC_MAX_PATH_LEN,loc);
119:     if (data.attrib & _A_SUBDIR) {
120:       PetscRMTree(loc);
121:     } else{
122:       if (remove(loc)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete file: %s",loc);
123:     }
124:   }
125:   _findclose(handle);
126:   if (_rmdir(dir)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete dir: %s",dir);
127:   return(0);
128: }
129: #else
130: #include <dirent.h>
131: #include <unistd.h>
132: PetscErrorCode PetscRMTree(const char dir[])
133: {
135:   struct dirent *data;
136:   char loc[PETSC_MAX_PATH_LEN];
137:   PetscBool flg1, flg2;
138:   DIR *dirp;
139:   struct stat statbuf;

142:   dirp = opendir(dir);
143:   if(!dirp) {
144:     PetscBool flg;
145:     PetscTestDirectory(dir,'r',&flg);
146:     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Cannot access directory to delete: %s",dir);
147:     PetscTestFile(dir,'r',&flg);
148:     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Specified path is a file - not a dir: %s",dir);
149:     return(0); /* perhaps the dir was not yet created */
150:   }
151:   while((data = readdir(dirp))) {
152:     PetscStrcmp(data->d_name, ".",&flg1);
153:     PetscStrcmp(data->d_name, "..",&flg2);
154:     if (flg1 || flg2) continue;
155:     PetscPathJoin(dir,data->d_name,PETSC_MAX_PATH_LEN,loc);
156:     if (lstat(loc,&statbuf) <0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"cannot run lstat() on: %s",loc);
157:     if (S_ISDIR(statbuf.st_mode)) {
158:       PetscRMTree(loc);
159:     } else {
160:       if (unlink(loc)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete file: %s",loc);
161:     }
162:   }
163:   closedir(dirp);
164:   if (rmdir(dir)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete dir: %s",dir);
165:   return(0);
166: }
167: #endif