llvm.org GIT mirror llvm / 51c5a28
For PR797: Final removal of exceptions from lib/System and adjustment of users to accommodate. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29846 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Spencer 14 years ago
9 changed file(s) with 155 addition(s) and 137 deletion(s). Raw diff Collapse all Expand all
250250 return Filename;
251251 }
252252 Filename.appendComponent(Name + ".dot");
253 Filename.makeUnique();
253 if (Filename.makeUnique(true,&ErrMsg)) {
254 std::cerr << "Error: " << ErrMsg << "\n";
255 return sys::Path();
256 }
257
254258 std::cerr << "Writing '" << Filename << "'... ";
255259
256260 std::ofstream O(Filename.c_str());
413413 /// already unique.
414414 /// @throws std::string if an unrecoverable error occurs.
415415 /// @brief Make the current path name unique in the file system.
416 void makeUnique( bool reuse_current = true );
416 bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg );
417417
418418 /// @}
419419 /// @name Disk Mutators
528528
529529 /// This function can be used to copy the file specified by Src to the
530530 /// file specified by Dest. If an error occurs, Dest is removed.
531 /// @throws std::string if an error opening or writing the files occurs.
531 /// @returns true if an error occurs, false otherwise
532532 /// @brief Copy one file to another.
533 void CopyFile(const Path& Dest, const Path& Src);
533 bool CopyFile(const Path& Dest, const Path& Src, std::string* ErrMsg);
534534 }
535535
536536 std::ostream& operator<<(std::ostream& strm, const sys::Path& aPath);
3434 #ifdef NEED_DEV_ZERO_FOR_MMAP
3535 static int zero_fd = open("/dev/zero", O_RDWR);
3636 if (zero_fd == -1) {
37 GetErrno("Can't open /dev/zero device", ErrMsg);
37 MakeErrMsg(ErrMsg, "Can't open /dev/zero device");
3838 return MemoryBlock();
3939 }
4040 fd = zero_fd;
5757 if (NearBlock) //Try again without a near hint
5858 return AllocateRWX(NumBytes, 0);
5959
60 GetErrno("Can't allocate RWX Memory", ErrMsg);
60 MakeErrMsg(ErrMsg, "Can't allocate RWX Memory");
6161 return MemoryBlock();
6262 }
6363 MemoryBlock result;
6969 bool llvm::sys::Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
7070 if (M.Address == 0 || M.Size == 0) return false;
7171 if (0 != ::munmap(M.Address, M.Size))
72 return GetErrno("Can't release RWX Memory", ErrMsg);
72 return MakeErrMsg(ErrMsg, "Can't release RWX Memory");
7373 return false;
7474 }
7575
168168 MakeErrMsg(ErrMsg,
169169 std::string(pathname) + ": can't create temporary directory");
170170 return Path();
171 }
171172 Path result;
172173 result.set(pathname);
173174 assert(result.isValid() && "mkstemp didn't create a valid pathname!");
358359 Path::getFileStatus(FileStatus &info, std::string *ErrStr) const {
359360 struct stat buf;
360361 if (0 != stat(path.c_str(), &buf))
361 return GetErrno(path + ": can't get status of file '" + path + "'", ErrStr);
362 return MakeErrMsg(ErrStr,
363 path + ": can't get status of file '" + path + "'");
362364 info.fileSize = buf.st_size;
363365 info.modTime.fromEpochTime(buf.st_mtime);
364366 info.mode = buf.st_mode;
565567 bool
566568 Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
567569 // Make this into a unique file name
568 makeUnique( reuse_current );
570 if (makeUnique( reuse_current, ErrMsg ))
571 return true;
569572
570573 // create the file
571574 int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666);
588591 // or other things that aren't "regular" files.
589592 if (Status.isFile) {
590593 if (unlink(path.c_str()) != 0)
591 return GetErrno(path + ": can't destroy file", ErrStr);
594 return MakeErrMsg(ErrStr, path + ": can't destroy file");
592595 return false;
593596 }
594597
613616 pathname[lastchar+1] = 0;
614617
615618 if (rmdir(pathname) != 0)
616 return GetErrno(std::string(pathname) + ": can't destroy directory",
617 ErrStr);
619 return MakeErrMsg(ErrStr,
620 std::string(pathname) + ": can't destroy directory");
618621 return false;
619622 }
620623
632635 utb.actime = si.modTime.toPosixTime();
633636 utb.modtime = utb.actime;
634637 if (0 != ::utime(path.c_str(),&utb))
635 return GetErrno(path + ": can't set file modification time", ErrStr);
638 return MakeErrMsg(ErrStr, path + ": can't set file modification time");
636639 if (0 != ::chmod(path.c_str(),si.mode))
637 return GetErrno(path + ": can't set mode", ErrStr);
638 return false;
639 }
640
641 void
642 sys::CopyFile(const sys::Path &Dest, const sys::Path &Src) {
640 return MakeErrMsg(ErrStr, path + ": can't set mode");
641 return false;
642 }
643
644 bool
645 sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
643646 int inFile = -1;
644647 int outFile = -1;
645 try {
646 inFile = ::open(Src.c_str(), O_RDONLY);
647 if (inFile == -1)
648 ThrowErrno(Src.toString() + ": can't open source file to copy: ");
649
650 outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666);
651 if (outFile == -1)
652 ThrowErrno(Dest.toString() +": can't create destination file for copy: ");
653
654 char Buffer[16*1024];
655 while (ssize_t Amt = ::read(inFile, Buffer, 16*1024)) {
656 if (Amt == -1) {
657 if (errno != EINTR && errno != EAGAIN)
658 ThrowErrno(Src.toString()+": can't read source file: ");
659 } else {
660 char *BufPtr = Buffer;
661 while (Amt) {
662 ssize_t AmtWritten = ::write(outFile, BufPtr, Amt);
663 if (AmtWritten == -1) {
664 if (errno != EINTR && errno != EAGAIN)
665 ThrowErrno(Dest.toString() + ": can't write destination file: ");
666 } else {
667 Amt -= AmtWritten;
668 BufPtr += AmtWritten;
648 inFile = ::open(Src.c_str(), O_RDONLY);
649 if (inFile == -1)
650 return MakeErrMsg(ErrMsg, Src.toString() +
651 ": can't open source file to copy");
652
653 outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666);
654 if (outFile == -1) {
655 ::close(inFile);
656 return MakeErrMsg(ErrMsg, Dest.toString() +
657 ": can't create destination file for copy");
658 }
659
660 char Buffer[16*1024];
661 while (ssize_t Amt = ::read(inFile, Buffer, 16*1024)) {
662 if (Amt == -1) {
663 if (errno != EINTR && errno != EAGAIN) {
664 ::close(inFile);
665 ::close(outFile);
666 return MakeErrMsg(ErrMsg, Src.toString()+": can't read source file: ");
667 }
668 } else {
669 char *BufPtr = Buffer;
670 while (Amt) {
671 ssize_t AmtWritten = ::write(outFile, BufPtr, Amt);
672 if (AmtWritten == -1) {
673 if (errno != EINTR && errno != EAGAIN) {
674 ::close(inFile);
675 ::close(outFile);
676 return MakeErrMsg(ErrMsg, Dest.toString() +
677 ": can't write destination file: ");
669678 }
679 } else {
680 Amt -= AmtWritten;
681 BufPtr += AmtWritten;
670682 }
671683 }
672684 }
673 ::close(inFile);
674 ::close(outFile);
675 } catch (...) {
676 if (inFile != -1)
677 ::close(inFile);
678 if (outFile != -1)
679 ::close(outFile);
680 throw;
681 }
682 }
683
684 void
685 Path::makeUnique(bool reuse_current) {
685 }
686 ::close(inFile);
687 ::close(outFile);
688 return false;
689 }
690
691 bool
692 Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
686693 if (reuse_current && !exists())
687 return; // File doesn't exist already, just use it!
694 return false; // File doesn't exist already, just use it!
688695
689696 // Append an XXXXXX pattern to the end of the file for use with mkstemp,
690697 // mktemp or our own implementation.
694701
695702 #if defined(HAVE_MKSTEMP)
696703 int TempFD;
697 if ((TempFD = mkstemp(FNBuffer)) == -1) {
698 ThrowErrno(path + ": can't make unique filename");
699 }
704 if ((TempFD = mkstemp(FNBuffer)) == -1)
705 return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
700706
701707 // We don't need to hold the temp file descriptor... we will trust that no one
702708 // will overwrite/delete the file before we can open it again.
706712 path = FNBuffer;
707713 #elif defined(HAVE_MKTEMP)
708714 // If we don't have mkstemp, use the old and obsolete mktemp function.
709 if (mktemp(FNBuffer) == 0) {
710 ThrowErrno(path + ": can't make unique filename");
711 }
715 if (mktemp(FNBuffer) == 0)
716 return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
712717
713718 // Save the name
714719 path = FNBuffer;
721726 path = FNBuffer;
722727 }
723728 if (FCounter > 999999)
724 throw std::string(path + ": can't make unique filename: too many files");
725 #endif
726
727 }
728 }
729
729 return MakeErrMsg(ErrMsg,
730 path + ": can't make unique filename: too many files");
731 #endif
732 return false;
733 }
734
735 } // end llvm namespace
736
6565 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
6666 #endif
6767
68 inline bool GetErrno(const std::string &prefix, std::string *ErrDest,
69 int errnum = -1) {
70 char buffer[MAXPATHLEN];
71
72 if (ErrDest == 0) return true;
73
74 buffer[0] = 0;
75 if (errnum == -1)
76 errnum = errno;
77 #ifdef HAVE_STRERROR_R
78 // strerror_r is thread-safe.
79 if (errnum)
80 strerror_r(errnum, buffer, MAXPATHLEN-1);
81 #elif HAVE_STRERROR
82 // Copy the thread un-safe result of strerror into
83 // the buffer as fast as possible to minimize impact
84 // of collision of strerror in multiple threads.
85 if (errnum)
86 strncpy(buffer, strerror(errnum), MAXPATHLEN-1);
87 buffer[MAXPATHLEN-1] = 0;
88 #else
89 // Strange that this system doesn't even have strerror
90 // but, oh well, just use a generic message
91 sprintf(buffer, "Error #%d", errnum);
92 #endif
93 *ErrDest = prefix + ": " + buffer;
94 return true;
95 }
96
97 inline void ThrowErrno(const std::string& prefix, int errnum = -1) {
98 char buffer[MAXPATHLEN];
99 buffer[0] = 0;
100 if (errnum == -1)
101 errnum = errno;
102 #ifdef HAVE_STRERROR_R
103 // strerror_r is thread-safe.
104 if (errnum)
105 strerror_r(errnum,buffer,MAXPATHLEN-1);
106 #elif HAVE_STRERROR
107 // Copy the thread un-safe result of strerror into
108 // the buffer as fast as possible to minimize impact
109 // of collision of strerror in multiple threads.
110 if (errnum)
111 strncpy(buffer,strerror(errnum),MAXPATHLEN-1);
112 buffer[MAXPATHLEN-1] = 0;
113 #else
114 // Strange that this system doesn't even have strerror
115 // but, oh well, just use a generic message
116 sprintf(buffer, "Error #%d", errnum);
117 #endif
118 throw prefix + ": " + buffer;
119 }
120
12168 /// This function builds an error message into \p ErrMsg using the \p prefix
12269 /// string and the Unix error number given by \p errnum. If errnum is -1, the
12370 /// default then the value of errno is used.
160160 void BugDriver::compileProgram(Module *M) {
161161 // Emit the program to a bytecode file...
162162 sys::Path BytecodeFile ("bugpoint-test-program.bc");
163 BytecodeFile.makeUnique();
163 std::string ErrMsg;
164 if (BytecodeFile.makeUnique(true,&ErrMsg)) {
165 std::cerr << ToolName << ": Error making unique filename: " << ErrMsg
166 << "\n";
167 exit(1);
168 }
164169 if (writeProgramToFile(BytecodeFile.toString(), M)) {
165170 std::cerr << ToolName << ": Error emitting bytecode to file '"
166171 << BytecodeFile << "'!\n";
187192 if (AI == 0) AI = Interpreter;
188193 assert(AI && "Interpreter should have been created already!");
189194 bool CreatedBytecode = false;
195 std::string ErrMsg;
190196 if (BytecodeFile.empty()) {
191197 // Emit the program to a bytecode file...
192198 sys::Path uniqueFilename("bugpoint-test-program.bc");
193 uniqueFilename.makeUnique();
199 if (uniqueFilename.makeUnique(true, &ErrMsg)) {
200 std::cerr << ToolName << ": Error making unique filename: "
201 << ErrMsg << "!\n";
202 exit(1);
203 }
194204 BytecodeFile = uniqueFilename.toString();
195205
196206 if (writeProgramToFile(BytecodeFile, Program)) {
209219
210220 // Check to see if this is a valid output filename...
211221 sys::Path uniqueFile(OutputFile);
212 uniqueFile.makeUnique();
222 if (uniqueFile.makeUnique(true, &ErrMsg)) {
223 std::cerr << ToolName << ": Error making unique filename: "
224 << ErrMsg << "\n";
225 exit(1);
226 }
213227 OutputFile = uniqueFile.toString();
214228
215229 // Figure out which shared objects to run, if any.
775775 CleanupAndPrepareModules(BD, Test, Safe);
776776
777777 sys::Path TestModuleBC("bugpoint.test.bc");
778 TestModuleBC.makeUnique();
778 std::string ErrMsg;
779 if (TestModuleBC.makeUnique(true, &ErrMsg)) {
780 std::cerr << BD.getToolName() << "Error making unique filename: "
781 << ErrMsg << "\n";
782 exit(1);
783 }
779784 if (BD.writeProgramToFile(TestModuleBC.toString(), Test)) {
780785 std::cerr << "Error writing bytecode to `" << TestModuleBC << "'\nExiting.";
781786 exit(1);
784789
785790 // Make the shared library
786791 sys::Path SafeModuleBC("bugpoint.safe.bc");
787 SafeModuleBC.makeUnique();
792 if (SafeModuleBC.makeUnique(true, &ErrMsg)) {
793 std::cerr << BD.getToolName() << "Error making unique filename: "
794 << ErrMsg << "\n";
795 exit(1);
796 }
788797
789798 if (BD.writeProgramToFile(SafeModuleBC.toString(), Safe)) {
790799 std::cerr << "Error writing bytecode to `" << SafeModuleBC << "'\nExiting.";
835844 CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen);
836845
837846 sys::Path TestModuleBC("bugpoint.test.bc");
838 TestModuleBC.makeUnique();
847 std::string ErrMsg;
848 if (TestModuleBC.makeUnique(true, &ErrMsg)) {
849 std::cerr << getToolName() << "Error making unique filename: "
850 << ErrMsg << "\n";
851 exit(1);
852 }
839853
840854 if (writeProgramToFile(TestModuleBC.toString(), ToCodeGen)) {
841855 std::cerr << "Error writing bytecode to `" << TestModuleBC << "'\nExiting.";
845859
846860 // Make the shared library
847861 sys::Path SafeModuleBC("bugpoint.safe.bc");
848 SafeModuleBC.makeUnique();
862 if (SafeModuleBC.makeUnique(true, &ErrMsg)) {
863 std::cerr << getToolName() << "Error making unique filename: "
864 << ErrMsg << "\n";
865 exit(1);
866 }
849867
850868 if (writeProgramToFile(SafeModuleBC.toString(), ToNotCodeGen)) {
851869 std::cerr << "Error writing bytecode to `" << SafeModuleBC << "'\nExiting.";
138138 // setup the output file name
139139 std::cout << std::flush;
140140 sys::Path uniqueFilename("bugpoint-output.bc");
141 uniqueFilename.makeUnique();
141 std::string ErrMsg;
142 if (uniqueFilename.makeUnique(true, &ErrMsg)) {
143 std::cerr << getToolName() << ": Error making unique filename: "
144 << ErrMsg << "\n";
145 return(1);
146 }
142147 OutputFilename = uniqueFilename.toString();
143148
144149 // set up the input file name
145150 sys::Path inputFilename("bugpoint-input.bc");
146 inputFilename.makeUnique();
151 if (inputFilename.makeUnique(true, &ErrMsg)) {
152 std::cerr << getToolName() << ": Error making unique filename: "
153 << ErrMsg << "\n";
154 return(1);
155 }
147156 std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
148157 std::ios::binary;
149158 std::ofstream InFile(inputFilename.c_str(), io_mode);
178187 args[n++] = 0;
179188
180189 sys::Path prog(sys::Program::FindProgramByName(ToolName));
181 std::string ErrMsg;
182190 int result = sys::Program::ExecuteAndWait(prog,args,0,0,Timeout,&ErrMsg);
183191
184192 // If we are supposed to delete the bytecode file or if the passes crashed,
5252
5353 // Rerun the compiler, capturing any error messages to print them.
5454 sys::Path ErrorFilename("error_messages");
55 ErrorFilename.makeUnique();
55 std::string ErrMsg;
56 if (ErrorFilename.makeUnique(true, &ErrMsg)) {
57 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
58 exit(1);
59 }
5660 RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
5761 ErrorFilename); // FIXME: check return code ?
5862
152156 //
153157 void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) {
154158 sys::Path uniqueFile(Bytecode+".llc.s");
155 uniqueFile.makeUnique();
159 std::string ErrMsg;
160 if (uniqueFile.makeUnique(true, &ErrMsg)) {
161 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
162 exit(1);
163 }
156164 OutputAsmFile = uniqueFile;
157165 std::vector LLCArgs;
158166 LLCArgs.push_back (LLCPath.c_str());
306314
307315 void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) {
308316 sys::Path uniqueFile(Bytecode+".cbe.c");
309 uniqueFile.makeUnique();
317 std::string ErrMsg;
318 if (uniqueFile.makeUnique(true, &ErrMsg)) {
319 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
320 exit(1);
321 }
310322 OutputCFile = uniqueFile;
311323 std::vector LLCArgs;
312324 LLCArgs.push_back (LLCPath.c_str());
408420 GCCArgs.push_back("none");
409421 GCCArgs.push_back("-o");
410422 sys::Path OutputBinary (ProgramFile+".gcc.exe");
411 OutputBinary.makeUnique();
423 std::string ErrMsg;
424 if (OutputBinary.makeUnique(true, &ErrMsg)) {
425 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
426 exit(1);
427 }
412428 GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
413429
414430 // Add any arguments intended for GCC. We locate them here because this is
461477 std::string &OutputFile,
462478 const std::vector &ArgsForGCC) {
463479 sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
464 uniqueFilename.makeUnique();
480 std::string ErrMsg;
481 if (uniqueFilename.makeUnique(true, &ErrMsg)) {
482 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
483 exit(1);
484 }
465485 OutputFile = uniqueFilename.toString();
466486
467487 std::vector GCCArgs;