Actual source code: fdir.c

  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: #if defined(PETSC_USING_DARWIN)
 50: /*
 51:     Apple's mkdtemp() crashes under Valgrind so this replaces it with a version that does not crash under valgrind
 52: */
 53: #include "apple_fdir.h"
 54: #endif

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

 59:   Not Collective

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

 64:   Level: developer

 66: .seealso: PetscMkdir()
 67: @*/
 68: PetscErrorCode PetscMkdtemp(char dir[])
 69: {
 71: #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_IO_H) && defined(PETSC_HAVE__MKDIR) && defined(PETSC_HAVE_DIRECT_H)
 72:   {
 73:     int            err = 1;
 74:     char           name[PETSC_MAX_PATH_LEN];
 75:     PetscInt       i = 0,max_retry = 26;
 76:     size_t         len;

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

 97: #if defined(PETSC_HAVE_DIRECT_H)
 98: PetscErrorCode PetscRMTree(const char dir[])
 99: {
101:   struct _finddata_t data;
102:   char loc[PETSC_MAX_PATH_LEN];
103:   PetscBool flg1, flg2;
104: #if defined (PETSC_HAVE_STDINT_H)
105:   intptr_t handle;
106: #else
107:   long handle;
108:   #endif

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

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