read on a tty blocks

From: J. Dubois (Analog S.I.) <"J.>
Date: Fri, 31 Oct 1997 16:32:46 -0500 (EST)

This is more of a programming questions, but here goes:
I'me writting a C program that manipulates a serial interface (/dev/tty00)

Sometimes, when the 2 communicating programs get out of sync, the "read"
command omn the tty hangs and freezes the port.
The process is in an üninteruptible" state (status U on a ps) and I
can't free it unless I reboot the system.

Any insight on how i can prevent this?
the port in opened in "non CANONICAL" but does not have "NODELAY" set,
since I need the timout functionality.

Any hints?

Thanks a bunch!

For the avid reader, here are my tty open and setup calls.
/* --------------------------------------------------------------

   devSetup:
       This function sets up all the communication parameters on the serial
       link device
       NOTE: The structure DevSet is static so we can change the timeouts

   Param:

   Returns:
         NOTHING. Tis function exits the program if something fails

------------------------------------------------------------------ */

void devSetup()
{

   /* Setup the timer function only once */
   if (! IsConnected) {
      if (signal( SIGALRM, &devTimer) == SIG_ERR) {
         fprintf(stderr," ERROR setting signal error = %d\n",errno);
         exit(-1);
         }
      IsConnected=TRUE;
      }
   else {
      /* Close the device before re-opening it */
      if (close(CommDev) != 0) {
         fprintf(stderr," SYSTEM ERROR, could not close link (err=%d)\n",
                 errno);
         exit(-1);
         }
      }
   TimerStat=3;
   TimedOut=FALSE;
   alarm(Conn.Timeout);
   CommDev=open(Conn.DevName,O_RDWR|O_NOCTTY);
   alarm(0);
   if (TimedOut)
      exit(-1);

   if (CommDev < 0)
      {
      fprintf(stderr," ERROR connection to serial link check device %s\n",
                     Conn.DevName);
      exit(-1);
      }
   if (tcflush(CommDev, TCIOFLUSH) != 0) {
      fprintf(stderr," ERROR could not flush the serial link %s!\n",
              Conn.DevName);
      exit(-1);
      }

   /* Setup the basic communications option + speed, parity, etc */
   if (tcgetattr(CommDev, &DevSet) != 0) {
      fprintf(stderr," ERROR getting options of serial link (%s) error %d\n",
                     Conn.DevName, errno);
      exit(-1);
      }

   /* Set INPUT control */
   DevSet.c_iflag=(DevSet.c_iflag & (IXON ^ ALLSET) ); /* Clear XON */
   DevSet.c_iflag=(DevSet.c_iflag & (IXOFF ^ ALLSET) ); /* Clear XOFF */
   DevSet.c_iflag=(DevSet.c_iflag & (BRKINT ^ ALLSET) );/* Clear XOFF */
   /* Remove all signal processing */
   DevSet.c_lflag=(DevSet.c_lflag & (ISIG ^ ALLSET) );
   DevSet.c_lflag=(DevSet.c_lflag & (ECHO ^ ALLSET) );

   /* Clear all CR,NL mapping */
   DevSet.c_iflag=(DevSet.c_iflag | INLCR );
   DevSet.c_iflag=(DevSet.c_iflag & (ICRNL ^ ALLSET) );

   /* Got to read in CANONICAL because no NL to terminate line */
   DevSet.c_lflag=(DevSet.c_lflag & (ICANON ^ ALLSET) );
   DevSet.c_cc[VMIN]=1; /* Always read 1 byte at the time */
   DevSet.c_cc[VTIME]=5; /* Timeout of 1/2 a sec for subs. reads */

   /* Set FLOW control */
   DevSet.c_cflag=(DevSet.c_cflag | CRTSCTS ); /* Hardw. Flow Ctrl */
   DevSet.c_cflag=(DevSet.c_cflag | CLOCAL ); /* No modem control */
   if (! Conn.EightBits)
      DevSet.c_cflag=(DevSet.c_cflag | CS7 & (CS8 ^ ALLSET));/* 7 Bits */

   /* Parity setup */
   if (Conn.Parity == 'N') {
      /* Clear parity chck */
      DevSet.c_cflag=(DevSet.c_cflag & (PARENB ^ ALLSET) );
      }
   else {
      /* Set parity check on and enable proper check */
      DevSet.c_cflag=(DevSet.c_cflag | PARENB);

      /* Clear or set ODD parity check */
      if (Conn.Parity == 'O')
         DevSet.c_cflag=(DevSet.c_cflag | PARODD);
      else
         DevSet.c_cflag=(DevSet.c_cflag & (PARODD^ ALLSET) );
      }
   DevSet.c_cflag=DevSet.c_cflag | CREAD;

   /* Set the speed */
   switch (Conn.Speed) {
         case 1200:
                  DevSet.c_ispeed=B1200;
                  DevSet.c_ospeed=B1200;
                  break;
         case 1800:
                  DevSet.c_ispeed=B1800;
                  DevSet.c_ospeed=B1800;
                  break;
         case 2400:
                  DevSet.c_ispeed=B2400;
                  DevSet.c_ospeed=B2400;
                  break;
         case 4800:
                  DevSet.c_ispeed=B4800;
                  DevSet.c_ospeed=B4800;
                  break;
         case 9600:
                  DevSet.c_ispeed=B9600;
                  DevSet.c_ospeed=B9600;
                  break;
         case 19200:
                  DevSet.c_ispeed=B19200;
                  DevSet.c_ospeed=B19200;
                  break;
         case 38400:
                  DevSet.c_ispeed=B38400;
                  DevSet.c_ospeed=B38400;
                  break;
         case 115200:
                  DevSet.c_ispeed=B115200;
                  DevSet.c_ospeed=B115200;
                  break;
         }

   if (tcsetattr(CommDev, TCSANOW, &DevSet) != 0) {
      fprintf(stderr," ERROR setting options of serial link (%s) error = %d\n",
                     Conn.DevName, errno);
      exit(-1);
      }
}
Received on Fri Oct 31 1997 - 22:48:12 NZDT

This archive was generated by hypermail 2.4.0 : Wed Nov 08 2023 - 11:53:37 NZDT