Justification of system calls allowing size_t request, but the result is only ssize_t?

Consider:

ssize_t write(int fd, const void *buf, size_t count); 

The result must be signed to account for -1 on error, etc., and thus ssize_t. But why, then, does an unsigned quantity (twice as many) be required for the query when the result of the query more than ssize_t is undefined?

Is there any significant optimization in the kernel due to the fact that you do not check the signature of the count parameter? Or something else?

+8
c linux unix
source share
4 answers

According to the documentation for ssize_t write(int fildes, const void *buf, size_t nbyte)

If nbyte is greater than {SSIZE_MAX}, the result is determined by the implementation.

Thus, each particular implementation can handle this situation differently. I would not be surprised if some implementations simply install EFBIG .

Regarding the logic, maybe size_t is just the best type to represent the buffer size semantically? He argues that this argument is a non-negative size, and nothing more.

+6
source share

It seems to me that this is good, since size_t is the type of value returned by the sizeof operator, this allows such calls:

 char buffer[1 << 20]; ssize_t wrote; wrote = write(fd, buffer, sizeof buffer); 

If the function took the signed version, a throw is required. In addition, as others noted, semantically similar functions cannot take a negative value, so it makes little sense to accept them.

+5
source share

By changing the unsigned parameter, it eliminates the need to test the function for non-essential negative requests.

+2
source share

write can only be written from one continuous array of unsigned char , which cannot be greater than PTRDIFF_MAX , which (on all real POSIX systems, and perhaps this is also required by POSIX ...?), equal to SIZE_MAX/2 . Thus, passing a value that will be negative if it is interpreted as a signed value is a programming error for starters - the transferred size is not consistent with the available space in the buffer.

In theory, readv and writev can perform I / O operations that exceed SIZE_MAX/2 , repeating the same iov buffers several times in the array, but if I remember correctly, they indicate a failure if the total size is larger than SSIZE_MAX .

+1
source share

All Articles