1. More Specific Broken Pipe Error

Ok. I have been at it all day and have narrowed down the possibilities. Perhaps
someone out
there can read this little example and may know why I am getting the Broken Pipe
error.

The following routine works flawlessly with connected sockets. The pipe crash
happens when
someone severs a link to the server by simply shutting off their client (a
generic MUD client)
and this routine tries to send information. However, the crash does not happen
in every
instance of this.

Most of the time poll () is able to pick up the disconnect and I automatically
shut them down.
In every instance, the person who is connected to the socket simply shut down
without entering
any information. Therefore, I think I can assume that it is not a problem of
buffered
information still waiting to be read because they reported little to no lag
before
disconnecting.  The code is as follows:

       game_output_buffer = allocate(length(text))
        poke(game_output_buffer, text)
        xxx = c_func(write, {n, game_output_buffer, length(text)})
        free(game_output_buffer)

        n is the file descriptor
        game_output_buffer and xxx are atoms

I have yet to record xxx being -1 and in all the man pages it tells of write
returning a SIGTRM
on error.  I hope this helps to describe the problem I am having a bit better.
If anymore is
needed please let me know and I will provide it. Again, I will appreciate any
feedback on this
as I have searched fruitlessly for the past 14 or so hours for the problem
and/or it's
solution, but so far with no success on either.

Cense wrote:


> Hi again Kayhlan,

> The "broken pipe error" just means that the socket connection has been broken.

> The communication between two sockets is done through a pipe and when that
> pipe

> breaks, so does the connection.
>
> This sounds rather similar to a problem i was having quite some time ago with
> a perl script that used linux sockets. I dont know for sure about your problem
> but i *think* that my problem (of similar nature) could have been due to the
> fact that i was sending data before the other side of my connection was
> replying to previous data. I dont know this for sure but now that you have
> brought this up, i will investigate again. Now i dont know why this would
> cause a pipe break because i was pretty sure TCP protected against this in
> some
> ways but then again, im no TCP/IP expert or anything of the sorts.
>
> Im going to try and find a solution now myself so then maybe i might be able
> to
> be of a little more assistance to you and my ex-perlscript.
>
> Dont give up :)
>
> --
> evil, corruption and bad taste
> ^[cense]

new topic     » topic index » view message » categorize

2. Re: More Specific Broken Pipe Error

On Tue, 14 Nov 2000, Kayhlan wrote:

heya again,

>> Ok. I have been at it all day and have narrowed down the possibilities.
>> Perhaps someone out there can read this little example and may know why I
>> am getting the Broken Pipe error.

>> The following routine works flawlessly with connected sockets. The pipe crash
>> happens when
>> someone severs a link to the server by simply shutting off their client (a
>> generic MUD client)
>> and this routine tries to send information. However, the crash does not
>> happen in every
>> instance of this.

If i understand what you are trying to say is that when someone closes their
client by quiting it, then the error has a possibility of occuring.

>> Most of the time poll () is able to pick up the disconnect and I
>> automatically shut them down.
>> In every instance, the person who is connected to the socket simply shut down
>> without entering
>> any information. Therefore, I think I can assume that it is not a problem of
>> buffered
>> information still waiting to be read because they reported little to no lag
>> before
>> disconnecting.  The code is as follows:
>> 
>>        game_output_buffer = allocate(length(text))
>>         poke(game_output_buffer, text)
>>         xxx = c_func(write, {n, game_output_buffer, length(text)})
>>         free(game_output_buffer)
>> 
>>         n is the file descriptor
>>         game_output_buffer and xxx are atoms
>> 
>> I have yet to record xxx being -1 and in all the man pages it tells of write
>> returning a SIGTRM
>> on error.  I hope this helps to describe the problem I am having a bit
>> better. If anymore is
>> needed please let me know and I will provide it. Again, I will appreciate any
>> feedback on this
>> as I have searched fruitlessly for the past 14 or so hours for the problem
>> and/or it's
>> solution, but so far with no success on either.

I would have figured the same as you in the situation, that write( ) would have
returned an error code if it could not send data. Usually as described by the
man file, if a file/socket descriptor was invalid -1 would be returned and
errno set properly. But obviously this is not the case.

Where in the man page did you see anything about SIGTERM? I could not see it.
If your process getting the SIGTERM signal would explain everything because
SIGTERM is the TERMINATION signal. When a process gets this signal is *usually*
terminates hence the "broken pipe error"

A solution might be to "catch" the shutting down of the client and properly
disconnect the socket before any damage is done.

On another note, I really do think that you should be using send( ) and recv( )
instead of write( ) and read( ). send and recv were designed for sockets
specifically while read and write were not. This is my only suggestion as i
have no other thoughts on solutions at this moment.

Hope some of my bullsh*t might help you.

-- 
evil, corruption and bad taste
^[cense]

new topic     » goto parent     » topic index » view message » categorize

3. Re: More Specific Broken Pipe Error

Being an avid Euphoria user, but admittedly a very novice C user I actually have
more questions about
your questions than I do answers.

First, man 2 write when talking about error messages lists EPIPE "fd is
connected to a pipe or socket
whose reading end is closed. When this happens, the writing process will receive
a SIGPIPE signal: if
it catches, blocks or ignores this error, EPIPE is returned."

