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