struct OperationConfig *config,
CURLSH *share,
bool capath_from_env,
- bool *added);
+ bool *added,
+ bool *skipped);
static CURLcode create_transfer(struct GlobalConfig *global,
CURLSH *share,
- bool *added);
+ bool *added,
+ bool *skipped);
static bool is_fatal_error(CURLcode code)
{
struct OperationConfig *config,
CURLSH *share,
bool capath_from_env,
- bool *added)
+ bool *added,
+ bool *skipped)
{
CURLcode result = CURLE_OK;
struct getout *urlnode;
struct State *state = &config->state;
char *httpgetfields = state->httpgetfields;
- *added = FALSE; /* not yet */
+ *skipped = *added = FALSE; /* not yet */
if(config->postfields) {
if(config->use_httpget) {
notef(global, "skips transfer, \"%s\" exists locally",
per->outfile);
per->skip = TRUE;
+ *skipped = TRUE;
}
}
if((urlnode->flags & GETOUT_USEREMOTE)
*addedp = FALSE;
*morep = FALSE;
if(all_pers < (global->parallel_max*2)) {
- result = create_transfer(global, share, addedp);
- if(result)
- return result;
+ bool skipped = FALSE;
+ do {
+ result = create_transfer(global, share, addedp, &skipped);
+ if(result)
+ return result;
+ } while(skipped);
}
for(per = transfers; per && (all_added < global->parallel_max);
per = per->next) {
- bool getadded = FALSE;
- if(per->added)
- /* already added */
+ if(per->added || per->skip)
+ /* already added or to be skipped */
continue;
if(per->startat && (time(NULL) < per->startat)) {
/* this is still delaying */
result = CURLE_OUT_OF_MEMORY;
}
- if(!result)
- result = create_transfer(global, share, &getadded);
+ if(!result) {
+ bool getadded = FALSE;
+ bool skipped = FALSE;
+ do {
+ result = create_transfer(global, share, &getadded, &skipped);
+ if(result)
+ break;
+ } while(skipped);
+ }
if(result) {
free(errorbuf);
return result;
#endif
else
#endif
- while(!s->mcode && (s->still_running || s->more_transfers)) {
- /* If stopping prematurely (eg due to a --fail-early condition) then signal
- that any transfers in the multi should abort (via progress callback). */
- if(s->wrapitup) {
- if(!s->still_running)
- break;
- if(!s->wrapitup_processed) {
- struct per_transfer *per;
- for(per = transfers; per; per = per->next) {
- if(per->added)
- per->abort = TRUE;
+
+ if(all_added) {
+ while(!s->mcode && (s->still_running || s->more_transfers)) {
+ /* If stopping prematurely (eg due to a --fail-early condition) then
+ signal that any transfers in the multi should abort (via progress
+ callback). */
+ if(s->wrapitup) {
+ if(!s->still_running)
+ break;
+ if(!s->wrapitup_processed) {
+ struct per_transfer *per;
+ for(per = transfers; per; per = per->next) {
+ if(per->added)
+ per->abort = TRUE;
+ }
+ s->wrapitup_processed = TRUE;
}
- s->wrapitup_processed = TRUE;
}
- }
- s->mcode = curl_multi_poll(s->multi, NULL, 0, 1000, NULL);
- if(!s->mcode)
- s->mcode = curl_multi_perform(s->multi, &s->still_running);
+ s->mcode = curl_multi_poll(s->multi, NULL, 0, 1000, NULL);
+ if(!s->mcode)
+ s->mcode = curl_multi_perform(s->multi, &s->still_running);
+ if(!s->mcode)
+ result = check_finished(s);
+ }
- if(!s->mcode)
- result = check_finished(s);
+ (void)progress_meter(global, &s->start, TRUE);
}
- (void)progress_meter(global, &s->start, TRUE);
-
/* Make sure to return some kind of error if there was a multi problem */
if(s->mcode) {
result = (s->mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
CURLcode result = CURLE_OK;
struct per_transfer *per;
bool added = FALSE;
+ bool skipped = FALSE;
- result = create_transfer(global, share, &added);
+ result = create_transfer(global, share, &added, &skipped);
if(result)
return result;
if(!added) {
if(is_fatal_error(returncode) || (returncode && global->fail_early))
bailout = TRUE;
else {
- /* setup the next one just before we delete this */
- result = create_transfer(global, share, &added);
- if(result) {
- returncode = result;
- bailout = TRUE;
- }
+ do {
+ /* setup the next one just before we delete this */
+ result = create_transfer(global, share, &added, &skipped);
+ if(result) {
+ returncode = result;
+ bailout = TRUE;
+ }
+ } while(skipped);
}
per = del_per_transfer(per);
static CURLcode transfer_per_config(struct GlobalConfig *global,
struct OperationConfig *config,
CURLSH *share,
- bool *added)
+ bool *added,
+ bool *skipped)
{
CURLcode result = CURLE_OK;
bool capath_from_env;
}
if(!result)
- result = single_transfer(global, config, share, capath_from_env, added);
+ result = single_transfer(global, config, share, capath_from_env, added,
+ skipped);
return result;
}
*/
static CURLcode create_transfer(struct GlobalConfig *global,
CURLSH *share,
- bool *added)
+ bool *added,
+ bool *skipped)
{
CURLcode result = CURLE_OK;
*added = FALSE;
while(global->current) {
- result = transfer_per_config(global, global->current, share, added);
+ result = transfer_per_config(global, global->current, share, added,
+ skipped);
if(!result && !*added) {
/* when one set is drained, continue to next */
global->current = global->current->next;