[En-Nut-Discussion] RFC: Changing Nut/OS device API to use size_t as type for length parameters in read() and write() and similar functions

Ole Reinhardt ole.reinhardt at embedded-it.de
Tue Sep 29 23:55:41 CEST 2015


Hi all,

while debugging the bug mentioned in my last posting, I realised, that
our device API, the libc implementation and the driver implementations
do not use consistent variable types for length parameters and return
values.

For our platform, this might be more a theoretical problem, but I would
suggest to harmonize the usage of integer types through the APIs.


For example:

_write() is defined as

int _write(int fd, const void *data, size_t count)

similar for read()


fwrite() is defined as

size_t fwrite(const void *data, size_t size, size_t count, FILE * stream)



First problem:
==============

_write() will return the number of bytes written.

On some platforms, size_t is not necessarily an unsigned int. For
example on 64 bit platforms it is a long unsigned int (64bit), while int
is only 32 bit.

For the AVR platform, I'm not sure how size_t is defined.

This means that calling _write() with size > MAX_INT, might correctly
write the given value, but will generate an integer overflow, if the
written size is returned as int.

Further fwrite() internally calls _write(). fwrite() correctly returns a
size_t, but as _write() returns only int, it still might return invalid
values.


Second problem:
===============

The file operations in struct _NUTDEVICE define

int (*dev_read) (NUTFILE *, void *, int);
int (*dev_write) (NUTFILE *, const void *, int);

with similar implementations for further fops and struct _NUTVIRTUALDEVICE

These again are called from _write() and _read(), passing size_t
arguments to these functions as third parameter.


I'm sure, when we carefully read the sources, we'll find several more
similar issues all over the code.



Suggestion:
===========

I'd like to suggest to follow POSIX and

a)
use size_t for all length / size parameters and internal calculations
based on these values

b)
use ssize_t or size_t as return value for functions that return sizes
(of read or written data for example)


This would influence

_read(), _write(), fread() and fwrite (in the implementation), the
NUTDEVICE file operations (including ioctl) and for sure all driver
implementations, socket implentations etc.




So I'm happy about any comments on this...

Best regards,

Ole


-- 
kernel concepts GmbH            Tel: +49-271-771091-14
Sieghuetter Hauptweg 48         Mob: +49-177-7420433
D-57072 Siegen
http://www.embedded-it.de
http://www.kernelconcepts.de


More information about the En-Nut-Discussion mailing list