mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
kernel/pipe: trigger EPOLLERR on a write end if all readers has been closed
Fixes #10066 PiperOrigin-RevId: 612838688
This commit is contained in:
@@ -178,6 +178,9 @@ func (fd *VFSPipeFD) Release(context.Context) {
|
||||
if fd.vfsfd.IsReadable() {
|
||||
fd.pipe.rClose()
|
||||
event |= waiter.WritableEvents
|
||||
if !fd.pipe.HasReaders() {
|
||||
event |= waiter.EventErr
|
||||
}
|
||||
}
|
||||
if fd.vfsfd.IsWritable() {
|
||||
fd.pipe.wClose()
|
||||
|
||||
@@ -594,6 +594,29 @@ TEST(EpollTest, PipeReaderHupAfterWriterClosed) {
|
||||
EXPECT_EQ(result[0].data.u64, kMagicConstant);
|
||||
}
|
||||
|
||||
TEST(EpollTest, PipeWriterErrAfterReaderClosed) {
|
||||
auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
|
||||
int pipefds[2];
|
||||
ASSERT_THAT(pipe(pipefds), SyscallSucceeds());
|
||||
FileDescriptor rfd(pipefds[0]);
|
||||
FileDescriptor wfd(pipefds[1]);
|
||||
|
||||
ASSERT_NO_ERRNO(
|
||||
RegisterEpollFD(epollfd.get(), wfd.get(), EPOLLERR, kMagicConstant));
|
||||
struct epoll_event result[kFDsPerEpoll];
|
||||
// Initially, wfd should not generate any events of interest.
|
||||
ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
|
||||
SyscallSucceedsWithValue(0));
|
||||
// Close the read end of the pipe.
|
||||
rfd.reset();
|
||||
// wfd should now generate EPOLLERR, which EPOLL_CTL_ADD unconditionally adds
|
||||
// to the set of events of interest.
|
||||
ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
|
||||
SyscallSucceedsWithValue(1));
|
||||
EXPECT_EQ(result[0].events, EPOLLERR);
|
||||
EXPECT_EQ(result[0].data.u64, kMagicConstant);
|
||||
}
|
||||
|
||||
TEST(EpollTest, DoubleLayerEpoll) {
|
||||
int pipefds[2];
|
||||
ASSERT_THAT(pipe2(pipefds, O_NONBLOCK), SyscallSucceeds());
|
||||
|
||||
Reference in New Issue
Block a user