Skip to content

Commit cd890c8

Browse files
committed
process: fix duplicate output, bug fixes
* flush all streams before `fork()` to ensure pending output does not get duplicated. Redirecting compiler or tester output to a file or a pipe produced extra output. * test and report `fork()` failures * pass `nil` instead of `0` as last argument to `execl` to ensure a pointer is passed instead of an `int` that has a different size on 64-bit targets.
1 parent 90c60a7 commit cd890c8

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

common/process_utils.c2

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ fn void child_error(i32 fd, const char* msg) {
5050
}
5151

5252
public fn i32 run(const char* path, const char* cmd, const char* logfile) {
53+
// run a command in a child process
54+
// - stdout and stderr are redirected together to a logfile
55+
56+
// flush all streams before forking to avoid duplicate output
57+
fflush(nil);
58+
5359
i32[2] error_pipe;
5460
if (pipe(error_pipe)) {
5561
fprintf(stderr, "pipe() failed: %s\n", strerror(*errno2()));
@@ -66,6 +72,10 @@ public fn i32 run(const char* path, const char* cmd, const char* logfile) {
6672
}
6773

6874
Pid child_pid = fork();
75+
if (child_pid == -1) {
76+
fprintf(stderr, "fork() failed: %s\n", strerror(*errno2()));
77+
return -1;
78+
}
6979
if (child_pid == 0) { // child
7080
char[256] errmsg;
7181

@@ -196,6 +206,12 @@ fn const char* find_bin(char *dest, usize size, const char* name) {
196206

197207
public fn i32 run_args(const char* path, const char* cmd, const char* logfile, const char* args)
198208
{
209+
// run a command in a child process
210+
// - stdout and stderr are redirected together to a logfile
211+
212+
// flush all streams before forking to avoid duplicate output
213+
fflush(nil);
214+
199215
i32[2] error_pipe;
200216
if (pipe(error_pipe)) {
201217
fprintf(stderr, "pipe() failed: %s\n", strerror(*errno2()));
@@ -212,6 +228,10 @@ public fn i32 run_args(const char* path, const char* cmd, const char* logfile, c
212228
}
213229

214230
Pid child_pid = fork();
231+
if (child_pid == -1) {
232+
fprintf(stderr, "fork() failed: %s\n", strerror(*errno2()));
233+
return -1;
234+
}
215235
if (child_pid == 0) { // child
216236
char[256] errmsg;
217237

common/process_utils2.c2

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ import string_utils;
2727

2828
public fn i32 run2(const char* path, const char* cmd, const char* args, char* output)
2929
{
30+
// run a command in a child process
31+
// - stdout and stderr are redirected together and captured into the `output` buffer
32+
// TODO merge with run_args.
33+
34+
// flush all streams before forking to avoid duplicate output
35+
fflush(nil);
36+
3037
i32[2] error_pipe;
3138
if (pipe(error_pipe)) {
3239
fprintf(stderr, "pipe() failed: %s\n", strerror(*errno2()));
@@ -70,7 +77,6 @@ public fn i32 run2(const char* path, const char* cmd, const char* args, char* ou
7077
}
7178

7279
// redirect output
73-
fflush(stdout);
7480
close(STDOUT_FILENO);
7581
if (dup(output_pipe[1]) == -1) {
7682
sprintf(errmsg, "dup(): %s", strerror(*errno2()));

generator/qbe_generator.c2

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,11 +596,19 @@ public fn void generate(const char* target,
596596

597597
public fn void build(const char* output_dir)
598598
{
599+
const char* make = "make";
600+
#if SYSTEM_FREEBSD
601+
make = "gmake";
602+
#endif
603+
#if SYSTEM_OPENBSD
604+
make = "gmake";
605+
#endif
606+
599607
// TODO put in aux-pool? (lowers stack-size)
600608
char[constants.Max_path] dir;
601609
stdio.sprintf(dir, "%s/%s/", output_dir, QBE_Dir);
602610

603-
i32 retval = process_utils.run(dir, "/usr/bin/make", LogFile);
611+
i32 retval = process_utils.run_args(dir, make, LogFile, "");
604612
if (retval != 0) {
605613
console.error("error during external QBE compilation");
606614
console.log("see %s%s for details", dir, LogFile);

tools/tester/test_db.c2

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,9 @@ public fn bool Db.parse(Db* db) {
751751
}
752752

753753
public fn void Db.testFile(Db* db) {
754+
// flush all streams before forking to avoid duplicate output
755+
fflush(nil);
756+
754757
i32[2] pipe_stdout;
755758
if (pipe(pipe_stdout) == -1) {
756759
fprintf(stderr, "pipe() failed: %s\n", strerror(*errno2()));
@@ -775,7 +778,7 @@ public fn void Db.testFile(Db* db) {
775778
while ((dup2(pipe_stderr[1], STDERR_FILENO) == -1) && (*errno2() == EINTR)) {}
776779
close(pipe_stderr[1]);
777780
close(pipe_stderr[0]);
778-
execl(db.c2c_cmd, "c2c", "-d", db.tmp_dir, "--test", 0);
781+
execl(db.c2c_cmd, "c2c", "-d", db.tmp_dir, "--test", nil);
779782
fprintf(stderr, "execl() failed: %s\n", strerror(*errno2()));
780783
exit(127); /* only if execv fails */
781784
} else { // parent

0 commit comments

Comments
 (0)