Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prototype of recv()

Tags:

c

posix

sockets

Typing man recv() on my system, I get:

 ssize_t
 recv(int socket, void *buffer, size_t length, int flags);

 …

RETURN VALUES
 These calls return the number of bytes received, or -1 if an error occurred.

Note that length is of unsigned type size_t and the function's result is a signed ssize_t.

If passed a value larger than SSIZE_MAX for length, how theoretical is the situation where recv() would fill the memory pointed by buffer and return a negative value other than -1 ? Are there types of sockets that allow very long messages (Unix domain?)? What about MSG_WAITALL?

like image 964
Pascal Cuoq Avatar asked Jun 20 '13 19:06

Pascal Cuoq


1 Answers

Here's what the Posix 2008 rationale has to say about ssize_t (extracted from B.2.12 Data Types):

ssize_t
This is intended to be a signed analog of size_t. The wording is such that an implementation may either choose to use a longer type or simply to use the signed version of the type that underlies size_t. All functions that return ssize_t (read() and write()) describe as "implementation-defined" the result of an input exceeding {SSIZE_MAX}.

Actually, that's not quite true, since the socket functions which return ssize_t, including recv, don't mention anything about input exceeding SSIZE_MAX. So I'm taking that as a statement of intention, implying that the missing wording in recv is an error which might be corrected some day.

In short, if you want to write portable code, you need to ensure that your I/O segments do not exceed SSIZE_MAX. Furthermore, SSIZE_MAX may be as small as 32767. So portable code shouldn't assume that it might be greater.

However, not everyone cares that much about portability. You might know something about the implementations your code runs on. Posix continues:

It is recognized that some implementations might have ints that are smaller than size_t. A conforming application would be constrained not to perform I/O in pieces larger than {SSIZE_MAX}, but a conforming application using extensions would be able to use the full range if the implementation provided an extended range, while still having a single type-compatible interface.

Posix does guarantee that the only values returned by recv are -1, 0 or the number of bytes received. A conforming implementation, according to the above wording, could map values greater than SSIZE_MAX but less than or equal to 2*SSIZE_MAX onto the negative integers other than -1. (How this might be accomplished is left as an exercise for the interested reader :) ). Linux does not, as far as I know, document any such extension, though.

like image 185
rici Avatar answered Oct 20 '22 05:10

rici