Skip to content

Commit 4c98233

Browse files
jonludlamrgrinberg
authored andcommitted
Delay opening redirected files until execing cmd (#1635)
1 parent f218d27 commit 4c98233

File tree

7 files changed

+24
-64
lines changed

7 files changed

+24
-64
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
- Fix preprocessing for libraries with `(include_subdirs ..)` (#1624, fix #1626,
88
@nojb, @rgrinberg)
99

10+
- Delay opening redirected output files until executing commands (#1633,
11+
@jonludlam)
12+
1013
1.6.2 (05/12/2018)
1114
------------------
1215

src/action_exec.ml

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,8 @@ type exec_context =
88
}
99

1010
let get_std_output : _ -> Process.std_output_to = function
11-
| None -> Terminal
12-
| Some (fn, oc) ->
13-
Opened_file { filename = fn
14-
; tail = false
15-
; desc = Channel oc }
16-
11+
| None -> Terminal
12+
| Some fn -> File fn
1713

1814
let exec_run_direct ~ectx ~dir ~env ~stdout_to ~stderr_to prog args =
1915
begin match ectx.context with
@@ -44,7 +40,7 @@ let exec_echo stdout_to str =
4440
Fiber.return
4541
(match stdout_to with
4642
| None -> print_string str; flush stdout
47-
| Some (_, oc) -> output_string oc str)
43+
| Some fn -> Io.write_file fn str)
4844

4945
let rec exec t ~ectx ~dir ~env ~stdout_to ~stderr_to =
5046
match (t : Action.t) with
@@ -60,15 +56,6 @@ let rec exec t ~ectx ~dir ~env ~stdout_to ~stderr_to =
6056
| Redirect (Stdout, fn, Echo s) ->
6157
Io.write_file fn (String.concat s ~sep:" ");
6258
Fiber.return ()
63-
| Redirect (outputs, fn, Run (Ok prog, args)) ->
64-
let out = Process.File fn in
65-
let stdout_to, stderr_to =
66-
match outputs with
67-
| Stdout -> (out, get_std_output stderr_to)
68-
| Stderr -> (get_std_output stdout_to, out)
69-
| Outputs -> (out, out)
70-
in
71-
exec_run_direct ~ectx ~dir ~env ~stdout_to ~stderr_to prog args
7259
| Redirect (outputs, fn, t) ->
7360
redirect ~ectx ~dir outputs fn t ~env ~stdout_to ~stderr_to
7461
| Ignore (outputs, t) ->
@@ -78,12 +65,9 @@ let rec exec t ~ectx ~dir ~env ~stdout_to ~stderr_to =
7865
| Echo strs -> exec_echo stdout_to (String.concat strs ~sep:" ")
7966
| Cat fn ->
8067
Io.with_file_in fn ~f:(fun ic ->
81-
let oc =
82-
match stdout_to with
83-
| None -> stdout
84-
| Some (_, oc) -> oc
85-
in
86-
Io.copy_channels ic oc);
68+
match stdout_to with
69+
| None -> Io.copy_channels ic stdout
70+
| Some fn -> Io.with_file_out fn ~f:(fun oc -> Io.copy_channels ic oc));
8771
Fiber.return ()
8872
| Copy (src, dst) ->
8973
Io.copy_file ~src ~dst ();
@@ -195,16 +179,16 @@ let rec exec t ~ectx ~dir ~env ~stdout_to ~stderr_to =
195179
Fiber.return ()
196180

197181
and redirect outputs fn t ~ectx ~dir ~env ~stdout_to ~stderr_to =
198-
let oc = Io.open_out fn in
199-
let out = Some (fn, oc) in
182+
(* We resolve the path to an absolute one here to ensure no
183+
Chdir actions change the eventual path of the file *)
184+
let out = Some (Path.to_absolute fn) in
200185
let stdout_to, stderr_to =
201186
match outputs with
202187
| Stdout -> (out, stderr_to)
203188
| Stderr -> (stdout_to, out)
204189
| Outputs -> (out, out)
205190
in
206-
exec t ~ectx ~dir ~env ~stdout_to ~stderr_to >>| fun () ->
207-
close_out oc
191+
exec t ~ectx ~dir ~env ~stdout_to ~stderr_to
208192

209193
and exec_list l ~ectx ~dir ~env ~stdout_to ~stderr_to =
210194
match l with

