mirror of
https://github.com/NixOS/nix
synced 2025-06-27 00:11:17 +02:00
fetchMercurial: Don't fetch hashes we already have
This commit is contained in:
parent
1969f357b7
commit
e026bc3b05
4 changed files with 74 additions and 28 deletions
|
@ -895,32 +895,46 @@ std::vector<char *> stringsToCharPtrs(const Strings & ss)
|
|||
|
||||
string runProgram(Path program, bool searchPath, const Strings & args,
|
||||
const std::experimental::optional<std::string> & input)
|
||||
{
|
||||
RunOptions opts(program, args);
|
||||
opts.searchPath = searchPath;
|
||||
opts.input = input;
|
||||
|
||||
auto res = runProgram(opts);
|
||||
|
||||
if (!statusOk(res.first))
|
||||
throw ExecError(res.first, fmt("program '%1%' %2%", program, statusToString(res.first)));
|
||||
|
||||
return res.second;
|
||||
}
|
||||
|
||||
std::pair<int, std::string> runProgram(const RunOptions & options)
|
||||
{
|
||||
checkInterrupt();
|
||||
|
||||
/* Create a pipe. */
|
||||
Pipe out, in;
|
||||
out.create();
|
||||
if (input) in.create();
|
||||
if (options.input) in.create();
|
||||
|
||||
/* Fork. */
|
||||
Pid pid = startProcess([&]() {
|
||||
if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
|
||||
throw SysError("dupping stdout");
|
||||
if (input && dup2(in.readSide.get(), STDIN_FILENO) == -1)
|
||||
if (options.input && dup2(in.readSide.get(), STDIN_FILENO) == -1)
|
||||
throw SysError("dupping stdin");
|
||||
|
||||
Strings args_(args);
|
||||
args_.push_front(program);
|
||||
Strings args_(options.args);
|
||||
args_.push_front(options.program);
|
||||
|
||||
restoreSignals();
|
||||
|
||||
if (searchPath)
|
||||
execvp(program.c_str(), stringsToCharPtrs(args_).data());
|
||||
if (options.searchPath)
|
||||
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
|
||||
else
|
||||
execv(program.c_str(), stringsToCharPtrs(args_).data());
|
||||
execv(options.program.c_str(), stringsToCharPtrs(args_).data());
|
||||
|
||||
throw SysError(format("executing '%1%'") % program);
|
||||
throw SysError("executing '%1%'", options.program);
|
||||
});
|
||||
|
||||
out.writeSide = -1;
|
||||
|
@ -935,11 +949,11 @@ string runProgram(Path program, bool searchPath, const Strings & args,
|
|||
});
|
||||
|
||||
|
||||
if (input) {
|
||||
if (options.input) {
|
||||
in.readSide = -1;
|
||||
writerThread = std::thread([&]() {
|
||||
try {
|
||||
writeFull(in.writeSide.get(), *input);
|
||||
writeFull(in.writeSide.get(), *options.input);
|
||||
promise.set_value();
|
||||
} catch (...) {
|
||||
promise.set_exception(std::current_exception());
|
||||
|
@ -952,14 +966,11 @@ string runProgram(Path program, bool searchPath, const Strings & args,
|
|||
|
||||
/* Wait for the child to finish. */
|
||||
int status = pid.wait();
|
||||
if (!statusOk(status))
|
||||
throw ExecError(status, format("program '%1%' %2%")
|
||||
% program % statusToString(status));
|
||||
|
||||
/* Wait for the writer thread to finish. */
|
||||
if (input) promise.get_future().get();
|
||||
if (options.input) promise.get_future().get();
|
||||
|
||||
return result;
|
||||
return {status, result};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -245,6 +245,23 @@ string runProgram(Path program, bool searchPath = false,
|
|||
const Strings & args = Strings(),
|
||||
const std::experimental::optional<std::string> & input = {});
|
||||
|
||||
struct RunOptions
|
||||
{
|
||||
Path program;
|
||||
bool searchPath = true;
|
||||
Strings args;
|
||||
std::experimental::optional<std::string> input;
|
||||
bool _killStderr = false;
|
||||
|
||||
RunOptions(const Path & program, const Strings & args)
|
||||
: program(program), args(args) { };
|
||||
|
||||
RunOptions & killStderr(bool v) { _killStderr = true; return *this; }
|
||||
};
|
||||
|
||||
std::pair<int, std::string> runProgram(const RunOptions & options);
|
||||
|
||||
|
||||
class ExecError : public Error
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue