diff options
-rw-r--r-- | src/nix/search.cc | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/nix/search.cc b/src/nix/search.cc index a9dc2d6b924b..87cdb2d7ed8a 100644 --- a/src/nix/search.cc +++ b/src/nix/search.cc @@ -214,13 +214,28 @@ struct CmdSearch : SourceExprCommand, MixJSON } else { + createDirs(dirOf(jsonCacheFileName)); + Path tmpFile = fmt("%s.tmp.%d", jsonCacheFileName, getpid()); - std::ofstream jsonCacheFile(tmpFile); + std::ofstream jsonCacheFile; + + try { + // iostream considered harmful + jsonCacheFile.exceptions(std::ofstream::failbit); + jsonCacheFile.open(tmpFile); - auto cache = writeCache ? std::make_unique<JSONObject>(jsonCacheFile, false) : nullptr; + auto cache = writeCache ? std::make_unique<JSONObject>(jsonCacheFile, false) : nullptr; - doExpr(getSourceExpr(*state), "", true, cache.get()); + doExpr(getSourceExpr(*state), "", true, cache.get()); + + } catch (std::exception &) { + /* Fun fact: catching std::ios::failure does not work + due to C++11 ABI shenanigans. + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145 */ + if (!jsonCacheFile) + throw Error("error writing to %s", tmpFile); + } if (rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1) throw SysError("cannot rename '%s' to '%s'", tmpFile, jsonCacheFileName); |