aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-11-18 17:32:25 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-11-19 12:43:34 +0300
commit15507d112650477ad64a5c9b19b4e515124affec (patch)
tree90911eccece558cd5642fa820d113c02aa2905c4
parentbb601c7d4e948035e1a087c7720aae6e2e7ef973 (diff)
Fix set buildscript builtin crash on Windows
-rw-r--r--libbuild2/script/run.cxx20
-rw-r--r--tests/test/script/runner/set.testscript9
2 files changed, 27 insertions, 2 deletions
diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx
index 703cd11..ca4a935 100644
--- a/libbuild2/script/run.cxx
+++ b/libbuild2/script/run.cxx
@@ -844,6 +844,11 @@ namespace build2
set_builtin (environment& env,
const strings& args,
auto_fd in,
+#ifndef _WIN32
+ bool,
+#else
+ bool pipe,
+#endif
const optional<deadline>& dl,
const command& deadline_cmd,
const location& ll)
@@ -889,7 +894,19 @@ namespace build2
// variable value will be incomplete, but we leave it to the caller
// to handle that.
//
+ // Note that on Windows we can only turn pipe file descriptors into
+ // the non-blocking mode. Thus, we have no choice but to read from
+ // descriptors of other types synchronously there. That implies that
+ // we can potentially block indefinitely reading a file and missing
+ // the deadline on Windows. Note though, that the user can always
+ // rewrite `set foo <<<file` with `cat file | set foo` to avoid this
+ // problem.
+ //
+#ifndef _WIN32
if (dl)
+#else
+ if (dl && pipe)
+#endif
{
fdselect_set fds {in.get ()};
cin.open (move (in), fdstream_mode::non_blocking);
@@ -1398,7 +1415,8 @@ namespace build2
if (verb >= 2)
print_process (process_args ());
- set_builtin (env, c.arguments, move (ifd),
+ set_builtin (env, c.arguments,
+ move (ifd), !first,
dl, dl_cmd != nullptr ? *dl_cmd : c,
ll);
diff --git a/tests/test/script/runner/set.testscript b/tests/test/script/runner/set.testscript
index 41709e4..777eccf 100644
--- a/tests/test/script/runner/set.testscript
+++ b/tests/test/script/runner/set.testscript
@@ -276,7 +276,14 @@
:
$c <<EOI && $b
env -t 10 -- $* -o 'foo' | set bar;
- echo $bar >foo 2>|
+ echo "$bar" >'foo'
+ EOI
+
+ : non-pipe
+ :
+ $c <<EOI && $b
+ env -t 10 -- set bar <'foo';
+ echo "$bar" >'foo'
EOI
: set-reached