Skip to content

Commit 09a4e6c

Browse files
author
Daniel Kroening
committed
run() can now redirect stderr
1 parent da34ceb commit 09a4e6c

File tree

4 files changed

+67
-36
lines changed

4 files changed

+67
-36
lines changed

src/goto-cc/as_mode.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ int as_modet::run_as()
267267
std::cout << '\n';
268268
#endif
269269

270-
return run(new_argv[0], new_argv, cmdline.stdin_file, "");
270+
return run(new_argv[0], new_argv, cmdline.stdin_file);
271271
}
272272

273273
int as_modet::as_hybrid_binary()
@@ -314,7 +314,7 @@ int as_modet::as_hybrid_binary()
314314
objcopy_argv.push_back("--remove-section=goto-cc");
315315
objcopy_argv.push_back(output_file);
316316

317-
result=run(objcopy_argv[0], objcopy_argv, "", "");
317+
result = run(objcopy_argv[0], objcopy_argv);
318318
}
319319

320320
if(result==0)
@@ -327,7 +327,7 @@ int as_modet::as_hybrid_binary()
327327
objcopy_argv.push_back("goto-cc="+saved);
328328
objcopy_argv.push_back(output_file);
329329

330-
result=run(objcopy_argv[0], objcopy_argv, "", "");
330+
result = run(objcopy_argv[0], objcopy_argv);
331331
}
332332

333333
int remove_result=remove(saved.c_str());
@@ -354,7 +354,7 @@ int as_modet::as_hybrid_binary()
354354
lipo_argv.push_back("-output");
355355
lipo_argv.push_back(output_file);
356356

357-
result=run(lipo_argv[0], lipo_argv, "", "");
357+
result = run(lipo_argv[0], lipo_argv);
358358
}
359359

360360
int remove_result=remove(saved.c_str());

src/goto-cc/gcc_mode.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ int gcc_modet::run_gcc(const compilet &compiler)
831831
debug() << " " << new_argv[i];
832832
debug() << eom;
833833

834-
return run(new_argv[0], new_argv, cmdline.stdin_file, "");
834+
return run(new_argv[0], new_argv, cmdline.stdin_file);
835835
}
836836

837837
int gcc_modet::gcc_hybrid_binary(compilet &compiler)

src/util/run.cpp

+59-29
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ Date: August 2012
1010

1111
#include "run.h"
1212

13-
#include <cassert>
14-
1513
#ifdef _WIN32
1614
#include <process.h>
1715
#else
@@ -30,6 +28,7 @@ Date: August 2012
3028

3129
#endif
3230

31+
#include <util/invariant.h>
3332
#include <util/unicode.h>
3433
#include <util/signal_catcher.h>
3534

@@ -39,19 +38,59 @@ int run_shell(const std::string &command)
3938
std::vector<std::string> argv;
4039
argv.push_back(shell);
4140
argv.push_back(command);
42-
return run(shell, argv, "", "");
41+
return run(shell, argv, "", "", "");
42+
}
43+
44+
#ifndef _WIN32
45+
/// open given file to replace either stdin, stderr, stdout
46+
static int stdio_redirection(int fd, const std::string &file)
47+
{
48+
int result_fd = fd;
49+
50+
if(file.empty())
51+
return result_fd;
52+
53+
int flags = 0, mode = 0;
54+
std::string name;
55+
56+
switch(fd)
57+
{
58+
case STDIN_FILENO:
59+
flags = O_RDONLY;
60+
name = "stdin";
61+
break;
62+
63+
case STDOUT_FILENO:
64+
case STDERR_FILENO:
65+
flags = O_CREAT | O_WRONLY;
66+
mode = S_IRUSR | S_IWUSR;
67+
name = fd == STDOUT_FILENO ? "stdout" : "stderr";
68+
break;
69+
70+
default:
71+
UNREACHABLE;
72+
}
73+
74+
result_fd = open(file.c_str(), flags, mode);
75+
if(result_fd == -1)
76+
perror(("Failed to open " + name + " file " + file).c_str());
77+
78+
return result_fd;
4379
}
80+
#endif
4481

