Skip to content
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

attempted minimal fix for #12829 #12858

Merged
merged 2 commits into from
Sep 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,8 @@ function reset{T<:IO}(io::T)
end

ismarked(io::IO) = io.mark >= 0

# Generic IO stubs

lock(::IO) = nothing
unlock(::IO) = nothing
33 changes: 21 additions & 12 deletions base/stream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,13 @@ end
# note that uv_is_readable/writable work for any subtype of
# uv_stream_t, including uv_tty_t and uv_pipe_t
function isreadable(io::Union{PipeEndpoint,TTY})
nb_available(io) > 0 && return true
isopen(io) || return false
return ccall(:uv_is_readable, Cint, (Ptr{Void},), io.handle) != 0
end
function iswritable(io::Union{PipeEndpoint,TTY})
isopen(io) || return false
io.status == StatusClosing && return false
return ccall(:uv_is_writable, Cint, (Ptr{Void},), io.handle) != 0
end

Expand All @@ -233,11 +235,11 @@ show(io::IO,stream::TTY) = print(io,"TTY(",uv_status_string(stream),", ",
nb_available(stream.buffer)," bytes waiting)")

function println(io::AsyncStream, xs...)
lock(io.lock)
lock(io)
try
invoke(println, Tuple{IO, map(typeof,xs)...}, io, xs...)
finally
unlock(io.lock)
unlock(io)
end
end

Expand Down Expand Up @@ -312,7 +314,7 @@ end

function isopen(x::Union{AsyncStream,UVServer})
if x.status == StatusUninit || x.status == StatusInit
throw(ArgumentError("$T object not initialized"))
throw(ArgumentError("$x is not initialized"))
end
x.status != StatusClosed && x.status != StatusEOF
end
Expand Down Expand Up @@ -538,22 +540,27 @@ end

show(io::IO,stream::Pipe) = print(io,
"Pipe(",
uv_status_string(stream.in), ", ",
uv_status_string(stream.in), " => ",
uv_status_string(stream.out), ", ",
nb_available(stream), " bytes waiting)")
isreadable(io::AbstractPipe) = isreadable(io.out)
iswritable(io::AbstractPipe) = iswritable(io.in)
read{T<:AbstractPipe}(io::T, args...) = read(io.out, args...)
write(io::AbstractPipe, byte::UInt8) = write(io.in, byte)
write(io::AbstractPipe, bytes::Vector{UInt8}) = write(io.in, bytes)
write{T<:AbstractPipe}(io::T, args...) = write(io.in, args...)
write{S<:AbstractPipe,T}(io::S, a::Array{T}) = write(io.in, a)
write{S<:AbstractPipe}(io::S, a::Array) = write(io.in, a)
buffer_or_write(io::AbstractPipe, p::Ptr, n::Integer) = buffer_or_write(io.in, p, n)
readuntil{T<:AbstractPipe}(io::T, args...) = readuntil(io.out, args...)
buffer_writes(io::AbstractPipe, args...) = buffer_writes(io.in, args...)
flush(io::AbstractPipe) = flush(io.in)

read(io::AbstractPipe, byte::Type{UInt8}) = read(io.out, byte)
read!(io::AbstractPipe, bytes::Vector{UInt8}) = read!(io.out, bytes)
read{T<:AbstractPipe}(io::T, args...) = read(io.out, args...)
read!{T<:AbstractPipe}(io::T, args...) = read!(io.out, args...)
readuntil{T<:AbstractPipe}(io::T, args...) = readuntil(io.out, args...)
readbytes(io::AbstractPipe) = readbytes(io.out)
readavailable(io::AbstractPipe) = readavailable(io.out)
println{T<:AbstractPipe}(io::T, args...) = println(io.out, args...)
flush(io::AbstractPipe) = flush(io.in)
buffer_writes(io::AbstractPipe, args...) = buffer_writes(io.in, args...)

isreadable(io::AbstractPipe) = isreadable(io.out)
iswritable(io::AbstractPipe) = iswritable(io.in)
isopen(io::AbstractPipe) = isopen(io.in) || isopen(io.out)
close(io::AbstractPipe) = (close(io.in); close(io.out))
wait_readnb(io::AbstractPipe, nb::Int) = wait_readnb(io.out, nb)
Expand Down Expand Up @@ -1164,6 +1171,8 @@ type BufferStream <: AsyncStream
BufferStream() = new(PipeBuffer(), Condition(), Condition(), true, false, ReentrantLock())
end

lock(s::BufferStream) = lock(s.lock)
unlock(s::BufferStream) = unlock(s.unlock)
isopen(s::BufferStream) = s.is_open
close(s::BufferStream) = (s.is_open = false; notify(s.r_c; all=true); notify(s.close_c; all=true); nothing)

Expand Down
10 changes: 10 additions & 0 deletions test/spawn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,16 @@ let bad = "bad\0name"
@test_throws ArgumentError run(setenv(`echo hello`, "good"=>bad))
end

# issue #12829
let out = Pipe()
@test_throws ArgumentError write(out, "not open error")
open(`cat`, "w", out) do io
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note mostly to myself that we won't always have cat available in the windows binaries post-libgit2, but we can use busybox or something to keep this and similar tests passing

println(io, 1)
end
close(out.in)
@test readline(out) == "1\n"
end

# issue #8529
let fname = tempname()
open(fname, "w") do f
Expand Down