title: Linux write to serial port in c++ returns bad file descriptor
body: <p>I am writing a c++ program to send a receive data from a device located at /dev/ttyACM0. I am able to read from the device without a problem, I can write to it from the command line, but I can not write to it within my c++ program. Here is what I have so far:</p>
  
  <pre><code>#include "SerialComms.h"
  #include &lt;errno.h&gt;
  #include &lt;string.h&gt;
  SerialComms::SerialComms() {
      serial_filestream = -1;
  
      //CONFIGURE THE PORT
      //The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
      //  Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
      //  CSIZE:- CS5, CS6, CS7, CS8
      //  CLOCAL - Ignore modem status lines
      //  CREAD - Enable receiver
      //  IGNPAR = Ignore characters with parity errors
      //  ICRNL - Map CR to NL on input
      //  PARENB - Parity enable
      //  PARODD - Odd parity (else even)
      tcgetattr(serial_filestream, &amp;options);
      options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;     //&lt;Set baud rate
      options.c_iflag = IGNPAR;
      options.c_oflag = 0;
      options.c_lflag = 0;
  }
  
  bool SerialComms::Init(string type){
      //The flags (defined in fcntl.h):
      //  Access modes (use 1 of these):
      //      O_RDONLY - Open for reading only.
      //      O_RDWR - Open for reading and writing.
      //      O_WRONLY - Open for writing only.
      //
      //  O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
      //                                          if there is no input immediately available (instead of blocking). Likewise, write requests can also return
      //                                          immediately with a failure status if the output can't be written immediately.
      //
      //  O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
      if (type == "USB"){  //if type equals USB, open USB
          serial_filestream = open(USBSerial, O_RDWR | O_NOCTTY | O_NDELAY);      //Open in non blocking read/write mode
      }else if (type == "UART1"){
          serial_filestream = open(UART1, O_RDWR | O_NOCTTY | O_NDELAY);      //Open in non blocking read/write mode
      }
  
      if (serial_filestream == -1)
      {
          //ERROR - CAN'T OPEN SERIAL PORT
          printf("Error - Unable to open: %s\n", type.c_str());
      }else{
          printf("Opened serial type: %s\n", type.c_str());
      }
      tcflush(serial_filestream, TCIFLUSH);
      tcsetattr(serial_filestream, TCSANOW, &amp;options);
      printf("Serial Comms for type: %s intialized", type.c_str());
      return 1;
  }
  
  bool SerialComms::Ping(){
      WriteSerial("p,1,1;\n");
      return true;
  }
  
   char* SerialComms::ReadSerial(){
      if (serial_filestream != -1)
      {
          // Read up to 255 characters from the port if they are there
          char rx_buffer[256];
          int rx_length = read(serial_filestream, (void*)rx_buffer, 255);     //Filestream, buffer to store in, number of bytes to read (max)
          if (rx_length &lt; 0)
          {
              //An error occured (will occur if there are no bytes)
          }
          else if (rx_length == 0)
          {
              //No data waiting
          }
          else
          {
              //Bytes received
              rx_buffer[rx_length] = '\0';
              int j = 0;
              while (rx_buffer[j] != ';' &amp;&amp; rx_buffer[j] != '\0' &amp;&amp; rx_buffer[j] != '\n'){
                  j++;
              }
              char rx_return[j+1];
              for(int i = 0; i &lt; j+1; i++){
                  rx_return[i] = rx_buffer[i];
              }
              rx_return[j+1] = '\0';
              return rx_return;
          }
      }
      return '\0';
  }
  
  bool SerialComms::WriteSerial(string data_out){
      const char * tx_buffer = data_out.c_str();
      if (serial_filestream != -1)
      {
          int wr = write(serial_filestream, tx_buffer, strlen(tx_buffer));
          if (wr &lt; 0){
              printf("Error writing to Serial: %s \n", strerror(errno));
              return 0;
          } else{
              printf("WroteSerial: %s, %d \n", tx_buffer, strlen(tx_buffer));
              return 1;
          }
      }else{
          printf("Error writing to Serial filestream errors \n");
          return 0;
      }
      return 1;
  }
  SerialComms::~SerialComms() {
      close(serial_filestream);
  }
  </code></pre>
  
  <p>If I use the command:</p>
  
  <pre><code>echo "p,1,1;\n" &gt; /dev/ttyACM0
  </code></pre>
  
  <p>It works without a problem, and I receive back the expected data from the serial device. </p>
  
  <p>However, my main loop in the c++ program calls the WriteSerial function once a minute like so:</p>
  
  <pre><code>void Ping(SerialComms serialLine){
      serialLine.WriteSerial("p,1,1;\n");
      printf("pinged at: %s \n", ctime(&amp;now));
  }
  </code></pre>
  
  <p>The first time the write is performed it doesn't give an error, but it doesn't seem to work, and the second write returns a bad file descriptor error. Also, it screws up reading from the port as well. Here is my program output:</p>
  
  <pre><code>WroteSerial: p,1,1;
  , 7 
  pinged at: Wed Dec 30 19:08:05 2015
  
  Error writing to Serial: Bad file descriptor 
  pinged at: Wed Dec 30 19:09:06 2015
  </code></pre>
  
  <p>I'm really not sure where to go from here so any suggestion would be appreciated. I'm pretty sure I'm missing something basic but I can't see it at the moment. </p>