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_HAVE_VALGRIND_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