xref: /petsc/src/sys/fileio/fdir.c (revision 8a10d460d4e6f5b949e47072e9fa14e373d93611)
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
16 
17 PetscErrorCode PetscPathJoin(const char dname[],const char fname[],size_t n,char fullname[])
18 {
19   PetscErrorCode ierr;
20   size_t         l1,l2;
21   PetscFunctionBegin;
22   ierr = PetscStrlen(dname,&l1);CHKERRQ(ierr);
23   ierr = PetscStrlen(fname,&l2);CHKERRQ(ierr);
24   if ((l1+l2+2)>n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Path length is greater than buffer size");
25   ierr = PetscStrncpy(fullname,dname,n);CHKERRQ(ierr);
26   ierr = PetscStrlcat(fullname,"/",n);CHKERRQ(ierr);
27   ierr = PetscStrlcat(fullname,fname,n);CHKERRQ(ierr);
28   PetscFunctionReturn(0);
29 }
30 
31 PetscErrorCode PetscMkdir(const char dir[])
32 {
33   int            err;
34   PetscErrorCode ierr;
35   PetscBool      flg;
36 
37   PetscFunctionBegin;
38   ierr = PetscTestDirectory(dir,'w',&flg);CHKERRQ(ierr);
39   if (flg) PetscFunctionReturn(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   PetscFunctionReturn(0);
47 }
48 
49 /*@C
50   PetscMkdtemp - Create a folder with a unique name given a filename template.
51 
52   Not Collective
53 
54   Input Parameters:
55 . dir - file name template, the last six characters must be 'XXXXXX', and they will be modified upon return
56 
57   Level: developer
58 
59 .seealso: PetscMkdir()
60 @*/
61 PetscErrorCode PetscMkdtemp(char dir[])
62 {
63   PetscFunctionBegin;
64   dir = mkdtemp(dir);
65   if(!dir) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not create temporary dir using the template: %s",dir);
66   PetscFunctionReturn(0);
67 }
68 
69 #if defined(PETSC_HAVE_DIRECT_H)
70 PetscErrorCode PetscRMTree(const char dir[])
71 {
72   PetscErrorCode ierr;
73   struct _finddata_t data;
74   char loc[PETSC_MAX_PATH_LEN];
75   PetscBool flg1, flg2;
76 #if defined (PETSC_HAVE_STDINT_H)
77   intptr_t handle;
78 #else
79   long handle;
80   #endif
81 
82   PetscFunctionBegin;
83   ierr = PetscPathJoin(dir,"*",PETSC_MAX_PATH_LEN,loc);CHKERRQ(ierr);
84   handle = _findfirst(loc, &data);
85   if (handle == -1) {
86     PetscBool flg;
87     ierr = PetscTestDirectory(loc,'r',&flg);CHKERRQ(ierr);
88     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Cannot access directory to delete: %s",dir);
89     ierr = PetscTestFile(loc,'r',&flg);CHKERRQ(ierr);
90     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Specified path is a file - not a dir: %s",dir);
91     PetscFunctionReturn(0); /* perhaps the dir was not yet created */
92   }
93   while (_findnext(handle, &data) != -1) {
94     ierr = PetscStrcmp(data.name, ".",&flg1);CHKERRQ(ierr);
95     ierr = PetscStrcmp(data.name, "..",&flg2);CHKERRQ(ierr);
96     if (flg1 || flg2) continue;
97     ierr = PetscPathJoin(dir,data.name,PETSC_MAX_PATH_LEN,loc);CHKERRQ(ierr);
98     if (data.attrib & _A_SUBDIR) {
99       ierr = PetscRMTree(loc);CHKERRQ(ierr);
100     } else{
101       if (remove(loc)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete file: %s",loc);
102     }
103   }
104   _findclose(handle);
105   if (_rmdir(dir)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete dir: %s",dir);
106   PetscFunctionReturn(0);
107 }
108 #else
109 #include <dirent.h>
110 #include <unistd.h>
111 PetscErrorCode PetscRMTree(const char dir[])
112 {
113   PetscErrorCode ierr;
114   struct dirent *data;
115   char loc[PETSC_MAX_PATH_LEN];
116   PetscBool flg1, flg2;
117   DIR *dirp;
118   struct stat statbuf;
119 
120   PetscFunctionBegin;
121   dirp = opendir(dir);
122   if(!dirp) {
123     PetscBool flg;
124     ierr = PetscTestDirectory(dir,'r',&flg);CHKERRQ(ierr);
125     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Cannot access directory to delete: %s",dir);
126     ierr = PetscTestFile(dir,'r',&flg);CHKERRQ(ierr);
127     if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Specified path is a file - not a dir: %s",dir);
128     PetscFunctionReturn(0); /* perhaps the dir was not yet created */
129   }
130   while((data = readdir(dirp))) {
131     ierr = PetscStrcmp(data->d_name, ".",&flg1);CHKERRQ(ierr);
132     ierr = PetscStrcmp(data->d_name, "..",&flg2);CHKERRQ(ierr);
133     if (flg1 || flg2) continue;
134     ierr = PetscPathJoin(dir,data->d_name,PETSC_MAX_PATH_LEN,loc);CHKERRQ(ierr);
135     if (lstat(loc,&statbuf) <0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"cannot run lstat() on: %s",loc);
136     if (S_ISDIR(statbuf.st_mode)) {
137       ierr = PetscRMTree(loc);CHKERRQ(ierr);
138     } else {
139       if (unlink(loc)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete file: %s",loc);
140     }
141   }
142   closedir(dirp);
143   if (rmdir(dir)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Could not delete dir: %s",dir);
144   PetscFunctionReturn(0);
145 }
146 #endif
147