@@ -46,12 +46,15 @@ public:
46
46
// / the current process's environment will be used instead.
47
47
ArrayRef<const char *> Env;
48
48
49
+ // / True if the errors of the Task should be stored in Errors instead of Output.
50
+ bool SeparateErrors;
51
+
49
52
// / Context associated with this Task.
50
53
void *Context;
51
54
52
55
Task (const char *ExecPath, ArrayRef<const char *> Args,
53
- ArrayRef<const char *> Env = llvm::None, void *Context = nullptr )
54
- : ExecPath(ExecPath), Args(Args), Env(Env), Context(Context) {}
56
+ ArrayRef<const char *> Env = llvm::None, void *Context = nullptr , bool SeparateErrors = false )
57
+ : ExecPath(ExecPath), Args(Args), Env(Env), Context(Context), SeparateErrors(SeparateErrors) {}
55
58
};
56
59
57
60
} // end namespace sys
@@ -75,10 +78,7 @@ unsigned TaskQueue::getNumberOfParallelTasks() const {
75
78
void TaskQueue::addTask (const char *ExecPath, ArrayRef<const char *> Args,
76
79
ArrayRef<const char *> Env, void *Context,
77
80
bool SeparateErrors) {
78
- // This implementation of TaskQueue ignores SeparateErrors.
79
- // We need to reference SeparateErrors to avoid warnings, though.
80
- (void )SeparateErrors;
81
- std::unique_ptr<Task> T (new Task (ExecPath, Args, Env, Context));
81
+ std::unique_ptr<Task> T (new Task (ExecPath, Args, Env, Context, SeparateErrors));
82
82
QueuedTasks.push (std::move (T));
83
83
}
84
84
@@ -104,16 +104,18 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
104
104
: decltype (Envp)(llvm::toStringRefArray (T->Env .data ()));
105
105
106
106
llvm::SmallString<64 > stdoutPath;
107
- llvm::SmallString<64 > stderrPath;
108
- if (fs::createTemporaryFile (" stdout" , " tmp" , stdoutPath)
109
- || fs::createTemporaryFile (" stderr" , " tmp" , stderrPath)) {
107
+ if (fs::createTemporaryFile (" stdout" , " tmp" , stdoutPath))
110
108
return true ;
111
- }
112
-
113
109
llvm::sys::RemoveFileOnSignal (stdoutPath);
114
- llvm::sys::RemoveFileOnSignal (stderrPath);
115
110
116
- Optional<StringRef> redirects[] = {None, {stdoutPath}, {stderrPath}};
111
+ llvm::SmallString<64 > stderrPath;
112
+ if (T->SeparateErrors ) {
113
+ if (fs::createTemporaryFile (" stderr" , " tmp" , stdoutPath))
114
+ return true ;
115
+ llvm::sys::RemoveFileOnSignal (stderrPath);
116
+ }
117
+
118
+ Optional<StringRef> redirects[] = {None, {stdoutPath}, {T->SeparateErrors ? stderrPath : stdoutPath}};
117
119
118
120
bool ExecutionFailed = false ;
119
121
ProcessInfo PI = ExecuteNoWait (T->ExecPath ,
@@ -133,10 +135,13 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
133
135
int ReturnCode = PI.ReturnCode ;
134
136
135
137
auto stdoutBuffer = llvm::MemoryBuffer::getFile (stdoutPath);
136
- auto stderrBuffer = llvm::MemoryBuffer::getFile (stderrPath);
137
-
138
138
StringRef stdoutContents = stdoutBuffer.get ()->getBuffer ();
139
- StringRef stderrContents = stderrBuffer.get ()->getBuffer ();
139
+
140
+ StringRef stderrContents;
141
+ if (T->SeparateErrors ) {
142
+ auto stderrBuffer = llvm::MemoryBuffer::getFile (stderrPath);
143
+ stderrContents = stderrBuffer.get ()->getBuffer ();
144
+ }
140
145
141
146
if (ReturnCode == -2 ) {
142
147
// Wait() returning a return code of -2 indicates the process received
@@ -161,7 +166,8 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
161
166
}
162
167
}
163
168
llvm::sys::fs::remove (stdoutPath);
164
- llvm::sys::fs::remove (stderrPath);
169
+ if (T->SeparateErrors )
170
+ llvm::sys::fs::remove (stderrPath);
165
171
}
166
172
167
173
return !ContinueExecution;
0 commit comments