@@ -193,8 +193,10 @@ fd(sink::FileSink) = fd(sink.s)
193
193
194
194
type Cmd
195
195
exec:: Executable
196
+ name:: String
196
197
pipes:: Dict{FileDes,PipeEnd}
197
198
sinks:: Dict{FileDes,FileSink}
199
+ closed_fds:: Vector{FileDes}
198
200
pipeline:: Set{Cmd}
199
201
pid:: Int32
200
202
status:: ProcessStatus
@@ -205,8 +207,10 @@ type Cmd
205
207
error (" Cmd: too few words to exec" )
206
208
end
207
209
this = new (exec,
210
+ " " ,
208
211
Dict {FileDes,PipeEnd} (),
209
212
Dict {FileDes,FileSink} (),
213
+ FileDes[],
210
214
Set {Cmd} (),
211
215
0 ,
212
216
ProcessNotRun (),
@@ -226,7 +230,9 @@ setsuccess(cmd::Cmd, f::Function) = (cmd.successful=f; cmd)
226
230
ignorestatus (cmd:: Cmd ) = setsuccess (cmd, ignore_success)
227
231
228
232
function show (io, cmd:: Cmd )
229
- if isa (cmd. exec,Vector{ByteString})
233
+ if cmd. name != " "
234
+ show (io, cmd. name)
235
+ elseif isa (cmd. exec,Vector{ByteString})
230
236
esc = shell_escape (cmd. exec... )
231
237
print (io, ' `' )
232
238
for c in esc
@@ -237,7 +243,7 @@ function show(io, cmd::Cmd)
237
243
end
238
244
print (io, ' `' )
239
245
else
240
- invoke (show, (Any,) , cmd. exec)
246
+ invoke (show, (Any, Any,), io , cmd. exec)
241
247
end
242
248
end
243
249
@@ -257,7 +263,7 @@ type Port
257
263
end
258
264
259
265
function fd (cmd:: Cmd , f:: FileDes )
260
- if ! has (cmd. pipes, f) && ! has (cmd. sinks, f)
266
+ if ! has (cmd. pipes, f) && ! has (cmd. sinks, f) && ! contains (cmd . closed_fds, f)
261
267
return Port (cmd,f)
262
268
end
263
269
error (" no " , f, " available in " , cmd)
@@ -266,12 +272,12 @@ end
266
272
function fd (cmds:: Set{Cmd} , f:: FileDes )
267
273
set = Set {Port} ()
268
274
for cmd in cmds
269
- if ! has (cmd. pipes, f) && ! has (cmd. sinks, f)
275
+ if ! has (cmd. pipes, f) && ! has (cmd. sinks, f) && ! contains (cmd . closed_fds, f)
270
276
add (set, fd (cmd,f))
271
277
end
272
278
end
273
279
if isempty (set)
274
- error (" no " , f, " available: " , cmds)
280
+ error (" no " , f, " available in " , cmds)
275
281
end
276
282
set
277
283
end
320
326
output (cmds:: Cmds ) = stdout (cmds) & stderr (cmds)
321
327
322
328
function connect (port:: Port , pend:: PipeEnd )
329
+ if contains (port. cmd. closed_fds, port. fd)
330
+ error (port. cmd, " port " , port. fd, " is closed" )
331
+ end
323
332
if ! has (port. cmd. pipes, port. fd) && ! has (port. cmd. sinks, port. fd)
324
333
port. cmd. pipes[port. fd] = pend
325
334
elseif has (port. cmd. pipes, port. fd) && port. cmd. pipes[port. fd] != pend
@@ -392,6 +401,7 @@ function redir(ports::Ports, sink::FileSink)
392
401
end
393
402
end
394
403
404
+ # redirect stdout
395
405
function (> )(src:: String , dst:: Cmds )
396
406
redir (stdin (dst), FileSink (src, " r" ))
397
407
return dst
426
436
427
437
(< )(dst:: IOStream , src:: Cmds ) = (> )(src, dst)
428
438
439
+ # redirect stderr
429
440
function (.> )(src:: Cmds , dst:: String )
430
441
redir (stderr (src), FileSink (dst, " w" ))
431
442
return src
@@ -446,15 +457,37 @@ end
446
457
447
458
(.< )(dst:: IOStream , src:: Cmds ) = (.> )(src, dst)
448
459
449
- # TODO : here-strings
450
- # function (>>>)(src::String, dst::Cmds)
451
- # redir(stdin(dst), FileSink(src, "r"))
452
- # return dst
453
- # end
454
- #
455
- # (<<<)(dst::Cmds, src::String) = (>>>)(src, dst)
460
+ # redirect both stdout and stderr
461
+ function (& > )(src:: Cmds , dst:: String )
462
+ redir (output (src), FileSink (dst, " w" ))
463
+ return src
464
+ end
465
+
466
+ function (& >> )(src:: Cmds , dst:: String )
467
+ redir (output (src), FileSink (dst, " a" ))
468
+ return src
469
+ end
456
470
471
+ (& < )(dst:: String , src:: Cmds ) = (& > )(src, dst)
472
+ (& << )(dst:: String , src:: Cmds ) = (& >> )(src, dst)
473
+
474
+ function (& > )(src:: Cmds , dst:: IOStream )
475
+ redir (output (src), FileSink (dst))
476
+ return src
477
+ end
478
+
479
+ (& < )(dst:: IOStream , src:: Cmds ) = (& > )(src, dst)
480
+
481
+ # here-strings:
482
+ function (>>> )(src:: String , dst:: Cmds )
483
+ hscmd = Cmd (()-> print (src))
484
+ push (hscmd. closed_fds, STDIN)
485
+ push (hscmd. closed_fds, STDERR)
486
+ hscmd. name = " here-string<" * src * " >"
487
+ return hscmd | dst
488
+ end
457
489
490
+ (<< < )(dst:: Cmds , src:: String ) = (>>> )(src, dst)
458
491
459
492
460
493
# spawn(cmd) starts all processes connected to cmd
@@ -508,7 +541,7 @@ function spawn(cmd::Cmd)
508
541
println (stderr_stream, " dup: " , strerror ())
509
542
exit (0x7f )
510
543
end
511
- bk_stderr_stream = fdio (bk_stderr_fd, true )
544
+ bk_stderr_stream = fdio (bk_stderr_fd)
512
545
513
546
# now actually do the fork and exec without writes
514
547
pid = fork ()
0 commit comments