4582
int run(
4683
const std::string &what,
4784
const std::vector<std::string> &argv,
4885
const std::string &std_input,
49-
const std::string &std_output)
86+
const std::string &std_output,
87+
const std::string &std_error)
5088
{
5189
#ifdef _WIN32
52-
// we don't support stdin/stdout redirection on Windows
53-
assert(std_input.empty());
54-
assert(std_output.empty());
90+
// we don't support stdin/stdout/stderr redirection on Windows
91+
PRECONDITION(std_input.empty());
92+
PRECONDITION(std_output.empty());
93+
PRECONDITION(std_error.empty());
5594

5695
// unicode version of the arguments
5796
std::vector<std::wstring> wargv;
@@ -77,29 +116,12 @@ int run(
77116
return status;
78117

79118
#else
80-
int stdin_fd=STDIN_FILENO;
119+
int stdin_fd = stdio_redirection(STDIN_FILENO, std_input);
120+
int stdout_fd = stdio_redirection(STDOUT_FILENO, std_output);
121+
int stderr_fd = stdio_redirection(STDERR_FILENO, std_error);
81122

82-
if(!std_input.empty())
83-
{
84-
stdin_fd=open(std_input.c_str(), O_RDONLY);
85-
if(stdin_fd==-1)
86-
{
87-
perror("Failed to open stdin copy");
88-
return 1;
89-
}
90-
}
91-
92-
int stdout_fd=STDOUT_FILENO;
93-
94-
if(!std_output.empty())
95-
{
96-
stdout_fd=open(std_output.c_str(), O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
97-
if(stdout_fd==-1)
98-
{
99-
perror("Failed to open stdout copy");
100-
return 1;
101-
}
102-
}
123+
if(stdin_fd == -1 || stdout_fd == -1 || stderr_fd == -1)
124+
return 1;
103125

104126
// temporarily suspend all signals
105127
sigset_t new_mask, old_mask;
@@ -127,6 +149,8 @@ int run(
127149
dup2(stdin_fd, STDIN_FILENO);
128150
if(stdout_fd!=STDOUT_FILENO)
129151
dup2(stdout_fd, STDOUT_FILENO);
152+
if(stderr_fd != STDERR_FILENO)
153+
dup2(stderr_fd, STDERR_FILENO);
130154

131155
errno=0;
132156
execvp(what.c_str(), _argv.data());
@@ -153,13 +177,17 @@ int run(
153177
close(stdin_fd);
154178
if(stdout_fd!=STDOUT_FILENO)
155179
close(stdout_fd);
180+
if(stderr_fd != STDERR_FILENO)
181+
close(stderr_fd);
156182
return 1;
157183
}
158184

159185
if(stdin_fd!=STDIN_FILENO)
160186
close(stdin_fd);
161187
if(stdout_fd!=STDOUT_FILENO)
162188
close(stdout_fd);
189+
if(stderr_fd != STDERR_FILENO)
190+
close(stderr_fd);
163191

164192
return WEXITSTATUS(status);
165193
}
@@ -173,6 +201,8 @@ int run(
173201
close(stdin_fd);
174202
if(stdout_fd!=STDOUT_FILENO)
175203
close(stdout_fd);
204+
if(stderr_fd != STDERR_FILENO)
205+
close(stderr_fd);
176206

177207
return 1;
178208
}

src/util/run.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ Date: August 2012
1818
int run(
1919
const std::string &what,
2020
const std::vector<std::string> &argv,
21-
const std::string &std_input,
22-
const std::string &std_output);
21+
const std::string &std_input = "",
22+
const std::string &std_output = "",
23+
const std::string &std_error = "");
2324

2425
int run_shell(const std::string &command);
2526

0 commit comments

Comments
 (0)