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: #include "apple_fdir.c"
 51: #endif

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

 56:   Not Collective

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

 61:   Level: developer

 63: .seealso: PetscMkdir()
 64: @*/
 65: PetscErrorCode PetscMkdtemp(char dir[])
 66: {
 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;

 76:     while (err && i < max_retry) {
 77:       PetscStrncpy(name,dir,sizeof(name));
 78:       PetscStrlen(name,&len);
 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:     PetscStrncpy(dir,name,len+1);
 86:   }
 87: #else
 88:   dir = mkdtemp(dir);
 89:   if (!dir) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not create temporary dir using the template: %s",dir);
 90: #endif
 91:   return(0);
 92: }

 94: #if defined(PETSC_HAVE_DIRECT_H)
 95: PetscErrorCode PetscRMTree(const char dir[])
 96: {
 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

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

146:   dirp = opendir(dir);
147:   if (!dirp) {
148:     PetscBool flg;
149:     PetscTestDirectory(dir,'r',&flg);
150:     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Cannot access directory to delete: %s",dir);
151:     PetscTestFile(dir,'r',&flg);
152:     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Specified path is a file - not a dir: %s",dir);
153:     return(0); /* perhaps the dir was not yet created */
154:   }
155:   while ((data = readdir(dirp))) {
156:     PetscStrcmp(data->d_name, ".",&flg1);
157:     PetscStrcmp(data->d_name, "..",&flg2);
158:     if (flg1 || flg2) continue;
159:     PetscPathJoin(dir,data->d_name,PETSC_MAX_PATH_LEN,loc);
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:       PetscRMTree(loc);
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:   return(0);
170: }
171: #endif