|
33 | 33 | # include <windows.h> //FindFirstFileW ... |
34 | 34 | #else |
35 | 35 | # include <dirent.h> //opendir ... |
| 36 | +# ifndef _IS_NO_dirent_d_type |
| 37 | +# ifdef __QNX__ |
| 38 | +# define _IS_NO_dirent_d_type 1 |
| 39 | +# else |
| 40 | +# define _IS_NO_dirent_d_type 0 |
| 41 | +# endif |
| 42 | +# endif |
| 43 | +# if (_IS_NO_dirent_d_type) |
| 44 | +# include <sys/stat.h> //stat |
| 45 | +# endif |
36 | 46 | #endif |
37 | 47 |
|
38 | 48 | #ifdef _WIN32 |
@@ -101,43 +111,88 @@ void hdiff_dirClose(hdiff_TDirHandle dirHandle){ |
101 | 111 | free(finder); |
102 | 112 | } |
103 | 113 | } |
| 114 | +// _WIN32 |
| 115 | +#else |
| 116 | +// linux-like |
104 | 117 |
|
105 | | -#else // _WIN32 |
| 118 | + struct _hdiff_TDIRData{ |
| 119 | + DIR* handle; |
| 120 | + #if (_IS_NO_dirent_d_type) |
| 121 | + char dirName[hpatch_kPathMaxSize]; |
| 122 | + #endif |
| 123 | + }; |
106 | 124 |
|
107 | 125 | hdiff_TDirHandle hdiff_dirOpenForRead(const char* dir_utf8){ |
108 | | - hdiff_TDirHandle h=opendir(dir_utf8); |
109 | | - if (!h) return 0; //error |
110 | | - return h; |
| 126 | + _hdiff_TDIRData* pdir=(_hdiff_TDIRData*)malloc(sizeof(_hdiff_TDIRData)); |
| 127 | + if (pdir==0) return 0; //error |
| 128 | + pdir->handle=opendir(dir_utf8); |
| 129 | + if (!pdir->handle) { hdiff_dirClose(pdir); return 0; }//error |
| 130 | + { |
| 131 | + #if (_IS_NO_dirent_d_type) |
| 132 | + const size_t slen=strlen(dir_utf8); |
| 133 | + if (slen>hpatch_kPathMaxSize-1) { hdiff_dirClose(pdir); return 0; }//error |
| 134 | + memcpy(pdir->dirName,dir_utf8,slen+1); |
| 135 | + #endif |
| 136 | + } |
| 137 | + return pdir; |
111 | 138 | } |
112 | 139 |
|
113 | 140 | hpatch_BOOL hdiff_dirNext(hdiff_TDirHandle dirHandle,hpatch_TPathType *out_type,const char** out_subName_utf8){ |
114 | 141 | assert(dirHandle!=0); |
115 | | - DIR* pdir =(DIR*)dirHandle; |
116 | | - struct dirent* pdirent = readdir(pdir); |
117 | | - if (pdirent==0){ |
118 | | - *out_subName_utf8=0; //finish |
119 | | - return hpatch_TRUE; |
120 | | - } |
121 | | - |
122 | | - if (pdirent->d_type==DT_DIR){ |
123 | | - *out_type=kPathType_dir; |
124 | | - *out_subName_utf8=pdirent->d_name; |
125 | | - return hpatch_TRUE; |
126 | | - }else if (pdirent->d_type==DT_REG){ |
127 | | - *out_type=kPathType_file; |
| 142 | + _hdiff_TDIRData* pdir=(_hdiff_TDIRData*)dirHandle; |
| 143 | + while (1){ |
| 144 | + struct dirent* pdirent = readdir(pdir->handle); |
| 145 | + if (pdirent==0){ |
| 146 | + *out_subName_utf8=0; //finish |
| 147 | + return hpatch_TRUE; |
| 148 | + } |
| 149 | + if ((strcmp(pdirent->d_name,".")==0) || (strcmp(pdirent->d_name,"..")==0)) |
| 150 | + continue; //next |
| 151 | + |
| 152 | + #if (_IS_NO_dirent_d_type) |
| 153 | + { |
| 154 | + struct stat s; |
| 155 | + char fullName_utf8[hpatch_kPathMaxSize]; |
| 156 | + int slen=snprintf(fullName_utf8,hpatch_kPathMaxSize,"%s/%s",pdir->dirName,pdirent->d_name); |
| 157 | + if ((slen<=0)||(slen>=hpatch_kPathMaxSize)) return hpatch_FALSE; |
| 158 | + if (stat(fullName_utf8,&s)!=0) return hpatch_FALSE; |
| 159 | + if ((s.st_mode&S_IFMT)==S_IFDIR) |
| 160 | + *out_type=kPathType_dir; |
| 161 | + else if ((s.st_mode&S_IFMT)==S_IFREG) |
| 162 | + *out_type=kPathType_file; |
| 163 | + #if (_IS_NEED_BLOCK_DEV) |
| 164 | + else if ((s.st_mode&S_IFMT)==S_IFBLK) |
| 165 | + *out_type=kPathType_file; |
| 166 | + #endif |
| 167 | + else |
| 168 | + continue; //next |
| 169 | + } |
| 170 | + #else |
| 171 | + if (pdirent->d_type==DT_DIR) |
| 172 | + *out_type=kPathType_dir; |
| 173 | + else if (pdirent->d_type==DT_REG) |
| 174 | + *out_type=kPathType_file; |
| 175 | + #if (_IS_NEED_BLOCK_DEV) |
| 176 | + else if (pdirent->d_type==DT_BLK) |
| 177 | + *out_type=kPathType_file; |
| 178 | + #endif |
| 179 | + else |
| 180 | + continue; //next |
| 181 | + #endif |
128 | 182 | *out_subName_utf8=pdirent->d_name; |
129 | 183 | return hpatch_TRUE; |
130 | | - }else{ |
131 | | - return hdiff_dirNext(dirHandle,out_type,out_subName_utf8); |
132 | 184 | } |
133 | 185 | } |
134 | 186 |
|
135 | 187 | void hdiff_dirClose(hdiff_TDirHandle dirHandle){ |
136 | | - if (dirHandle) |
137 | | - closedir((DIR*)dirHandle); |
| 188 | + _hdiff_TDIRData* pdir=(_hdiff_TDIRData*)dirHandle; |
| 189 | + if (pdir){ |
| 190 | + if (pdir->handle) closedir((DIR*)pdir->handle); |
| 191 | + free(pdir); |
| 192 | + } |
138 | 193 | } |
139 | 194 |
|
140 | | -#endif // if _WIN32 else |
| 195 | +#endif // _WIN32 & linux-like |
141 | 196 | #endif // _IS_NEED_DIR_DIFF_PATCH |
142 | 197 |
|
143 | 198 |
|
|
0 commit comments