You have FileCopyPeerFDStream::Done(); FileCopyPeer::Done() wasn't
virtual (before this patch.)
bool FileCopyPeerFDStream::Done()
{
if(!super::Done())
return false;
+ if(broken || Error())
+ return true;
if(stream && delete_stream && !stream->Done())
return false;
return true;
}
makes error/broken behavior consistent.
Here's a simpler version of FileCopyPeer::Done(); it's just flattened:
bool FileCopyPeer::Done()
{
if(broken || Error())
return true;
if(!eof || in_buffer!=0)
return false;
if(removing)
return false;
if(mode==PUT && do_set_date && !date_set)
return false;
return true;
}
(This helps show why the broken||Error check needs to be done in each
override.)
> bool FileCopyPeerFA::Done()
> {
> if(!super::Done())
> return false;
> if(broken || Error())
> return true;
> if(in_buffer!=0 || !eof)
> return false;
>
> return session->StoreStatus() != FA::IN_PROGRESS;
> }
>
> helps, but there's probably something else I'm missing; I suspect date
> setting sitll won't work. Maybe there's a better way; replace the
> "removing" stage with a "finishing" stage and include it in that?
Actually, it looks just like FileCopyPeerFDStream::Done, once I remove
the third (superfluous) conditional and did the above. (I didn't know
about FileCopyPeerFDStream::Done before; I didn't think to look for it
because FileCopyPeer::Done wasn't virtual.)
About the broken pipe problem:
if(put->Broken())
{
debug((9,_("copy: put is broken\n")));
goto pre_GET_DONE_WAIT;
}
You're not treating a broken put as an error.
SetError(strerror(EPIPE));
debug((9,_("copy: put is broken\n")));
return MOVED;
seems to fix it (though the error should probably include the name of
the put.) Was there a reason you did it that way?
(Working on fixing these because I need them working to finish OutputJob
error handling. The cls progress bug is fixed, by the way.)
--
Glenn Maynard