llvm.org GIT mirror llvm / 5a06077
For PR797: Eliminate exception throwing from Path::renamePathOnDisk and adjust its users correspondingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29843 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Spencer 14 years ago
8 changed file(s) with 44 addition(s) and 49 deletion(s). Raw diff Collapse all Expand all
491491 /// This method renames the file referenced by \p this as \p newName. The
492492 /// file referenced by \p this must exist. The file referenced by
493493 /// \p newName does not need to exist.
494 /// @returns true
495 /// @throws std::string if there is an file system error.
494 /// @returns true on error, false otherwise
496495 /// @brief Rename one file as another.
497 bool renamePathOnDisk(const Path& newName);
496 bool renamePathOnDisk(const Path& newName, std::string* ErrMsg);
498497
499498 /// This method attempts to destroy the file or directory named by the
500499 /// last component of the Path. If the Path refers to a directory and the
495495 arch.close();
496496
497497 // Move the final file over top of TmpArchive
498 FinalFilePath.renamePathOnDisk(TmpArchive);
498 if (FinalFilePath.renamePathOnDisk(TmpArchive, error))
499 return false;
499500 }
500501
501502 // Before we replace the actual archive, we need to forget all the
503504 // this because we cannot replace an open file on Windows.
504505 cleanUpMemory();
505506
506 TmpArchive.renamePathOnDisk(archPath);
507 if (TmpArchive.renamePathOnDisk(archPath, error))
508 return false;
507509
508510 return true;
509511 }
495495 arch.close();
496496
497497 // Move the final file over top of TmpArchive
498 FinalFilePath.renamePathOnDisk(TmpArchive);
498 if (FinalFilePath.renamePathOnDisk(TmpArchive, error))
499 return false;
499500 }
500501
501502 // Before we replace the actual archive, we need to forget all the
503504 // this because we cannot replace an open file on Windows.
504505 cleanUpMemory();
505506
506 TmpArchive.renamePathOnDisk(archPath);
507 if (TmpArchive.renamePathOnDisk(archPath, error))
508 return false;
507509
508510 return true;
509511 }
390390 }
391391
392392 bool Path::makeReadableOnDisk(std::string* ErrMsg) {
393 if (!AddPermissionBits(*this, 0444)) {
394 MakeErrMsg(ErrMsg, path + ": can't make file readable");
395 return true;
396 }
393 if (!AddPermissionBits(*this, 0444))
394 return MakeErrMsg(ErrMsg, path + ": can't make file readable");
397395 return false;
398396 }
399397
400398 bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
401 if (!AddPermissionBits(*this, 0222)) {
402 MakeErrMsg(ErrMsg, path + ": can't make file writable");
403 return true;
404 }
399 if (!AddPermissionBits(*this, 0222))
400 return MakeErrMsg(ErrMsg, path + ": can't make file writable");
405401 return false;
406402 }
407403
408404 bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
409 if (!AddPermissionBits(*this, 0111)) {
410 MakeErrMsg(ErrMsg, path + ": can't make file executable");
411 return true;
412 }
405 if (!AddPermissionBits(*this, 0111))
406 return MakeErrMsg(ErrMsg, path + ": can't make file executable");
413407 return false;
414408 }
415409
416410 bool
417411 Path::getDirectoryContents(std::set& result, std::string* ErrMsg) const {
418412 DIR* direntries = ::opendir(path.c_str());
419 if (direntries == 0) {
420 MakeErrMsg(ErrMsg, path + ": can't open directory");
421 return true;
422 }
413 if (direntries == 0)
414 return MakeErrMsg(ErrMsg, path + ": can't open directory");
423415
424416 std::string dirPath = path;
425417 if (!lastIsSlash(dirPath))
434426 if (0 != lstat(aPath.path.c_str(), &st)) {
435427 if (S_ISLNK(st.st_mode))
436428 continue; // dangling symlink -- ignore
437 MakeErrMsg(ErrMsg, aPath.path + ": can't determine file object type");
438 return true;
429 return MakeErrMsg(ErrMsg,
430 aPath.path + ": can't determine file object type");
439431 }
440432 result.insert(aPath);
441433 }
543535 *next = 0;
544536 if (0 != access(pathname, F_OK | R_OK | W_OK))
545537 if (0 != mkdir(pathname, S_IRWXU | S_IRWXG)) {
546 MakeErrMsg(ErrMsg,
547 std::string(pathname) + ": can't create directory");
548 return true;
538 return MakeErrMsg(ErrMsg,
539 std::string(pathname) + ": can't create directory");
549540 }
550541 char* save = next;
551542 next = strchr(next+1,'/');
555546
556547 if (0 != access(pathname, F_OK | R_OK))
557548 if (0 != mkdir(pathname, S_IRWXU | S_IRWXG)) {
558 MakeErrMsg(ErrMsg, std::string(pathname) + ": can't create directory");
559 return true;
549 return MakeErrMsg(ErrMsg,
550 std::string(pathname) + ": can't create directory");
560551 }
561552 return false;
562553 }
565556 Path::createFileOnDisk(std::string* ErrMsg) {
566557 // Create the file
567558 int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR);
568 if (fd < 0) {
569 MakeErrMsg(ErrMsg, path + ": can't create file");
570 return true;
571 }
559 if (fd < 0)
560 return MakeErrMsg(ErrMsg, path + ": can't create file");
572561 ::close(fd);
573562 return false;
574563 }
580569
581570 // create the file
582571 int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666);
583 if (fd < 0) {
584 MakeErrMsg(ErrMsg, path + ": can't create temporary file");
585 return true;
586 }
572 if (fd < 0)
573 return MakeErrMsg(ErrMsg, path + ": can't create temporary file");
587574 ::close(fd);
588575 return false;
589576 }
632619 }
633620
634621 bool
635 Path::renamePathOnDisk(const Path& newName) {
622 Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
636623 if (0 != ::rename(path.c_str(), newName.c_str()))
637 ThrowErrno(std::string("can't rename '") + path + "' as '" +
624 return MakeErrMsg(ErrMsg, std::string("can't rename '") + path + "' as '" +
638625 newName.toString() + "' ");
639 return true;
626 return false;
640627 }
641628
642629 bool
122122 /// string and the Unix error number given by \p errnum. If errnum is -1, the
123123 /// default then the value of errno is used.
124124 /// @brief Make an error message
125 inline void MakeErrMsg(
125 inline bool MakeErrMsg(
126126 std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
127127 if (!ErrMsg)
128 return;
128 return true;
129129 char buffer[MAXPATHLEN];
130130 buffer[0] = 0;
131131 if (errnum == -1)
147147 sprintf(buffer, "Error #%d", errnum);
148148 #endif
149149 *ErrMsg = buffer;
150 return true;
150151 }
151152
152153 #endif
650650 }
651651
652652 bool
653 Path::renamePathOnDisk(const Path& newName) {
653 Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
654654 if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
655 ThrowError("Can't move '" + path +
656 "' to '" + newName.path + "': ");
655 return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path
656 + "': ");
657657 return true;
658658 }
659659
4343 throw s;
4444 }
4545
46 inline void MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
46 inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
4747 if (!ErrMsg)
48 return;
48 return true;
4949 char *buffer = NULL;
5050 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
5151 NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
5252 ErrMsg = prefix + buffer;
5353 LocalFree(buffer);
54 return true;
5455 }
5556
5657 inline void ThrowErrno(const std::string& prefix) {
504504 if (tmp_output.isBytecodeFile()) {
505505 sys::Path target(RealBytecodeOutput);
506506 target.eraseFromDisk();
507 tmp_output.renamePathOnDisk(target);
507 if (tmp_output.renamePathOnDisk(target, &ErrMsg)) {
508 std::cerr << argv[0] << ": " << ErrMsg << "\n";
509 return 2;
510 }
508511 } else
509512 return PrintAndReturn(
510513 "Post-link optimization output is not bytecode");