8
8
9
9
#define HCAST (type , handle ) ((type)(intptr_t)handle)
10
10
11
- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
12
11
unsigned int _CRT_fmode = _O_BINARY ;
13
12
14
13
int err_win_to_posix (DWORD winerr )
@@ -173,15 +172,12 @@ static int read_yes_no_answer(void)
173
172
return -1 ;
174
173
}
175
174
176
- static int ask_yes_no_if_possible (const char * format , ... )
175
+ static int ask_yes_no_if_possible (const char * format , va_list args )
177
176
{
178
177
char question [4096 ];
179
178
const char * retry_hook [] = { NULL , NULL , NULL };
180
- va_list args ;
181
179
182
- va_start (args , format );
183
180
vsnprintf (question , sizeof (question ), format , args );
184
- va_end (args );
185
181
186
182
if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
187
183
retry_hook [1 ] = question ;
@@ -203,33 +199,48 @@ static int ask_yes_no_if_possible(const char *format, ...)
203
199
}
204
200
}
205
201
202
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
203
+ {
204
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
205
+ va_list args ;
206
+ int result , saved_errno = errno ;
207
+
208
+ if ((* tries ) < ARRAY_SIZE (delay )) {
209
+ /*
210
+ * We assume that some other process had the file open at the wrong
211
+ * moment and retry. In order to give the other process a higher
212
+ * chance to complete its operation, we give up our time slice now.
213
+ * If we have to retry again, we do sleep a bit.
214
+ */
215
+ Sleep (delay [* tries ]);
216
+ (* tries )++ ;
217
+ return 1 ;
218
+ }
219
+
220
+ va_start (args , format );
221
+ result = ask_yes_no_if_possible (format , args );
222
+ va_end (args );
223
+ errno = saved_errno ;
224
+ return result ;
225
+ }
226
+
206
227
int mingw_unlink (const char * pathname )
207
228
{
208
- int ret , tries = 0 ;
229
+ int tries = 0 ;
209
230
wchar_t wpathname [MAX_LONG_PATH ];
210
231
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
211
232
return -1 ;
212
233
213
- /* read-only files cannot be removed */
214
- _wchmod (wpathname , 0666 );
215
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
234
+ do {
235
+ /* read-only files cannot be removed */
236
+ _wchmod (wpathname , 0666 );
237
+ if (!_wunlink (wpathname ))
238
+ return 0 ;
216
239
if (!is_file_in_use_error (GetLastError ()))
217
240
break ;
218
- /*
219
- * We assume that some other process had the source or
220
- * destination file open at the wrong moment and retry.
221
- * In order to give the other process a higher chance to
222
- * complete its operation, we give up our time slice now.
223
- * If we have to retry again, we do sleep a bit.
224
- */
225
- Sleep (delay [tries ]);
226
- tries ++ ;
227
- }
228
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
229
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
230
- "Should I try again?" , pathname ))
231
- ret = _wunlink (wpathname );
232
- return ret ;
241
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
242
+ "Should I try again?" , pathname ));
243
+ return -1 ;
233
244
}
234
245
235
246
static int is_dir_empty (const wchar_t * wpath )
@@ -256,12 +267,14 @@ static int is_dir_empty(const wchar_t *wpath)
256
267
257
268
int mingw_rmdir (const char * pathname )
258
269
{
259
- int ret , tries = 0 ;
270
+ int tries = 0 ;
260
271
wchar_t wpathname [MAX_LONG_PATH ];
261
272
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
262
273
return -1 ;
263
274
264
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
275
+ do {
276
+ if (!_wrmdir (wpathname ))
277
+ return 0 ;
265
278
if (!is_file_in_use_error (GetLastError ()))
266
279
errno = err_win_to_posix (GetLastError ());
267
280
if (errno != EACCES )
@@ -270,21 +283,9 @@ int mingw_rmdir(const char *pathname)
270
283
errno = ENOTEMPTY ;
271
284
break ;
272
285
}
273
- /*
274
- * We assume that some other process had the source or
275
- * destination file open at the wrong moment and retry.
276
- * In order to give the other process a higher chance to
277
- * complete its operation, we give up our time slice now.
278
- * If we have to retry again, we do sleep a bit.
279
- */
280
- Sleep (delay [tries ]);
281
- tries ++ ;
282
- }
283
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
284
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
285
- "Should I try again?" , pathname ))
286
- ret = _wrmdir (wpathname );
287
- return ret ;
286
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
287
+ "Should I try again?" , pathname ));
288
+ return -1 ;
288
289
}
289
290
290
291
static int make_hidden (const wchar_t * path )
@@ -1783,20 +1784,8 @@ int mingw_rename(const char *pold, const char *pnew)
1783
1784
SetFileAttributesW (wpnew , attrs );
1784
1785
}
1785
1786
}
1786
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
1787
- /*
1788
- * We assume that some other process had the source or
1789
- * destination file open at the wrong moment and retry.
1790
- * In order to give the other process a higher chance to
1791
- * complete its operation, we give up our time slice now.
1792
- * If we have to retry again, we do sleep a bit.
1793
- */
1794
- Sleep (delay [tries ]);
1795
- tries ++ ;
1796
- goto repeat ;
1797
- }
1798
1787
if (gle == ERROR_ACCESS_DENIED &&
1799
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
1788
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
1800
1789
"Should I try again?" , pold , pnew ))
1801
1790
goto repeat ;
1802
1791
0 commit comments