diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-06-28 03:48:47 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-06-28 03:48:47 +0000 |
commit | e79a87226aa5d557ca07325db99264747e56d4fb (patch) | |
tree | 5686417455d97252da2683b58bb50f44602c782e /llvm/lib/Support/Path.cpp | |
parent | 1a54aad50b3547e025f4e553d548ae9e5cd7d783 (diff) | |
download | bcm5719-llvm-e79a87226aa5d557ca07325db99264747e56d4fb.tar.gz bcm5719-llvm-e79a87226aa5d557ca07325db99264747e56d4fb.zip |
Improvements to unique_file and createUniqueDirectory.
* Don't try to create parent directories in unique_file. It had two problem:
* It violates the contract that it is atomic. If the directory creation
success and the file creation fails, we would return an error but the
file system was modified.
* When creating a temporary file clang would have to first check if the
parent directory existed or not to avoid creating one when it was not
supposed to.
* More efficient implementations of createUniqueDirectory and the unique_file
that produces only the file name. Now all 3 just call into a static
function passing what they want (name, file or directory).
Clang also has to be updated, so tests might fail if a bot picks up this commit
and not the corresponding clang one.
llvm-svn: 185126
Diffstat (limited to 'llvm/lib/Support/Path.cpp')
-rw-r--r-- | llvm/lib/Support/Path.cpp | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp index 1f4f44acb08..fa03df5a24a 100644 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -153,6 +153,18 @@ namespace { } } // end unnamed namespace +enum FSEntity { + FS_Dir, + FS_File, + FS_Name +}; + +// Implemented in Unix/Path.inc and Windows/Path.inc. +static llvm::error_code +createUniqueEntity(const llvm::Twine &Model, int &ResultFD, + llvm::SmallVectorImpl<char> &ResultPath, + bool MakeAbsolute, unsigned Mode, FSEntity Type); + namespace llvm { namespace sys { namespace path { @@ -625,32 +637,31 @@ bool is_relative(const Twine &path) { namespace fs { +// This is a mkostemps with a different pattern. Unfortunatelly OS X (ond *BSD) +// don't have it. It might be worth experimenting with mkostemps on systems +// that have it. +error_code unique_file(const Twine &Model, int &ResultFD, + SmallVectorImpl<char> &ResultPath, bool MakeAbsolute, + unsigned Mode) { + return createUniqueEntity(Model, ResultFD, ResultPath, MakeAbsolute, Mode, + FS_File); +} + +// This is a mktemp with a differet pattern. We use createUniqueEntity mostly +// for consistency. It might be worth it experimenting with mktemp. error_code unique_file(const Twine &Model, SmallVectorImpl<char> &ResultPath, bool MakeAbsolute) { - // FIXME: This is really inefficient. unique_path creates a path an tries to - // open it. We should factor the code so that we just don't create/open the - // file when we don't need it. - int FD; - error_code Ret = unique_file(Model, FD, ResultPath, MakeAbsolute, all_read); - if (Ret) - return Ret; - - if (close(FD)) - return error_code(errno, system_category()); - - StringRef P(ResultPath.begin(), ResultPath.size()); - return fs::remove(P); + int Dummy; + return createUniqueEntity(Model, Dummy, ResultPath, MakeAbsolute, 0, FS_Name); } +// This is a mkdtemp with a different pattern. We use createUniqueEntity mostly +// for consistency. It might be worth it experimenting with mkdtemp. error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl<char> &ResultPath) { - // FIXME: This is double inefficient. We compute a unique file name, created - // it, delete it and keep only the directory. - error_code EC = unique_file(Prefix + "-%%%%%%/dummy", ResultPath); - if (EC) - return EC; - path::remove_filename(ResultPath); - return error_code::success(); + int Dummy; + return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath, + true, 0, FS_Dir); } error_code make_absolute(SmallVectorImpl<char> &path) { |