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-L1vi/[email protected]>
| Newsgroups | gmane.comp.hardware.microcontrollers.ethernut |
|---|---|
| Message-ID | <[email protected]> |
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 _______________________________________________ http://lists.egnite.de/mailman/listinfo/en-nut-discussion