I have client and server connected.
client write and read from csock.
server write and read from ssock
suppose the server does :
....
close(ssock); //send FIN to client
othertask();
....
READ ERROR
if after the server close() the client does:
...
read(csock,...);
...
read(csock,...);
...
close(csock,...);
...
read(csock,...);
...
first read return 0 (read FIN)
second read also return 0.
third read return -1 with errno set to EBADF.
QUESTION 1:
Indeed if after the server close() the client does:
....
write(csock, "hello", 6); //server send RST
...
read(csock,...);
...
write(csock, ...);
first write return 6 without signaling nothing.
read return:
0 if the client read before the RST arrives.
-1 with errno set to ECONNRESET otherwise.
second write comports the SIGPIPE signal.
if it is ignored write return -1 and errno=EPIPE, otherwise it
comports the client termination.
is ok?
IS THE SITUATION THE SAME WHEN THE SERVER CRASH BEFORE THE CLIENT'S
FIRST WRITE?
QUESTION 2:
when read fails with errno=ENOTCONN?
QUESTION 3:
In general if I don't set the timeout option, is possible that a
read() fails with errno=ETIMEDOUT?
Here are some examples of when these errors occur:
write(..) on a socket that has been closed at the other end will cause a SIGPIPE.
read on a remotely closed socket will return 0 (EOF) or ECONNRESET in some cases, see the last part of this reply.
read(..) or write(..) on a socket that was never connected will return ENOTCONN.
read(..) or write(..) on a locally closed socket will return EBADF
I'm referring to [comp.unix.programmer] Unix-socket-faq for network programming when answering the question regarding read returning 0 or ECONNRESET:
"If the peer calls close() or exits, without having messed with
SO_LINGER, then our calls to read() should return 0. It is less clear
what happens to write() calls in this case; I would expect EPIPE, not
on the next call, but the one after.
If the peer reboots, or sets l_onoff = 1, l_linger = 0 and then
closes, then we should get ECONNRESET (eventually) from read(), or
EPIPE from write()."
close() closes the file descriptor hence your EBADF for the following read.
As a suggestion, once you use close, actually or mentally put -1 into the file descriptor variable. This also acts as a massive hint that the file descriptor is no longer valid.