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