Skip to content

read() write() functions return types. #333

@Jakio815

Description

@Jakio815

The return types of the read() and write() functions seem quite odd.

read()

int read_from_socket(int socket, size_t num_bytes, unsigned char* buffer);
//  * @return 0 for success, 1 for EOF, and -1 for an error.

int read_from_socket_close_on_error(int* socket, size_t num_bytes, unsigned char* buffer);
//  * @return 0 for success, -1 for failure.

void read_from_socket_fail_on_error( int* socket, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...);
//  @return The number of bytes read, or 0 if an EOF is received, or a negative number for an error.

write()

int write_to_socket(int socket, size_t num_bytes, unsigned char* buffer);
//  * @return 0 for success, -1 for failure.

int write_to_socket_close_on_error(int* socket, size_t num_bytes, unsigned char* buffer);
//  * @return 0 for success, -1 for failure.

void write_to_socket_fail_on_error( int* socket, size_t num_bytes, unsigned char* buffer, lf_mutex_t* mutex, char* format, ...);

Prob1. Return values.

So, it currently returns 0 for success, -1 for failure.

This seems not to be a general practice for read() and write() functions.

According to the man page of read(),

       On success, the number of bytes read is returned (zero indicates
       end of file), and the file position is advanced by this number.
       It is not an error if this number is smaller than the number of
       bytes requested; this may happen for example because fewer bytes
       are actually available right now (maybe because we were close to
       end-of-file, or because we are reading from a pipe, or from a
       terminal), or because read() was interrupted by a signal.  See
       also NOTES.

       On error, -1 is returned, and [errno](https://man7.org/linux/man-pages/man3/errno.3.html) is set to indicate the error.
       In this case, it is left unspecified whether the file position
       (if any) changes.

To summarize,

return:
     >0: number_of_bytes_successfully_read,
      0: EOF (no bytes read)
     -1: error

Prob2. Parameter orders

ssize_t read(int fd, void buf[.count], size_t count);
int read_from_socket(int socket, size_t num_bytes, unsigned char* buffer);

The order of the parameters are quite different. It can be quite confusing.

Seems to need some refactoring.

Why it should be changed?

On PR #330, I am working on a network driver to enable other network protocols to work. Especially targeting to make TCP based encryption protocols such as TLS/SSL work.

int read_from_netdrv(netdrv_t netdrv, unsigned char *buffer, size_t num_bytes)

Below is the read function of OpenSSL's TLS library. Details are here.

 #include <openssl/ssl.h>

 int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
 int SSL_read(SSL *ssl, void *buf, int num);

 int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
 int SSL_peek(SSL *ssl, void *buf, int num);

DESCRIPTION
SSL_read_ex() and SSL_read() try to read num bytes from the specified ssl
 into the buffer buf. On success SSL_read_ex() will store the number of bytes
  actually read in *readbytes.

SSL_peek_ex() and SSL_peek() are identical to SSL_read_ex() and SSL_read()
 respectively except no bytes are actually removed from the underlying BIO
  during the read, so that a subsequent call to SSL_read_ex() or SSL_read()
   will yield at least the same bytes.

Return values

SSL_read_ex() and SSL_peek_ex() will return 1 for success or 0 for failure. 
Success means that 1 or more application data bytes have been read from
 the SSL connection. Failure means that no bytes could be read from the
 SSL connection. Failures can be retryable (e.g. we are waiting for more 
bytes to be delivered by the network) or non-retryable (e.g. a fatal network
 error). In the event of a failure call SSL_get_error(3) to find out
 the reason which indicates whether the call is retryable or not.

For SSL_read() and SSL_peek() the following return values can occur:

> 0
The read operation was successful. The return value is the number of bytes
 actually read from the TLS/SSL connection.

<= 0
The read operation was not successful, because either the connection was 
closed, an error occurred or action must be taken by the calling process. Call 
SSL_get_error(3)with the return value ret to find out the reason.

Old documentation indicated a difference between 0 and -1, and that -1 was 
retryable. You should instead call SSL_get_error() to find out if it's retryable.

It follows the basic read() function style.

For the scalability of the code the socket read and writes seem to need some refactoring.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions