-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
os/spawn
works inconsistencly depending on what owns the pipe
#881
Comments
So, I thought to get around it by having a tertiary process called repipe that just reads from stdin and writes what it gets to stdout till it gets the string that signals EOF...
(var tmp (:read stdin :line)) #originally mispasted
(def designator "END\0\0\0\0\0\n")
(while (and tmp (not= (string tmp) designator))
(:write stdout tmp)
(flush)
(set tmp (:read stdin :line))) So, lets hook it up into # this is echo, works
(def p1 (os/spawn ["echo" "hello"] :p {:out :pipe}))
(def p2 (os/spawn ["cat"] :p {:in (p1 :out) :out :pipe}))
(:read (p2 :out) :all)
(:wait p2)
# this is repipe
(def janet (dyn :executable))
(def designator "END\0\0\0\0\0\n")
(def repipe (os/spawn [janet "repipe.janet"] :p {:in :pipe :out :pipe}))
(def p (os/spawn ["cat"] :p {:in (repipe :out) :out :pipe :err :pipe}))
(:write (repipe :in) "hello\n")
(:write (repipe :in) designator)
(:read (p :out) :all nil 1) # returns nil, the extra args after :all are to guard against hanging
(:read (p :err) :all nil 1) # result -> @"cat: stdin: Resource temporarily unavailable\n"
|
I'll also note that if you do something like the following: (def p2 (os/spawn ["cat"] :p {:in :pipe :out :pipe}))
(:write (p2 :in) "hello")
(:read (p2 :out) :all nil 1) #time out instead of hang Then later call |
you need to close a pipe after you pass it to a child. edit: my bad - the close was not in your example just in your comment. |
Pushed a fix on master in 4a40e57 - problem was that we were leaking file descriptors. |
The following program should now work:
You do need to close the input, though. |
The below works as expected, cat eventually exits (pipe ended).
When Janet (not another process) owns the pipe however we hang!
I've tried quite a few ways to perhaps tell cat it's
:in
pipe is done, such as(close (p :in))
both before/after reading and while we close it, we still ultimately hang at the read. If we change the read to a "read amount of bytes", we can get the content. But if you are uncertain how much content is to be generated, and call read in a loop, you hang! Regardless of how much reading you manage to do or not, you can never:wait
on the process, you'll hang, as the process will never end. It seems we simply don't have a way from within Janet to indicate to the child process that it won't be getting any more input and so it needs to do what it does when it doesn't have input, which is, exit, in the case of cat.The text was updated successfully, but these errors were encountered: