
Jonathan Wakely <cow@compsoc.man.ac.uk> writes: | 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, In that the target can come into existance after checked for? lots and lots of races like that possible when working with filesystems. | 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: Well, you can expect the implementators of your stdlib to be experts on the system it is implemented for. And that speaks in favour of writing a C++ solution. Pity that there is no ios::nocreate in the standard. And in the case where noclobber is false there is no race. | ssize_t sz; | while ( (sz = ::read( infile, buf.get(), buf_sz )) > 0 | && (sz = ::write( outfile, buf.get(), sz )) > 0 ) {} exactly the kindo thing that has been solved of the implementators for the out << in.rdbuf(); case. -- Lgb