Difference between read()/recv() and write()/send()

Hi,

I read that read(2) is equivalent to recv(2) with flags set to 0 and write(2) is equivalent to send(2) with flags set to 0. However, in man pages there are different possibles errno's returned by each pair of syscalls.

Are man pages incomplete or these syscalls can return different errno's?

Regards,
Michal Pietras
 
NewGuy said:
Technically they have similar functionality since the UNIX family of operating systems treat everything as a file. Though send(2)/recv(2) are usually used with sockets and write(2)/read(2) are typically used on local files.

Thanks, I realized that. Since both can have every similar implementation I am not sure if read(2) can set errno to ENOTCONN like recv(2) can. Can I be sure that man pages list every possible errno or some could omitted?

Many thanks,
Michael
 
pietrasm said:
Hi,

I read that read(2) is equivalent to recv(2) with flags set to 0 and write(2) is equivalent to send(2) with flags set to 0. However, in man pages there are different possibles errno's returned by each pair of syscalls.

Are man pages incomplete or these syscalls can return different errno's?

Regards,
Michal Pietras

You read wrong, recv(2) is a superset of read(2) that is socket mechanism aware (same goes for send/write syscalls). recv(2) will generally set same errnos as read(2) except the ones that do not apply for sockets (ENOTSOCK takes care of them) in addition of socket specific errnos. Makes sense, no?
 
manual page

expl said:
You read wrong, recv(2) is a superset of read(2) that is socket mechanism aware (same goes for send/write syscalls). recv(2) will generally set same errnos as read(2) except the ones that do not apply for sockets (ENOTSOCK takes care of them) in addition of socket specific errnos. Makes sense, no?

No, he didn't read it wrong, he was quoting the man page. It specifically says the two calls are equivalent. From the man page:
Code:
The only difference between send() and write(2) is the presence of flags.

To answer the original question, you can be fairly certain all of the errno values are listed in the manual page, these functions have been around a long time. But, again, the reason read() isn't likely to set ENOCONN is because read(2) is typically used for files and recv(2) for sockets. People don't generally worry about their files becoming disconnected. :)
 
NewGuy said:
No, he didn't read it wrong, he was quoting the man page. It specifically says the two calls are equivalent. From the man page:
Code:
The only difference between send() and write(2) is the presence of flags.

To answer the original question, you can be fairly certain all of the errno values are listed in the manual page, these functions have been around a long time. But, again, the reason read(2) isn't likely to set ENOCONN is because read(2) is typically used for files and recv(2) for sockets. People don't generally worry about their files becoming disconnected. :)
Great, thanks. So what read() will set when the error occurs that would cause recv(2) to set ENOTCONN?
 
expl said:
No, read(2) will set ENOTCONN. Returning 0 would not make sense.

Are you sure about that because it isn't stated in man pages that I can do so? I know for sure that read(2) returns zero when the remote side has closed connection in a normal way. Therefore, maybe it make sense that it returns zero in all situations in which ENOTCONN would arise?

Thanks.
 
pietrasm said:
I know for sure that read(2) returns zero when the remote side has closed connection in a normal way.

recv will also return 0 in this case

pietrasm said:
Are you sure about that because it isn't stated in man pages that I can do so?

Code:
   char buffer;
   int sockfd = socket(AF_INET, SOCK_STREAM, 0);
   int rv = read(sockfd, &buffer, sizeof(buffer));
   
   if (rv == -1 && errno == ENOTCONN) {
       printf("read() set ENOTCONN\n");
   }

Code:
$ ./out
read() set ENOTCONN
 
expl said:
recv will also return 0 in this case



Code:
   char buffer;
   int sockfd = socket(AF_INET, SOCK_STREAM, 0);
   int rv = read(sockfd, &buffer, sizeof(buffer));
   
   if (rv == -1 && errno == ENOTCONN) {
       printf("read() set ENOTCONN\n");
   }

Code:
$ ./out
read() set ENOTCONN

Thanks, question solved. However, it's rather nasty that man pages are missing some possible errno's. Are there any other errno's that are not listed but could be returned by any of mentioned syscalls?

Many thanks.
 
Back
Top