title: C Failing to Read Data from Serial Port in Linux
body: <p>I'm using the following C code borrowed from here: <a href="https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c">how to open, read, and write from serial port in C</a></p>
  
  <p>with some slight modifications so that the program waits for keyboard input, then writes this data to a serial port and waits to read it back. Here's my code:</p>
  
  <pre><code>#include &lt;errno.h&gt;
  #include &lt;termios.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;fcntl.h&gt;
  
  
  
  int
  set_interface_attribs (int fd, int speed, int parity)
  {
          struct termios tty;
          memset (&amp;tty, 0, sizeof tty);
          if (tcgetattr (fd, &amp;tty) != 0)
          {
                  error_message ("error %d from tcgetattr", errno);
                  return -1;
          }
  
          cfsetospeed (&amp;tty, speed);
          cfsetispeed (&amp;tty, speed);
  
          tty.c_cflag = (tty.c_cflag &amp; ~CSIZE) | CS8;     // 8-bit chars
          // disable IGNBRK for mismatched speed tests; otherwise receive break
          // as \000 chars
          tty.c_iflag &amp;= ~IGNBRK;         // ignore break signal
          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 &amp;= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
  
          tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                          // enable reading
          tty.c_cflag &amp;= ~(PARENB | PARODD);      // shut off parity
          tty.c_cflag |= parity;
          tty.c_cflag &amp;= ~CSTOPB;
          tty.c_cflag &amp;= ~CRTSCTS;
  
          if (tcsetattr (fd, TCSANOW, &amp;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 (&amp;tty, 0, sizeof tty);
          if (tcgetattr (fd, &amp;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, &amp;tty) != 0)
                  error_message ("error %d setting term attributes", errno);
  }
  
  
  int main{
  
      char *portname = "/dev/tty0"
      int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
      if (fd &lt; 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
  
      while (1){
          char data[20];
          if (fgets(data, sizeof data, stdin)){
              int m = write(fd, data, sizeof data);
              printf("%d chars written\n", m);
              char buf[100];
              sleep(10);
              int n = read (fd, buf, sizeof buf);
              printf("%d chars read", n);
          }
      }
  }
  </code></pre>
  
  <p>The problem is that while the keyboard input is successfully written to serial file, after sleeping for 10 seconds the program still reports that it has read 0 chars. Why is this? Do I need to actually have a physical device waiting on the other end of the port which receives the data and returns something, or is it fine to write to and read from the serial port with the same program? Thanks in advance for any help!</p>
  
  <h3>EDIT:</h3>
  
  <p>Ok so now I've created a second program which waits for data on the serial port sent by the above program, but this program is still unable to read the data sent to it. Here's the code:</p>
  
  <pre><code>#include &lt;errno.h&gt;
  #include &lt;termios.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;fcntl.h&gt;
  
  
  
  int
  set_interface_attribs (int fd, int speed, int parity)
  {
          struct termios tty;
          memset (&amp;tty, 0, sizeof tty);
          if (tcgetattr (fd, &amp;tty) != 0)
          {
                  error_message ("error %d from tcgetattr", errno);
                  return -1;
          }
  
          cfsetospeed (&amp;tty, speed);
          cfsetispeed (&amp;tty, speed);
  
          tty.c_cflag = (tty.c_cflag &amp; ~CSIZE) | CS8;     // 8-bit chars
          // disable IGNBRK for mismatched speed tests; otherwise receive break
          // as \000 chars
          tty.c_iflag &amp;= ~IGNBRK;         // ignore break signal
          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 &amp;= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
  
          tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                          // enable reading
          tty.c_cflag &amp;= ~(PARENB | PARODD);      // shut off parity
          tty.c_cflag |= parity;
          tty.c_cflag &amp;= ~CSTOPB;
          tty.c_cflag &amp;= ~CRTSCTS;
  
          if (tcsetattr (fd, TCSANOW, &amp;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 (&amp;tty, 0, sizeof tty);
          if (tcgetattr (fd, &amp;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, &amp;tty) != 0)
                  error_message ("error %d setting term attributes", errno);
  }
  
  
  int main{
  
      char *portname = "/dev/tty0"
      int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
      if (fd &lt; 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
  
  
      char buf[20];
      int n = 0;
      while (n == 0){
          n = read(fd, buf, sizeof buf);
      }
      printf("%d chars read\n", n);
  
      return 0;
  
  }
  </code></pre>
  
  <p>When I run this and right afterwards run the first program and write some data to the serial port, this program just stays in the while loop forever and never reads in any data. Help?</p>