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



## pietrasm (Feb 7, 2013)

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 (Feb 7, 2013)

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.


----------



## pietrasm (Feb 7, 2013)

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


----------



## expl (Feb 7, 2013)

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.
> 
> ...



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?


----------



## NewGuy (Feb 8, 2013)

*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:

```
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.


----------



## pietrasm (Feb 8, 2013)

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:
> 
> ```
> The only difference between send() and write(2) is the presence of flags.
> ...


Great, thanks. So what read() will set when the error occurs that would cause recv(2) to set ENOTCONN?


----------



## pietrasm (Feb 8, 2013)

pietrasm said:
			
		

> Great, thanks. So what read(2) will set when the error occurs that would cause recv(2) to set ENOTCONN?



I've got an idea. I think that read(2) returns zero in situations in which recv(2) would return ENOTCONN. What do you guys think?

Thanks.


----------



## expl (Feb 8, 2013)

pietrasm said:
			
		

> I've got an idea. I think that read(2) returns zero in situations in which recv(2) would return ENOTCONN. What do you guys think?
> 
> Thanks.



No, read(2) will set ENOTCONN. Returning 0 would not make sense.


----------



## pietrasm (Feb 8, 2013)

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.


----------



## expl (Feb 8, 2013)

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?




```
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");
   }
```


```
$ ./out
read() set ENOTCONN
```


----------



## pietrasm (Feb 8, 2013)

expl said:
			
		

> recv will also return 0 in this case
> 
> 
> 
> ...



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.


----------

