select call does block unless data arrives at socket (when waiting for serial port and ip socket)

Stefan Mahr dac922@gmx.de
Wed Sep 29 22:29:00 GMT 2004


Hi...

I want to use select() to wait for a serial port and a ip socket.
Following problem:
If data arrives the serial port, select() works as aspected and returns 1.
If data arrives the ip socket, select() doesn't return.
If data arrives the serial port and before there was some data at the ip 
socket,
select() returns 2. Both file descriptors are set in "fd_set input", and 
all data
can be read by the next functions.

I am using the cygwin1.dll  version 1.5.11 with Windows XP.
(The same problem with previous versions of cygwin1.dll.)

Thanks for help.
Stefan



Sample sourcecode:
/*********************************************/

/* ipserial.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

/*****************************************************************************/ 

#define HOSTNAME "localhost"
#define HOSTMODEPORT 5000
#define MAXDATASIZE 256
#define SERIALPORT "com5"

/*****************************************************************************/ 

int open_port(void)
{
 int fd;

 fd = open(SERIALPORT, O_RDWR | O_NOCTTY);
 if (fd == -1) {
   perror("open serial port");
 } else
   fcntl(fd, F_SETFL, 0);

 return (fd);
}

/*****************************************************************************/ 

int init_port(int fd)
{
 struct termios options;

 tcgetattr(fd, &options);

 cfsetispeed(&options, B19200);
 cfsetospeed(&options, B19200);

 options.c_cflag |= (CLOCAL | CREAD);
 options.c_cflag &= ~CSTOPB;
 options.c_cflag &= ~CRTSCTS;
 options.c_iflag &= ~(IXON | IXOFF | IXANY);

 //cfmakeraw(&options);
 options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
 options.c_oflag &= ~OPOST;
 options.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
 options.c_cflag &= ~(CSIZE|PARENB);
 options.c_cflag |= CS8;

 options.c_cc[VMIN]  = 0;
 options.c_cc[VTIME] = 10;

 tcsetattr(fd, TCSANOW, &options);

 return(0);
}

/*****************************************************************************/ 

int main(void)
{
 int err;
 int numbytes;

 char serialbuf[MAXDATASIZE];
 char socketbuf[MAXDATASIZE];

 int            serialfd,socketfd;
 int            max_fd;
 fd_set         input;

 struct hostent *he;
 struct sockaddr_in their_addr;

 if ((he=gethostbyname(HOSTNAME)) == NULL) {
     perror("gethostbyname");
     exit(1);
 }
 if ((socketfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
     perror("socket");
     exit(1);
 }

 their_addr.sin_family = AF_INET;
 their_addr.sin_port = htons(HOSTMODEPORT);
 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 memset(&(their_addr.sin_zero), '\0', 8);

 if (connect(socketfd, (struct sockaddr *)&their_addr,sizeof(struct 
sockaddr)) == -1) {
     perror("connect");
     exit(1);
 }

 serialfd = open_port();
 err = init_port(serialfd);

 while (1) {

   FD_ZERO(&input);
   FD_SET(socketfd,&input);
   FD_SET(serialfd,&input);

   max_fd = (socketfd > serialfd ? socketfd : serialfd);

   err = select(max_fd+1, &input, NULL, NULL, NULL);
     if (err) {

     if (FD_ISSET(serialfd,&input)) {
             if ((numbytes=read(serialfd, serialbuf, MAXDATASIZE-1)) < 0) {
           perror("read serial");
           exit(1);
       }
       if (send(socketfd,serialbuf,numbytes,0) == -1) {
           perror("send socket");
           exit(1);
       }

     }
         if (FD_ISSET(socketfd,&input)) {
             if ((numbytes=recv(socketfd, socketbuf, MAXDATASIZE-1, 0)) 
== -1) {
           perror("recv socket");
           exit(1);
       }
       if (write(serialfd, socketbuf, numbytes) < 0) {
           perror("write serial");
           exit(1);
       }

      }
       }

 }

 close(serialfd);
 close(socketfd);

 return(0);
}


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list