1. More Specific Broken Pipe Error
- Posted by Kayhlan <kayhlan at EARTHLINK.NET> Nov 14, 2000
- 427 views
- Last edited Nov 15, 2000
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]
2. Re: More Specific Broken Pipe Error
- Posted by cense <cense at MAIL.RU> Nov 14, 2000
- 432 views
- Last edited Nov 15, 2000
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]
3. Re: More Specific Broken Pipe Error
- Posted by Kayhlan <kayhlan at EARTHLINK.NET> Nov 15, 2000
- 441 views
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]
4. Re: More Specific Broken Pipe Error
- Posted by cense <cense at MAIL.RU> Nov 15, 2000
- 422 views
- Last edited Nov 16, 2000
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]