| 280 | |
| 281 | |
| 282 | std::unique_ptr<fdostream> output_file( |
| 283 | const std::string& filename, |
| 284 | bool make_sav, bool direct) |
| 285 | // Create an output file stream ready to receive the data for a file. |
| 286 | // This will also make any intermediate directories needed. |
| 287 | // If make_sav is true and the file already exists then the old file will be |
| 288 | // moved to .sav before proceeding. |
| 289 | { |
| 290 | std::string dirname(filename); |
| 291 | makedirname(dirname); |
| 292 | make_dirs(dirname); |
| 293 | struct stat st; |
| 294 | |
| 295 | if(stat(filename.c_str(), &st) == 0) { |
| 296 | if(make_sav) { |
| 297 | // We need to make a .sav. This isn't a fatal error if we can't |
| 298 | std::string sav_filename(filename + ".sav"); |
| 299 | int rc = rename(filename.c_str(), sav_filename.c_str()); |
| 300 | if(rc == -1) { |
| 301 | std::cerr << "Cannot create " << sav_filename << ": " |
| 302 | << errno << " " << strerror(errno) << std::endl; |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | // unlink the existing file (fix for unable to overwrite a readonly file) |
| 307 | if(unlink(filename.c_str()) == -1 && errno != ENOENT) { |
| 308 | std::cerr << "Cannot unlink " << filename << ": " |
| 309 | << errno << " " << strerror(errno) << std::endl; |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | int flags = O_WRONLY | O_CREAT | O_TRUNC; |
| 314 | |
| 315 | #if defined(__sun) || defined(__APPLE__) |
| 316 | int fd = open(filename.c_str(), flags, 0666); |
| 317 | if(fd == -1) throw Error("Error opening '" + filename + "' for writing"); |
| 318 | #else |
| 319 | if (direct) |
| 320 | flags |= O_DIRECT; |
| 321 | reopen: |
| 322 | int fd = open(filename.c_str(), flags, 0666); |
| 323 | if(fd == -1) { |
| 324 | if (EINVAL == errno){ |
| 325 | std::clog << "Turning off directio because of open() err: " << std::strerror(errno) << std::endl; |
| 326 | flags ^= O_DIRECT; |
| 327 | goto reopen; |
| 328 | } else { |
| 329 | throw Error("Error opening '" + filename + "' for writing"); |
| 330 | } |
| 331 | } |
| 332 | #endif |
| 333 | |
| 334 | return std::unique_ptr<fdostream>(new fdostream(fd)); |
| 335 | } |
| 336 | |
| 337 | void remove_all_old_files(std::string &datadir) { |
| 338 | std::list<std::string> dirlist; |
no test coverage detected