src/build.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ let symlink ~src ~dst =
249249
action ~targets:[dst] (Symlink (src, dst))
250250

251251
let create_file fn =
252-
action ~targets:[fn] (Redirect (Stdout, fn, Progn []))
252+
action ~targets:[fn] (Redirect (Stdout, fn, Echo []))
253253

254254
let remove_tree dir =
255255
arr (fun _ -> Action.Remove_tree dir)

src/process.ml

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,6 @@ let map_result
3333
type std_output_to =
3434
| Terminal
3535
| File of Path.t
36-
| Opened_file of opened_file
37-
38-
and opened_file =
39-
{ filename : Path.t
40-
; desc : opened_file_desc
41-
; tail : bool
42-
}
43-
44-
and opened_file_desc =
45-
| Fd of Unix.file_descr
46-
| Channel of out_channel
4736

4837
type purpose =
4938
| Internal_job
@@ -125,19 +114,18 @@ module Fancy = struct
125114
| Some dir -> sprintf "(cd %s && %s)" (Path.to_string dir) s
126115
in
127116
match stdout_to, stderr_to with
128-
| (File fn1 | Opened_file { filename = fn1; _ }),
129-
(File fn2 | Opened_file { filename = fn2; _ }) when Path.equal fn1 fn2 ->
117+
| File fn1, File fn2 when Path.equal fn1 fn2 ->
130118
sprintf "%s &> %s" s (Path.to_string fn1)
131119
| _ ->
132120
let s =
133121
match stdout_to with
134122
| Terminal -> s
135-
| File fn | Opened_file { filename = fn; _ } ->
123+
| File fn ->
136124
sprintf "%s > %s" s (Path.to_string fn)
137125
in
138126
match stderr_to with
139127
| Terminal -> s
140-
| File fn | Opened_file { filename = fn; _ } ->
128+
| File fn ->
141129
sprintf "%s 2> %s" s (Path.to_string fn)
142130

143131
let pp_purpose ppf = function
@@ -196,19 +184,11 @@ let get_std_output ~default = function
196184
| File fn ->
197185
let fd = Unix.openfile (Path.to_string fn)
198186
[O_WRONLY; O_CREAT; O_TRUNC; O_SHARE_DELETE] 0o666 in
199-
(fd, Some (Fd fd))
200-
| Opened_file { desc; tail; _ } ->
201-
let fd =
202-
match desc with
203-
| Fd fd -> fd
204-
| Channel oc -> flush oc; Unix.descr_of_out_channel oc
205-
in
206-
(fd, Option.some_if tail desc)
187+
(fd, Some fd)
207188

208189
let close_std_output = function
209190
| None -> ()
210-
| Some (Fd fd) -> Unix.close fd
211-
| Some (Channel oc) -> close_out oc
191+
| Some fd -> Unix.close fd
212192

213193
let gen_id =
214194
let next = ref (-1) in

src/process.mli

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,6 @@ type ('a, 'b) failure_mode =
1818
type std_output_to =
1919
| Terminal
2020
| File of Path.t
21-
| Opened_file of opened_file
22-
23-
and opened_file =
24-
{ filename : Path.t
25-
; desc : opened_file_desc
26-
; tail : bool
27-
(** If [true], the descriptor is closed after starting the command *)
28-
}
29-
30-
and opened_file_desc =
31-
| Fd of Unix.file_descr
32-
| Channel of out_channel
3321

3422
(** Why a Fiber.t was run *)
3523
type purpose =

src/stdune/path.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,8 @@ let of_filename_relative_to_initial_cwd fn =
626626

627627
let to_absolute_filename t = Kind.to_absolute_filename (kind t)
628628

629+
let to_absolute t = external_ (External.of_string (to_absolute_filename t))
630+
629631
let external_of_local x ~root =
630632
External.to_string (External.relative root (Local.to_string x))
631633

src/stdune/path.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ val of_filename_relative_to_initial_cwd : string -> t
6666
root has been set. [root] is the root directory of local paths *)
6767
val to_absolute_filename : t -> string
6868

69+
(** Convert any path to an absolute path *)
70+
val to_absolute : t -> t
71+
6972
val reach : t -> from:t -> string
7073

7174
(** [from] defaults to [Path.root] *)

0 commit comments

Comments
 (0)