|
Boost : |
From: Jonathan Wakely (cow_at_[hidden])
Date: 2005-01-28 07:30:32
On Fri, Jan 28, 2005 at 10:58:24AM +0000, Jonathan Wakely wrote:
> Looking at the implementation of copy_file() I'm wondering why it isn't
> done like this (this provides noclobber support too):
>
> std::fstream out;
> if (noclobber)
> {
> out.open(to_file_ph.string().c_str(), std::ios::in);
> if (out.is_open())
> {
> // file exists
> boost::throw_exception( filesystem_error(
> "boost::filesystem::copy_file",
> from_file_ph, to_file_ph, fs::detail::system_error_code() ) );
> }
> }
> std::ifstream in(from_file_ph.string().c_str());
> out.open(to_file_ph.string().c_str(), std::ios::out);
> out << in.rdbuf();
Hmm, this has a race-condition, which is a good reason to stick with
open(2) and O_CREAT|O_EXCL and read(2)/write(2).
However, in that case there's a comment about the implementation:
// TODO: Ask POSIX experts if this is the best way to copy a file
Now, I'm no POSIX expert, but I believe the loop used:
ssize_t sz;
while ( (sz = ::read( infile, buf.get(), buf_sz )) > 0
&& (sz = ::write( outfile, buf.get(), sz )) > 0 ) {}
can result in lost data if write(2) only does a partial write, which
might happen if the write is interrupted by a signal. I think it should
loop on the writes too, until write() has returned sz in total.
jon
-- Message terminated with signal 11, SIGFAULT
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk