Boost logo

Boost :

From: Lars Gullik Bjønnes (larsbj_at_[hidden])
Date: 2005-01-28 09:55:54


Jonathan Wakely <cow_at_[hidden]> 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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk