My C code is sending data to Uart perfectly but while receiving it gives error.
Here is my code
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h>
void main()
{
int USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY );
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
/* Error Handling */
if ( USB < 0 )
{
printf( "Error %d form tcgetattr : %s /n", errno, strerror( errno ) );
}
/* Save old tty parameters */
tty_old = tty;
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);
/* Setting other Port Stuff */
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 1; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
/* Make raw */
cfmakeraw(&tty);
/* Flush Port, then applies attributes */
tcflush( USB, TCIFLUSH );
if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
{
printf("Error %d from tcsetattr /n",errno);
// std::cout << "Error " << errno << " from tcsetattr" << std::endl;
}
/* WRITE */
unsigned char cmd[] = "YES this program is writing \r";
int n_written = 0,spot = 0;
do {
n_written = write( USB, &cmd[spot], 1 );
spot += n_written;
} while (cmd[spot-1] != '\r' && n_written > 0);
/* READ */
int n = 0,spot_r =0;
char buf = '\0';
/* Whole response*/
char response[1024];
memset(response, '\0', sizeof response);
do {
n = read( USB, &buf, 1 );
sprintf( &response[spot_r], "%c", buf );
spot_r += n;
} while( buf != '\r' && n > 0);
if (n < 0) {
printf("Error reading %s",strerror(errno));
}
else if (n==0) {
printf("read nothing");
}
else {
printf("Response %s",response);
}
}
Error Message
Error reading Resource temporarily unavailable
It is sending data to UART perfectly.
But at reception side it gives error of resource temporary unavailable.
Should i put delay in-between?
Or any other function that could help me out.
Thank you.
Abhi
Related
I am writing a small library module which accesses the UART and uses epoll to react on incoming data. It works fine with the tty device, however, I want to write test cases for this module. When I open a loop device (/dev/loop*) instead of a tty, epoll_ctl fails with EPERM. The Manual states:
EPERM: fd does not support epoll.
So the question is: Is there any kind of loopback device which could be used with epoll?
Here's a gist with my example code: https://gist.github.com/0815fox/9ce9f19648ce2dc9b23b37dbbb9adab4
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/epoll.h>
#include <linux/loop.h>
#include <sys/ioctl.h>
#include <pthread.h>
static int getFreeLoopDevice(const char * backingfileName) {
int loopctlfd, loopfd, backingfile;
long devnr;
char loopname[4096];
loopctlfd = open("/dev/loop-control", O_RDWR);
devnr = ioctl(loopctlfd, LOOP_CTL_GET_FREE);
close(loopctlfd);
return devnr;
sprintf(loopname, "/dev/loop%ld", devnr);
loopfd = open(loopname, O_RDWR);
backingfile = open(backingfileName, O_RDWR);
ioctl(loopfd, LOOP_SET_FD, backingfile);
return loopfd;
}
static int set_interface_attribs (int fd, int speed, int parity) {
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0) {
fprintf (stderr, "error %d from tcgetattr", errno);
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0) {
fprintf (stderr, "error %d from tcsetattr", errno);
return -1;
}
return 0;
}
void set_blocking (int fd, int should_block) {
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
fprintf (stderr, "error %d from tggetattr", errno);
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
if (tcsetattr (fd, TCSANOW, &tty) != 0)
fprintf (stderr, "error %d setting term attributes", errno);
}
static void * uart_thread(void * handle) {
const int uartHandle = *(int*)handle;
char buffer[100];
// the epoll stuff:
const int ePollFileDescriptor = epoll_create(1);
struct epoll_event ePollEvent;
ePollEvent.events = EPOLLIN;
ePollEvent.data.fd = uartHandle;
const int epoll_ctl_result = epoll_ctl(ePollFileDescriptor, EPOLL_CTL_ADD, uartHandle, &ePollEvent);
if (epoll_ctl_result) perror("epoll_ctl\n");
for (;;) {
static struct epoll_event events[1] __attribute__((aligned(8)));
const int eventCount = epoll_wait(ePollFileDescriptor, events, 1, -1);
if (eventCount < 0) {
perror("epoll_wait\n");
} else {
const int bytesRead = read(uartHandle, buffer, 99);
if (bytesRead >= 0) buffer[bytesRead] = 0;
else buffer[0] = 0;
fprintf(stderr, "Buffer: %s\nBytesread:%d\n", buffer, bytesRead);
}
}
}
int main (void) {
// working:
// char *portname = "/dev/ttyUSB0";
// const int uartHandle = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
// not working:
const int uartHandle = getFreeLoopDevice("/tmp/my-loop-back");
if (uartHandle < 0) {
fprintf (stderr, "error %d opening: %s\n", errno, strerror (errno));
return errno;
}
set_interface_attribs (uartHandle, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity)
set_blocking (uartHandle, 0); // set no blocking
// the pthread stuff:
pthread_t threadHandle;
const int pthread_create_result = pthread_create( &threadHandle, NULL, uart_thread, (void *) &uartHandle);
while (1) {
fprintf(stderr, "writing to uart\n");
write(uartHandle, "hello!\n", 7);
sleep(10);
}
}
I am using USB to Uart converter for transmission and reception for my data.
Here is my code for transmission
void main()
{
int USB = open( "/dev/ttyUSB0", O_RDWR | O_NONBLOCK | O_NDELAY);
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);
/* Setting other Port Stuff */
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 1; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
/* Make raw */
cfmakeraw(&tty);
/* Flush Port, then applies attributes */
tcflush( USB, TCIFLUSH );
/* WRITE */
unsigned char cmd[] = "YES this program is writing \r";
int n_written = 0,spot = 0;
do {
n_written = write( USB, &cmd[spot], 1 );
spot += n_written;
} while (cmd[spot-1] != '\r' && n_written > 0);
The output of my code is same as expacted
YES this program is writing
Now this is my code for reading from UART
/* READ */
int n = 0,spot1 =0;
char buf = '\0';
/* Whole response*/
char response[1024];
memset(response, '\0', sizeof response);
do {
n = read( USB, &buf, 1 );
sprintf( &response[spot1], "%c", buf );
spot1 += n;
} while( buf != '\r' && n > 0);
if (n < 0) {
printf("Error reading %d %s",errno, strerror(errno));
}
else if (n==0) {
printf("read nothing");
}
else {
printf("Response %s",response);
}
}
This reading from Uart gives error from errno and it is error number 11 which says that Resource is temporary unavailable
I am getting this output
Error reading 11 Resource temporarily unavailable
I am using USB to UART converter. Hope someone could help. Thanks :)
You are getting the error code EAGAIN from your read call and this is causing you to exit your loop and print out the error. Of course EAGAIN means that this was a temporary problem (e.g. there wasn't anything to read at the time you tried to read it, perhaps you'd like to try later?).
You could restructure the read to be similar to:
n = read(USB, &buf, 1)
if (n == 0) {
break;
} else if (n > 0) {
response[spot1++] = buf;
} else if (n == EAGAIN || n == EWOULDBLOCK)
continue;
} else { /*unrecoverable error */
perror("Error reading");
break;
}
You could improve your code by making buf be an array and reading more than one character at a time. Also notice that sprintf was unnecessary, you can just copy the character(s) in to the array.
I am writing c code to send and receive characters to and from an Ergometer using FTDI USB to RS232 Cable in Linux. The write function is working properly but the read function has failed. I am not getting any data back from the Ergometer. I have posted my code here:
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#include <stdbool.h>
#define SOH 0x01 // Start of Header
#define ETB 0x17 // End of transmission block
#define ACK 0x06 // Acknowledged
#define NAK 0x15 // Not Acknowledged
#define GS 0x1D // Group separator
#define FP_WATT1_PROG 0x13
#define FP_CARDIO 0x2F
int main(){
/* Open File Descriptor */
int USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY );
/* Error Handling */
if ( USB < 0 )
{
printf("Error beim oeffnen");
}
// Configure Port
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
// Error Handling
if ( tcgetattr ( USB, &tty ) != 0 ) {
printf("error beim tcgetattr");
}
// Save old tty parameters
tty_old = tty;
// Set Baud Rate of 9600 Bps
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);
// 8 Bits, No Parity and 1 Stop bit settings
tty.c_cflag &= ~PARENB; // No Parity
tty.c_cflag &= ~CSTOPB; // 1 Stop Bit
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8 Bits
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 1; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= (CLOCAL | CREAD ); // turn on READ & ignore ctrl lines
// Make raw
cfmakeraw(&tty);
// Flush Port, then apply attributes
tcflush( USB, TCIFLUSH );
if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
{
printf("from tcsetattr");
}
// WRITE
// Set the Ergometer language.
char cmd[255] = {0x60,0x01}; // Ergometer Cockpit Adresse
int n_written = write( USB, cmd, sizeof(cmd));
printf("%s\n",cmd);
// Allocate memory for read buffer
int bb = 0;
int i,x = 0;
bool cmdOK=false;
char marr[10];
do
{
if((bb = read(USB, &marr[x], sizeof( marr )-x )) > 0)
{
for (i=x;i<x+bb;i++)
{
//printf("0x%02x",marr[i]);
if ((marr[i]==ACK)||(marr[i]==NAK)) cmdOK=true;
}
x+=bb;
//printf("\n");
//printf("x=%d\n",x);
}
}while(!cmdOK);
printf("-Ausgabe---------------------\n");
for (i=0; i<x; i++)
{
printf("0x%02x",marr[i]);
}
close(USB);
// ttyUSB0 auf alten Wert setzen
tcflush(USB,TCIFLUSH);
if (tcsetattr(USB, TCSANOW, &tty) != 0) return(-1);
exit(0);
return 0;
}
This should be fairly straightforward for someone in the know, but I have been struggling for a bit and would appreciate some thoughts. I am writing an application that reads from a serial comm port.
My Setup:
I have a windows machine with putty open and connected to my comm port of interest.
I have a linux (ubuntu) machine in which I am writing this software (in C).
I am typing into putty on the windows machine and trying to read it with my application on the linux machine.
What I have:
So far, using the code below I can successfully write to the putty display on the windows machine from my application on the linux computer, but I cannot read the buffer on my linux machine when I type on the windows machine.
Code:
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h>
int openport()
{
int USB = open( "/dev/ttyUSB0", O_RDWR| O_NOCTTY | O_NONBLOCK );
struct termios tty;
struct termios tty_old;
memset(&tty, 0, sizeof tty);
/* Error Handling */
if ( tcgetattr( USB, &tty ) != 0 )
{
printf("Error 1, or something");
}
/* Save old tty parameters */
tty_old = tty;
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);
/* Setting other Port Stuff */
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 1; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
/* Make raw */
cfmakeraw(&tty);
/* Flush Port, then applies attributes */
tcflush( USB, TCIFLUSH );
if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
{
printf("Error, or something");
}
return USB;
}
int main()
{
int n = 0;
int j = 0;
unsigned char buf[10] = {0,0,0,0,0,0,0,0,0,0};
printf("Hello world!\n");
int USB = openport();
unsigned char cmd[] = "INIT Hey SHanahas \r";
int n_written = 0;
do
{
n_written += write( USB, &cmd[n_written], 1 );
}
while (cmd[n_written-1] != '\r' && n_written > 0);
printf("Here\n\n");
do
{
n = read( USB, &buf, 1 );
printf("%s \n",buf);
printf("%d",n);
}
while( buf != '\r' && n > 0);
printf("Herr2");
return 0;
}
Does anyone have any thoughts on what might be happening? the read() command returns a -1 error.
Thanks!
I am a little bit confused about reading and writing to a serial port. I have a USB device in Linux that uses the FTDI USB serial device converter driver. When I plug it in, it creates: /dev/ttyUSB1.
I thought itd be simple to open and read/write from it in C. I know the baud rate and parity information, but it seems like there is no standard for this?
Am I missing something, or can someone point me in the right direction?
I wrote this a long time ago (from years 1985-1992, with just a few tweaks since then), and just copy and paste the bits needed into each project.
You must call cfmakeraw on a tty obtained from tcgetattr. You cannot zero-out a struct termios, configure it, and then set the tty with tcsetattr. If you use the zero-out method, then you will experience unexplained intermittent failures, especially on the BSDs and OS X. "Unexplained intermittent failures" include hanging in read(3).
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int
set_interface_attribs (int fd, int speed, int parity)
{
struct termios tty;
if (tcgetattr (fd, &tty) != 0)
{
error_message ("error %d from tcgetattr", errno);
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
error_message ("error %d from tcsetattr", errno);
return -1;
}
return 0;
}
void
set_blocking (int fd, int should_block)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
error_message ("error %d from tggetattr", errno);
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
if (tcsetattr (fd, TCSANOW, &tty) != 0)
error_message ("error %d setting term attributes", errno);
}
...
char *portname = "/dev/ttyUSB1"
...
int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0)
{
error_message ("error %d opening %s: %s", errno, portname, strerror (errno));
return;
}
set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity)
set_blocking (fd, 0); // set no blocking
write (fd, "hello!\n", 7); // send 7 character greeting
usleep ((7 + 25) * 100); // sleep enough to transmit the 7 plus
// receive 25: approx 100 uS per char transmit
char buf [100];
int n = read (fd, buf, sizeof buf); // read up to 100 characters if ready to read
The values for speed are B115200, B230400, B9600, B19200, B38400, B57600, B1200, B2400, B4800, etc. The values for parity are 0 (meaning no parity), PARENB|PARODD (enable parity and use odd), PARENB (enable parity and use even), PARENB|PARODD|CMSPAR (mark parity), and PARENB|CMSPAR (space parity).
"Blocking" sets whether a read() on the port waits for the specified number of characters to arrive. Setting no blocking means that a read() returns however many characters are available without waiting for more, up to the buffer limit.
Addendum:
CMSPAR is needed only for choosing mark and space parity, which is uncommon. For most applications, it can be omitted. My header file /usr/include/bits/termios.h enables definition of CMSPAR only if the preprocessor symbol __USE_MISC is defined. That definition occurs (in features.h) with
#if defined _BSD_SOURCE || defined _SVID_SOURCE
#define __USE_MISC 1
#endif
The introductory comments of <features.h> says:
/* These are defined by the user (or the compiler)
to specify the desired environment:
...
_BSD_SOURCE ISO C, POSIX, and 4.3BSD things.
_SVID_SOURCE ISO C, POSIX, and SVID things.
...
*/
For demo code that conforms to POSIX standard as described in Setting Terminal Modes Properly
and Serial Programming Guide for POSIX Operating Systems, the following is offered.
This code should execute correctly using Linux on x86 as well as ARM (or even CRIS) processors.
It's essentially derived from the other answer, but inaccurate and misleading comments have been corrected.
This demo program opens and initializes a serial terminal at 115200 baud for non-canonical mode that is as portable as possible.
The program transmits a hardcoded text string to the other terminal, and delays while the output is performed.
The program then enters an infinite loop to receive and display data from the serial terminal.
By default the received data is displayed as hexadecimal byte values.
To make the program treat the received data as ASCII codes, compile the program with the symbol DISPLAY_STRING, e.g.
cc -DDISPLAY_STRING demo.c
If the received data is ASCII text (rather than binary data) and you want to read it as lines terminated by the newline character, then see this answer for a sample program.
#define TERMINAL "/dev/ttyUSB0"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 1;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
void set_mincount(int fd, int mcount)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error tcgetattr: %s\n", strerror(errno));
return;
}
tty.c_cc[VMIN] = mcount ? 1 : 0;
tty.c_cc[VTIME] = 5; /* half second timer */
if (tcsetattr(fd, TCSANOW, &tty) < 0)
printf("Error tcsetattr: %s\n", strerror(errno));
}
int main()
{
char *portname = TERMINAL;
int fd;
int wlen;
char *xstr = "Hello!\n";
int xlen = strlen(xstr);
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
/*baudrate 115200, 8 bits, no parity, 1 stop bit */
set_interface_attribs(fd, B115200);
//set_mincount(fd, 0); /* set to pure timed read */
/* simple output */
wlen = write(fd, xstr, xlen);
if (wlen != xlen) {
printf("Error from write: %d, %d\n", wlen, errno);
}
tcdrain(fd); /* delay for output */
/* simple noncanonical input */
do {
unsigned char buf[80];
int rdlen;
rdlen = read(fd, buf, sizeof(buf) - 1);
if (rdlen > 0) {
#ifdef DISPLAY_STRING
buf[rdlen] = 0;
printf("Read %d: \"%s\"\n", rdlen, buf);
#else /* display hex */
unsigned char *p;
printf("Read %d:", rdlen);
for (p = buf; rdlen-- > 0; p++)
printf(" 0x%x", *p);
printf("\n");
#endif
} else if (rdlen < 0) {
printf("Error from read: %d: %s\n", rdlen, strerror(errno));
} else { /* rdlen == 0 */
printf("Timeout from read\n");
}
/* repeat read to get full message */
} while (1);
}
For an example of an efficient program that provides buffering of received data yet allows byte-by-byte handing of the input, then see this answer.