Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

verify if socket is writable

1,461 views
Skip to first unread message

cerr

unread,
Jan 7, 2010, 5:21:44 PM1/7/10
to
Hi There,

I SIGPIPE-out when I try to send data to a socket that's been closed
on the other side. I understand that I have to check with select() if
my socket is still active but i don't quite understand how I can do
this.
My code:

if (log_sock>-1) {
sndlen=strlen(res);
syslog(LOG_ERR, "_run_logger(): got strlen(res):%d, log_sock:
%d",sndlen, log_sock);
reclen=send(log_sock, res, sndlen, 0);
syslog(LOG_ERR, "_run_logger(): sent \'%s\"",res);

How do I need to use the select() statement before the if to verify if
my socket is still open?
Thank you!
Ron

Moi

unread,
Jan 7, 2010, 5:56:05 PM1/7/10
to

Basically, your socket is open until you close it.
If the other end has close()ed the connection then:

-> your write() will return -1 with errno set properly (EPIPE).
-> your read() will return 0 on EOF (or -1 with errno set properly)

Select() and poll() will return a socket as readable or writable
if it is safe for you to call read() or write() without blocking.

So you will in any case need to set a signal handler for SIGPIPE to SIGIGN
to handle the EPIPE case (the default handler is ABRT)

(there are more details, causing you to need setting the sockets to
non-blockable, but DS will hanle that case ;-)

HTH,
AvK

cerr

unread,
Jan 7, 2010, 6:19:54 PM1/7/10
to
On Jan 7, 2:56 pm, Moi <r...@invalid.address.org> wrote:
> On Thu, 07 Jan 2010 14:21:44 -0800, cerr wrote:
> > Hi There,
>
> > I SIGPIPE-out when I try to send data to a socket that's been closed on
> > the other side. I understand that I have to check with select() if my
> > socket is still active but i don't quite understand how I can do this.
> > My code:
>
> >       if (log_sock>-1) {
> >    sndlen=strlen(res);
> >    syslog(LOG_ERR, "_run_logger(): got strlen(res):%d, log_sock:
> > %d",sndlen, log_sock);
> >    reclen=send(log_sock, res, sndlen, 0); syslog(LOG_ERR, "_run_logger():
> >    sent \'%s\"",res);
>
> > How do I need to use the select() statement before the if to verify if
> > my socket is still open?
>
> Basically, your socket is open until you close it.
> If the other end has close()ed the connection then:
>
> -> your write() will return -1 with errno set properly (EPIPE).
> -> your read() will return 0 on EOF (or -1 with errno set properly)

So, should I be using write() instead of send? send() apparently ends
up in a SIGPIPE exception...

> Select() and poll() will return a socket as readable or writable
> if it is safe for you to call read() or write() without blocking.

exactly, I should be able to read with select if my socket is
writable, right?

> So you will in any case need to set a signal handler for SIGPIPE to SIGIGN
> to handle the EPIPE case (the default handler is ABRT)

set a signal handler? With setjmp()? Hm...

cerr

unread,
Jan 7, 2010, 6:29:22 PM1/7/10
to

Okay,

I tried it like this
FD_ZERO(&sendset);
FD_SET(log_sock, &sendset);
recv_tv.tv_sec = 0;
recv_tv.tv_usec = 10000;//10ms
select(log_sock+1, NULL, &sendset, NULL, &send_tv);
if (log_sock>-1 && FD_ISSET(log_sock, &sendset)) {


sndlen=strlen(res);
syslog(LOG_ERR, "_run_logger(): got strlen(res):%d, log_sock:
%d",sndlen, log_sock);
reclen=send(log_sock, res, sndlen, 0);

But it doesn't seem to work. I always get the "got strlen" message the
last and nothing past it and my debugger tells me:
Program received signal SIGPIPE, Broken pipe.

Program terminated with signal SIGPIPE, Broken pipe.
The program no longer exists.
(gdb)
:(( What am I doing wrong there? :o

Thanks!
Ron

Moi

unread,
Jan 7, 2010, 6:37:52 PM1/7/10
to
On Thu, 07 Jan 2010 15:19:54 -0800, cerr wrote:

> On Jan 7, 2:56 pm, Moi <r...@invalid.address.org> wrote:
>> On Thu, 07 Jan 2010 14:21:44 -0800, cerr wrote:
>> > Hi There,
>>
>> > I SIGPIPE-out when I try to send data to a socket that's been closed
>> > on the other side. I understand that I have to check with select() if
>> > my socket is still active but i don't quite understand how I can do
>> > this. My code:
>>
>> >       if (log_sock>-1) {
>> >    sndlen=strlen(res);
>> >    syslog(LOG_ERR, "_run_logger(): got strlen(res):%d, log_sock:
>> > %d",sndlen, log_sock);
>> >    reclen=send(log_sock, res, sndlen, 0); syslog(LOG_ERR,
>> >    "_run_logger(): sent \'%s\"",res);
>>
>> > How do I need to use the select() statement before the if to verify
>> > if my socket is still open?
>>
>> Basically, your socket is open until you close it. If the other end has
>> close()ed the connection then:
>>
>> -> your write() will return -1 with errno set properly (EPIPE). -> your
>> read() will return 0 on EOF (or -1 with errno set properly)
>
> So, should I be using write() instead of send? send() apparently ends up
> in a SIGPIPE exception...

You could, but there is no difference in return and errno.
[in your case, you don't _need_ sendto(), write() would be good enough]


>> Select() and poll() will return a socket as readable or writable if it
>> is safe for you to call read() or write() without blocking.
>
> exactly, I should be able to read with select if my socket is writable,
> right?

Learn how to read.
You can call read() or write() , and they won't block.
(but instead return immediately with 0 or -1)

>> So you will in any case need to set a signal handler for SIGPIPE to
>> SIGIGN to handle the EPIPE case (the default handler is ABRT)
>
> set a signal handler? With setjmp()? Hm...

No. signal() or sigaction()
man 2 signal

HTH,
AvK

Barry Margolin

unread,
Jan 7, 2010, 10:50:26 PM1/7/10
to
In article
<4ff3b6bd-873f-4e86...@b2g2000yqi.googlegroups.com>,
cerr <ron.e...@gmail.com> wrote:

You can't.

The problem is that TCP doesn't provide a way for the receiver to tell
you that it doesn't want any more data. The only way to find out is to
send data; if it didn't want any more, it responds with a RST packet.
This causes you to get a SIGPIPE signal. If you're ignoring this
signal, you'll get an EPIPE error on the *next* operation on the socket.

You should design your application protocol so that the other end tells
you when it's closing the connection. And in case the other end
terminates abnormally, you should just establish a handler for SIGPIPE.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***

David Schwartz

unread,
Jan 7, 2010, 11:05:07 PM1/7/10
to
On Jan 7, 2:21 pm, cerr <ron.egg...@gmail.com> wrote:

> I SIGPIPE-out when I try to send data to a socket that's been closed
> on the other side.

What do you want to happen in this case?

> I understand that I have to check with select() if
> my socket is still active but i don't quite understand how I can do
> this.

That's wrong on so many levels, but the most obvious is this: suppose
there was some function that could tell you if the socket was okay or
not. How would that help you? Just because it was okay when you asked
doesn't mean it will still be okay when you try to use it.

> How do I need to use the select() statement before the if to verify if
> my socket is still open?

That would be really silly. That would mean two system calls where one
would do 99.9999% of the time. Ignore SIGPIPE or handle it, depending
on what you want to do.

DS

David Schwartz

unread,
Jan 7, 2010, 11:06:08 PM1/7/10
to
On Jan 7, 2:56 pm, Moi <r...@invalid.address.org> wrote:

> Select() and poll() will return a socket as readable or writable
> if it is safe for you to call read() or write() without blocking.

It's always safe to call 'read' or 'write' without blocking.

> So you will in any case need to set a signal handler for SIGPIPE to SIGIGN
> to handle the EPIPE case (the default handler is ABRT)

Exactly.

> (there are more details, causing you to need setting the sockets to
> non-blockable,  but DS will hanle that case ;-)

If you don't want to block, you have to set the sockets non-blocking.
If you want to block if an operation cannot be completed (or fail)
immediately, then don't set them non-blocking. We can't tell which the
OP wants.

DS

Valentin Nechayev

unread,
Jan 8, 2010, 5:29:44 AM1/8/10
to
>>> David Schwartz wrote:

>> (there are more details, causing you to need setting the sockets to

>> non-blockable, О©╫but DS will hanle that case ;-)
DS> If you don't want to block, you have to set the sockets non-blocking.

This could have side effects of appearing of non-blocking mode for
other descriptor (possibly in other process), as soon as F_SETFL flags
affect "ofile", not descriptor. When this is important, I prefer to
rely on select/poll notifications.

I would like to see non-blocking mark on _operation_, not _object_.
This is already true for send*/recv* in some OSes as Linux, but can be
easily spread to other kinds of objects. There is no essential reasons
except historic legacy to allow send() and recv() only for sockets.


--netch--

cerr

unread,
Jan 8, 2010, 5:56:09 PM1/8/10
to

Okay, I understand.

> >> So you will in any case need to set a signal handler for SIGPIPE to
> >> SIGIGN to handle the EPIPE case (the default handler is ABRT)
>
> > set a signal handler? With setjmp()? Hm...
>
> No. signal() or sigaction()
> man 2 signal

Yes,
signal (SIGPIPE,SIG_IGN);
this has done the trick, thanks!

cerr

unread,
Jan 8, 2010, 5:58:49 PM1/8/10
to

Yep,
signal (SIGPIPE,SIG_IGN);
did the trick for me. I just read how many bytes have been sent and
proceed upon that the way i want....

0 new messages