Boost logo

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