Counting bytes received by posix read()

883 Views Asked by At

I get confused with one line of code:

temp_uart_count = read(VCOM, temp_uart_data, 4096); 

I found more about read function at http://linux.die.net/man/3/read, but if everything is okay it returns 0, so how we can get num of bytes received from that?

temp_uart_count is used to count how much bytes we received from virtual COM port and stored it to temp_uart_data which is 4096 bytes wide.

Am I really getting how much bytes i received with this line of code?

3

There are 3 best solutions below

0
On BEST ANSWER

... but if everything is okay it returns 0, so how we can get num of bytes received from that?

A return code of zero simply means that read() was unable to provide any data.

Am I really getting how much bytes i received with this line of code?

Yes, a positive return code (i.e. >= 0) from read() is an accurate count of bytes that were returned in the buffer. Zero is a valid count.

If you're expecting more data, then simply repeat the read() syscall. (However you may have setup the termios arguments poorly, e.g. VMIN=0 and VTIME=0).


And - zero indicates end of file

If you get 0, it means that the end of file (or an equivalent condition) has been reached and there is nothing else to read.

The above (one from a comment, and the other in an answer) are incorrect.
Reading from a tty device (e.g. a serial port) is not like reading from a file on a block device, but is temporal. Data for reading is only available as it is received over the comm link.

A non-blocking read() will return with -1 and errno set to EAGAIN when there is no data available.

A blocking non-canonical read() will return zero when there is no data available. Correlate your termios configuration with this to confirm that a return of zero is valid (and does not indicate "end of file").

In either case, the read() can be repeated to get more data when/if it arrives.
Also when using non-canonical (aka raw) mode (or non-blocking reads), do not expect or rely on the the read() to perform message or packet management for you. You will need to add a layer to your program to read bytes, concatenate those bytes into a complete message datagram/packet, and validate it before that message can be processed.

2
On

Yes, temp_uart_count will contain the actual number of bytes read, and obviously that number will be smaller or equal to the number of elements of temp_uart_data. If you get 0, it means that the end of file (or an equivalent condition) has been reached and there is nothing else to read.

If it returns -1 this indicate that an error has occurred and you'll need to check the errno variable to understand what happened.

0
On

ssize_t read(int fd, void *buf, size_t count); returns you the size of bytes he read and stores it into the value you passed in parameters. And when errors happen it returns -1 (with errno set to EINTR) or to return the number of bytes already read..

From the linux man :

On files that support seeking, the read operation commences at the current file offset, and the file offset is incremented by the number of bytes read. If the current file offset is at or past the end of file, no bytes are read, and read() returns zero.