| 507 | } |
| 508 | |
| 509 | void ConvertFile(std::string fileName) { |
| 510 | FILE* fin = OpenFileUtf8(fileName, "rb"); |
| 511 | if (!fin) { |
| 512 | throw FileNotFound(fileName); |
| 513 | } |
| 514 | |
| 515 | if (!outputFileName.IsNull() && |
| 516 | IsSameFileUtf8(fileName, outputFileName.Get())) { |
| 517 | if (!inPlace) { |
| 518 | fclose(fin); |
| 519 | throw Exception("Input and output refer to the same file; use " |
| 520 | "--in-place to overwrite it."); |
| 521 | } |
| 522 | |
| 523 | std::string targetFileName = outputFileName.Get(); |
| 524 | GetRealPathUtf8(outputFileName.Get(), &targetFileName); |
| 525 | if (HasMultipleLinksUtf8(targetFileName)) { |
| 526 | fclose(fin); |
| 527 | throw Exception("--in-place cannot safely update files with multiple " |
| 528 | "hard links."); |
| 529 | } |
| 530 | |
| 531 | std::string tempFileName; |
| 532 | FILE* fout = CreateTempFileNearUtf8(targetFileName, &tempFileName); |
| 533 | if (!fout) { |
| 534 | fclose(fin); |
| 535 | if (tempFileName.empty()) { |
| 536 | tempFileName = "temporary file"; |
| 537 | } |
| 538 | throw FileNotWritable(tempFileName); |
| 539 | } |
| 540 | |
| 541 | try { |
| 542 | ConvertFileStreams(fin, fout); |
| 543 | if (PreserveMetadataUtf8(targetFileName, tempFileName) != 0) { |
| 544 | RemoveFileUtf8(tempFileName); |
| 545 | throw FileNotWritable(tempFileName); |
| 546 | } |
| 547 | if (ReplaceFileUtf8(tempFileName, targetFileName) != 0) { |
| 548 | RemoveFileUtf8(tempFileName); |
| 549 | throw FileNotWritable(targetFileName); |
| 550 | } |
| 551 | } catch (...) { |
| 552 | RemoveFileUtf8(tempFileName); |
| 553 | throw; |
| 554 | } |
| 555 | return; |
| 556 | } |
| 557 | |
| 558 | FILE* fout = GetOutputStream(); |
| 559 | ConvertFileStreams(fin, fout); |
| 560 | } |
| 561 | |
| 562 | void ConvertStdin() { |
| 563 | PrintInteractiveStdinHint(); |
no test coverage detected