Questions about this:

You say errno would be set properly, but how is this passed into Euphoria?
Do I have to make a global integer in Euphoria or is this just not possible?

As I said, I have never recorded xxx equal to anything but the length of the
data sent.
(Possibly because the time it would return -1 it terminates with the broken
pipe)

I do use recv() instead of read, however I cannot make Euphoria pass strings to
C so I have been
unable to get send() to work properly.
And as far as "catching" the signal, other than poll() (which is not catching
the disconnect all the
time) I have no clue how to go about detecting the disconnection another way. Is
there some function
that would test a socket to see if it is still active?

thanks very much for your help so far,

Kayhlan

cense wrote:

> I would have figured the same as you in the situation, that write( ) would
> have
> returned an error code if it could not send data. Usually as described by the
> man file, if a file/socket descriptor was invalid -1 would be returned and
> errno set properly. But obviously this is not the case.
>
> Where in the man page did you see anything about SIGTERM? I could not see it.
> If your process getting the SIGTERM signal would explain everything because
> SIGTERM is the TERMINATION signal. When a process gets this signal is
> *usually*
> terminates hence the "broken pipe error"
>
> A solution might be to "catch" the shutting down of the client and properly
> disconnect the socket before any damage is done.
>
> On another note, I really do think that you should be using send( ) and recv(
> )
> instead of write( ) and read( ). send and recv were designed for sockets
> specifically while read and write were not. This is my only suggestion as i
> have no other thoughts on solutions at this moment.
>
> Hope some of my bullsh*t might help you.
>
> --
> evil, corruption and bad taste
> ^[cense]

new topic     » goto parent     » topic index » view message » categorize

4. Re: More Specific Broken Pipe Error

On Tue, 14 Nov 2000, Kayhlan wrote:
>> Being an avid Euphoria user, but admittedly a very novice C user I actually
>> have more questions about your questions than I do answers.

Im not C expert myself, infact i was just in your position a little while ago.
 
>> First, man 2 write when talking about error messages lists EPIPE "fd is
>> connected to a pipe or socket
>> whose reading end is closed. When this happens, the writing process will
>> receive a SIGPIPE signal: if
>> it catches, blocks or ignores this error, EPIPE is returned."

hehe, now i see that part of the man page, stupid me

>> Questions about this:
>> 
>> You say errno would be set properly, but how is this passed into Euphoria?
>> Do I have to make a global integer in Euphoria or is this just not possible?

Now again, i dont know a whole lot about C like others on this list (Bernie
Ryan for sure knows his C programming) but i know that errno is a variable
declared as "extern int errno" in the include <errno.h>

As far as i know there is no way to access this variable from Euphoria other
than perhaps peeking into the memory where errno is allocated but i do not know
how to do this myself. Give Bernie Ryan or other more highly qualified C guys a
shout about that question

>> As I said, I have never recorded xxx equal to anything but the length of the
>> data sent.
>> (Possibly because the time it would return -1 it terminates with the broken
>> pipe)

I agree with this theory of why you are never getting -1

>> I do use recv() instead of read, however I cannot make Euphoria pass strings
>> to C so I have been
>> unable to get send() to work properly.

to get Euphoria to pass a string to a C routine, you need to put your sequence
(the euphoria string) into memory ala C style. This can be accomplished using a
simple function like this:

function alloc_string( sequence str )
  atom ptr
  
  ptr = allocate( length( str ) + 1 )
  poke( ptr, str & 0 )

  return ptr
end function

A C compliant pointer is returned by alloc_string which can be used in wherever
a "char *" is needed. In your case, the second argument to send( )

send can also accept pointers to any type of data so if you are not sending
strings, it will work exactly the same.

>> And as far as "catching" the signal, other than poll() (which is not catching
>> the disconnect all the
>> time) I have no clue how to go about detecting the disconnection another way.
>> Is there some function
>> that would test a socket to see if it is still active?

To "catch" a signal sent to a process, you have to install a new signal handler
by using the function "signal( )". the man 2 signal page has some info on
signal but its still kinda confusing so i can give you a little extra help on
that. I have a wrapper for "signal( )" that i *think* works but i have not
tested it, it goes as follows:

function signal( int signum, int routine )
  atom sig_handler_ptr, ret_ptr
  
  sig_handler_ptr = call_back( routine )
  ret_ptr = c_func( signal_, { signum, sig_handler_ptr } )
  
  if ret_ptr = sig_handler_ptr then
    return 0
  else
    return 1
  end if  
end function

Now for my documentation. signal( ) above takes two arguments, the first is the
signal number you want "catch" (in your case SIGPIPE or 13). The second
argument is the routine_id of the function that you will be using to handle the
signal when it is recived. You can get the routine_id of any function in
euphoria by using "routine_id( s )" check the Euphoria reference manual for
details.

If you need some more help with signal or if you dont understand my
rambling, mail back once more and i will try to be a little more clear and
in-depth.

>> thanks very much for your help so far,

No problem, this is what the mailing list is for!

>> Kayhlan

-- 
evil, corruption and bad taste
^[cense]

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu