diff --git a/kernel/include/sortix/kernel/pipe.h b/kernel/include/sortix/kernel/pipe.h index f6734c1a..0de3aa07 100644 --- a/kernel/include/sortix/kernel/pipe.h +++ b/kernel/include/sortix/kernel/pipe.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. This file is part of Sortix. @@ -41,6 +41,10 @@ public: ~PipeEndpoint(); bool Connect(PipeEndpoint* destination); void Disconnect(); + bool GetSIGPIPEDelivery(); + bool SetSIGPIPEDelivery(bool deliver_sigpipe); + size_t Size(); + bool Resize(size_t new_size); ssize_t read(ioctx_t* ctx, uint8_t* buf, size_t count); ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count); int poll(ioctx_t* ctx, PollNode* node); diff --git a/kernel/net/fs.cpp b/kernel/net/fs.cpp index 592a28d7..aeb0d6b9 100644 --- a/kernel/net/fs.cpp +++ b/kernel/net/fs.cpp @@ -418,6 +418,9 @@ Ref Manager::Accept(StreamSocket* socket, ioctx_t* ctx, return Ref(NULL); } + client->outgoing.SetSIGPIPEDelivery(false); + server->outgoing.SetSIGPIPEDelivery(false); + client->is_connected = true; server->is_connected = true; diff --git a/kernel/pipe.cpp b/kernel/pipe.cpp index fc7eb6ef..4a499980 100644 --- a/kernel/pipe.cpp +++ b/kernel/pipe.cpp @@ -60,6 +60,8 @@ public: void CloseReading(); void CloseWriting(); void PerhapsShutdown(); + bool GetSIGPIPEDelivery(); + void SetSIGPIPEDelivery(bool deliver_sigpipe); ssize_t read(ioctx_t* ctx, uint8_t* buf, size_t count); ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count); int read_poll(ioctx_t* ctx, PollNode* node); @@ -81,6 +83,7 @@ private: size_t buffersize; bool anyreading; bool anywriting; + bool is_sigpipe_enabled; }; @@ -93,6 +96,7 @@ PipeChannel::PipeChannel(uint8_t* buffer, size_t buffersize) this->buffersize = buffersize; bufferoffset = bufferused = 0; anyreading = anywriting = true; + is_sigpipe_enabled = true; } PipeChannel::~PipeChannel() @@ -170,9 +174,9 @@ ssize_t PipeChannel::write(ioctx_t* ctx, const uint8_t* buf, size_t count) } if ( !anyreading ) { - CurrentThread()->DeliverSignal(SIGPIPE); - errno = EPIPE; - return -1; + if ( is_sigpipe_enabled ) + CurrentThread()->DeliverSignal(SIGPIPE); + return errno = EPIPE, -1; } if ( buffersize - bufferused < count ) { count = buffersize - bufferused; } size_t writeoffset = (bufferoffset + bufferused) % buffersize; @@ -228,6 +232,18 @@ int PipeChannel::write_poll(ioctx_t* /*ctx*/, PollNode* node) return errno = EAGAIN, -1; } +bool PipeChannel::GetSIGPIPEDelivery() +{ + ScopedLockSignal lock(&pipelock); + return is_sigpipe_enabled; +} + +void PipeChannel::SetSIGPIPEDelivery(bool deliver_sigpipe) +{ + ScopedLockSignal lock(&pipelock); + is_sigpipe_enabled = deliver_sigpipe; +} + PipeEndpoint::PipeEndpoint() { channel = NULL; @@ -286,6 +302,20 @@ int PipeEndpoint::poll(ioctx_t* ctx, PollNode* node) : channel->write_poll(ctx, node); } +bool PipeEndpoint::GetSIGPIPEDelivery() +{ + return !reading ? channel->GetSIGPIPEDelivery() : false; +} + +bool PipeEndpoint::SetSIGPIPEDelivery(bool deliver_sigpipe) +{ + if ( !reading ) + channel->SetSIGPIPEDelivery(deliver_sigpipe); + else if ( reading && deliver_sigpipe != false ) + return errno = EINVAL, false; + return true; +} + class PipeNode : public AbstractInode { public: