Actual source code: fdir.c
petsc-3.14.6 2021-03-30
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