Problem with reading nonblocking /dev/com in 1.7.10 and up

Abdul Muis muis@ui.ac.id
Tue Apr 10 18:17:00 GMT 2012


I have notice that I could not read serial device (/dev/com4 or
/dev/ttyS3) with non blocking mode since 1.7.10 and up. I used to read
serial data while doing openGL visualization. In which, the openGL
display was not changed due to blocking mode reading.

The command is

fcntl(fd, F_SETFL, FNDELAY); // set reading as non blocking mode, should
return '0' if no data comming
n=read(fd, &test, 10); // starting from 1.7.10 always return -1 although
there is incoming data

There is no problem with blocking mode, the program can read incoming data
fcntl(fd, F_SETFL, 0); // blocking mode
n=read(fd, &test, 10); // the program will stop here until incoming data
arrived

Before reporting this bug, I have tested in Windows 7 32bit, Windows 7
64bit.
luckily I have several cygwin version in different folder.
I have tested the program in version 1.7.9, 1.7.10, 1.7.11, and current
version 1.7.13 at both 32bit and 64bit Windows7.
The program can read in non blocking mode only in 1.7.9
In addition, although I compiled the program in 1.7.10 and put
cygwin1.dll (ver. 1.7.9) in the same folder, the program could read in
non blocking mode too. So, I suspect the bug is in cygwin1.dll in
version 1.7.10 and up.
Unfortunately, if I compiled the program in 1.7.11 and 1.7.13 then used
cygwin1.dll (ver. 1.7.9) the program stuck.

I notice in version 1.7.10, there are additional API_MINOR changed
(/usr/include/cygwin/version.h)

238: Export pthread_spin_destroy, pthread_spin_init, pthread_spin_lock,
pthread_spin_trylock, pthread_spin_unlock.
239: Export pthread_setschedprio.
240: Export ppoll.
241: Export pthread_attr_getstack, pthread_attr_getstackaddr,
pthread_getattr_np.
242: Export psiginfo, psignal, sys_siglist.
243: Export sysinfo.
244: Export clock_settime.
245: Export pthread_attr_getguardsize, pthread_attr_setguardsize,
pthread_attr_setstack, pthread_attr_setstackaddr.
246: Add CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID.
Export clock_getcpuclockid, pthread_getcpuclockid.
247: Export error, error_at_line, error_message_count, error_one_per_line,
error_print_progname.
248: Export __fpurge.
249: Export pthread_condattr_getclock, pthread_condattr_setclock.
250: Export clock_nanosleep.
251: RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND added.
252: CW_CVT_ENV_TO_WINENV added.
253: Export TIOCSCTTY, tcgetsid.
254: Export getgrouplist.
255: Export ptsname_r.
256: Add CW_ALLOC_DRIVE_MAP, CW_MAP_DRIVE_MAP, CW_FREE_DRIVE_MAP.
257: Export getpt.
258: Export get_current_dir_name.
259: Export pthread_sigqueue.

I don't know what kind of changed that made non blocking read failed. I
attached the program for testing.
I really hope next version will make it possible again.

Thanks in advanced for all efforts.
Kind regards,
Abdul Muis


-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>			/* File control definitions */
#include <errno.h>			/* Error number definitions */
#include <termios.h>		/* POSIX terminal control definitions */
#include <sys/time.h>

#include <io.h> 

int fd, fser1, fser2;
  
int baud, parity;

int open_port(void) {
	int fd;		// File Descriptor for serial port
	char s[60]="/dev/com4";
	baud=19200;
	parity=0;
	
	printf("Checking communication port : %s\n",s);
	fd = open(s, O_RDWR | O_NOCTTY | O_NDELAY); 
	if(fd == -1) {
		perror("-- Unable to open /dev/com --");
		exit(1);
	}	else {
		fcntl(fd, F_SETFL, 0);
		printf("...Done\n");
	}
	
	return(fd);
}

void init_port(int fd) {
	struct termios configs;
	
	tcgetattr(fd, &configs);
	
	switch(baud) {
		case 9600: baud=B9600;break;
		case 19200: baud=B19200;break;
		case 38400: baud=B38400;break;
		default: baud=B19200;
	}
	cfsetispeed(&configs, baud);
	cfsetospeed(&configs, baud);
	
	// Setting Control Mode
	switch (parity) {
		case 1:  // even parity
			 configs.c_cflag |= PARENB;		// Parity enable
			 configs.c_cflag &= ~PARODD;		// Even Parity
			 break;
		case 2:  // odd parity
			 configs.c_cflag |= PARENB;		// Parity enable
			 configs.c_cflag |= PARODD;		// Even Parity
			 break;
		default : // no parity
			 //configs.c_cflag |= PARENB;		// Parity enable
			 //configs.c_cflag &= ~PARODD;		// Even Parity
			 configs.c_cflag &= ~PARENB;  // Parity disable
	}
	configs.c_cflag &= ~CSTOPB;		// 1 stop bit
	//configs.c_cflag |= CSTOPB;		// 2 stop bit
	configs.c_cflag &= ~CSIZE;
	configs.c_cflag |= CS8;			// 8-bit data
	configs.c_cflag &= ~CRTSCTS;	// Disable hardware flow control
	
	// Setting Local Mode
	configs.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);	//RAW input
	
	// Setting Input mode
	configs.c_iflag |= INPCK;			// Enabling Parity Check
	configs.c_iflag &= ~ISTRIP;			// Disable strip off 8th bit when received
	configs.c_iflag &= ~(IXON | IXOFF | IXANY);	// Disable software flow control
	
	// Setting Output Mode
	configs.c_oflag &= ~OPOST;		// RAW output
	
	// Setting Control chars
	configs.c_cc[VTIME] = 0;		// Timeout in 0.1s, 0 (no timeout)
	configs.c_cc[VMIN] = 0;
	
	tcflush(fd, TCIFLUSH); // clean line
	
	if (tcsetattr(fd, TCSANOW, &configs)!=0) {
		fprintf(stderr, "ERROR ! Unable to write configuration to hardware\n");
	}
}


int main(int argc, char **argv) {
	FILE *fdata;
	int comm, count,n;
	unsigned char i;
	fd_set read_fd;
	struct timeval tv;
  tv.tv_sec=0;
	tv.tv_usec=100;

 	unsigned char test[10];
	
	//Open serial port
	fd = open_port();
	
	//Initialize serial
	init_port(fd);
	
	int fd0, retval;
	struct timeval tv0, tv1;
	
  gettimeofday(&tv0, NULL);
	printf("start reading..\n");
	while(1) {
				gettimeofday(&tv1, NULL);
				fcntl(fd, F_SETFL, FNDELAY);  // set reading as non blocking 
				n=read(fd, &test, 10); // return -1 in version 1.7.10 and up
				if (n>0) {
					printf("%d, ",(tv1.tv_sec-tv0.tv_sec)*1000+(tv1.tv_usec/1000-tv0.tv_usec/1000));
				  printf("read (%d bytes) : ", n);
				  for (i=0;i<n;i++)
				    printf("%x ", test[i]);
				  printf("\n");
				} else
				  printf("%d \n",n);
	}
  close(fd);
	return 0;
}
-------------- next part --------------
--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


More information about the Cygwin mailing list