# A pass-through option for IOCapture

**URL:** <https://discourse.julialang.org/t/a-pass-through-option-for-iocapture/108642>\
**Category:** Internals & Design\
**Tags:** question, io\
**Created:** [January 10, 2024, 8:03pm UTC](https://discourse.julialang.org/t/a-pass-through-option-for-iocapture/108642 "2024-01-10T20:03:45Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [January 11, 2024, 5:16pm UTC](https://discourse.julialang.org/t/a-pass-through-option-for-iocapture/108642/7 "2024-01-11T17:16:47Z")

</div>

Yeah, `unsafe_write` is probably too unsafe, especially while I don’t understand every detail of asynchronous I/O. Also `copyuntil` doesn’t seem to work with `Pipe`/`PipeEndpoint` objects.

> It would be nice if there was an atomic `bytes_read = read!(pip, buffer, bufsize)` , but I don’t think there is.

Actually, looking at the internals, with `@edit read(pipe, bufsize)`, I think there is, and it’s [`readbytes!`](https://docs.julialang.org/en/v1/base/io-network/#Base.readbytes!).

So [this is my latest iteration](https://github.com/JuliaDocs/IOCapture.jl/pull/20/commits/5db37e9a84d090d118d5d42ef895946418193bdb), which seems to work and shouldn’t allocate anything inside the loop:

```julia
bufsize = 128
buffer = Vector{UInt8}(undef, bufsize)
buffer_redirect_task = @async begin
    while true
        nbytes = readbytes!(pipe, buffer, bufsize)
        data = view(buffer, 1:nbytes)
        write(output, data)
        write(default_stdout, data)
        isopen(pipe) || break
    end
end

```

Now, one more question about the exit condition from the loop (since I’m still pretty unsure about some of the details of asynchronous I/O): Is there any possibility that I might be missing data because the main task puts data into the pipe between the time I call `readbytes!(pipe, buffer, bufsize)` and the time I call `isopen(pipe)`? What about if I move the `isopen` check to the beginning of the loop (`while isopen(pipe)`)?

The other possibility I was considering was `(nbytes == 0) && break`, which also seems to work in my tests. But again: is there any possibility that the main task doesn’t write data to the pipe fast enough, so that there (temporarily) might not be anything for `readbytes!` to read, making me believe erroneously that the main task is done? **Update** : Let’s split this off to [Race condition reading from Pipe](https://discourse.julialang.org/t/race-condition-reading-from-pipe/108707). The MWE there demonstrated that `(nbytes == 0)` does _not_ work in general.

I saw `iolock_begin()` and `iolock_end()` in the internals of `Pipe`. Is that something I might need here to avoid race conditions?

---

_[View the full topic](https://discourse.julialang.org/t/a-pass-through-option-for-iocapture/108642)._
