From: godot AT uni-paderborn DOT de (Frank Baumgart) Subject: pl19: serial communication via COM1: 3 Mar 1998 05:08:48 -0800 Message-ID: <34FB4DA5.7672437D.cygnus.gnu-win32@uni-paderborn.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------C813F10E372EC4054DC38A89" To: gnu-win32 AT cygnus DOT com This is a multi-part message in MIME format. --------------C813F10E372EC4054DC38A89 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The attached program fails with cygwin32 pl19 as follows: (see strace-output-attachment also) - nonblocking mode does not seem to be set (1) after select() (see below) returns, read() is called but blocks - if we try to read more data than is available - if no data is available though select() supposes so - select() does not time out correctly (2) Even with no input from the read-fd(s) available, time out does not occur, instead, select() returns 1 as if data was available. As strace shows, the file descriptor is considered as follows: "cygwin32_select: added fd 3 to always_read" which is wrong, even in non-blocking mode. fhandler.cc/h shows no special case for "COMx:"/"AUX:" "files" (well, devices), defaulting to a handler returning 1 meaning always_read. I do not know how to fix this but I hope this information is sufficient. (Sergey, could you please make a binary cygwin19.dll with patches available, I do have difficulties to build the dll myself) - alarm (which should show predictable behaviour while not used around a select() call) does not "fire", when read() blocks. (3) - (not demonstrated here) when trying to set communication parameters with tcsetattr(), cygwin fails with "no tty device" (no quote, just sense); CYGWIN32 does not contain the term "tty", though setting "tty" does not make any difference. (I think it is just for console handling anyway?) Interestingly, strace shows that isatty(fd) returns true. nb.: this program works with HP-UX 10.20 and Linux 2.0/2.1 libc5 my environment: - cygwin32 pl19 has been installed as a cross compiler on a Linux machine running 2.0.33/2.1.84 with libc 5.4.33 - the executables are exported via samba to the NT 4.0 SP3 machine - output is examined with "vnc" (allows to display/work with a Win'95/NT screen on a (UNIX)/X11 machine - something like WinDD I think, just free but slow) - there is no old pl18 around --------------C813F10E372EC4054DC38A89 Content-Type: text/plain; charset=us-ascii; name="modem.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="modem.c" /* modem - serial communication test program connect a modem to COM1: and invoke with "modem at-command" or "modem" godot AT uni-paderborn DOT de (Frank Baumgart), 03.03.1998 */ #define DEBUG 1 #include #include #include #include #include #include #include #include #include #if defined(hpux) #include #include #include #endif void set_baudrate(int fd,long rate); void modem_read_answer(int fd); void alarm_handler(int); #if defined(WINNT) #define PORT "COM1:" #elif defined(hpux) #define PORT "/dev/tty0p0" #else #define PORT "/dev/cua0" #endif int main(int argc,char *argv[]) { int fd; fd = open(PORT,O_RDWR | O_NONBLOCK); /* (1) */ if (fd < 0) { printf("can not open device %s\n",PORT); return 1; } #if 0 // fails using tc[sg]etattr() complaining about "no tty device" set_baudrate(fd,B38400); #endif if (argc == 2) { puts(argv[1]); write(fd,argv[1],strlen(argv[1])); write(fd,"\r\n",2); } else { puts("AT&V"); write(fd,"AT&V\r\n",6); } sleep(1); modem_read_answer(fd); return 0; } void modem_read_answer(int fd) { fd_set rset; struct timeval tv; int ret; do { FD_ZERO(&rset); FD_SET(fd,&rset); /* timeout after 3 s */ tv.tv_sec = 3; tv.tv_usec = 0; ret = select(fd+1,&rset,NULL,NULL,&tv); /* (2) */ #if DEBUG // show, that select() does return 1 even if no data is available // and a timeout should occur printf("select = %d\n",ret); // even if a timeout should occur, the timeout value // in tv remains 3 s + 0 us. // (yes, I know this is Linux specific behaviour, considered bad etc.; // just checking for a workaround) printf("s:u = %ld:%ld\n",tv.tv_sec,tv.tv_usec); #endif if (ret && FD_ISSET(fd,&rset)) { long bytes; char answer[100]; // alarm never fires when read() blocks (3) signal(SIGALRM,alarm_handler); alarm(5); #if DEBUG printf("\nread: "); fflush(stdout); #endif // reading less than 4 bytes (trigger level) per read() results // in data loss using HP-UX 10.20; no problem with HP-UX 9.x // (just a side note) bytes = read(fd,answer,20); #if DEBUG printf("%ld\n",bytes); #endif if (bytes < 0) { puts("read error!"); return; } if (bytes == 0) { // NEVER reached when data was ONCE available. // Only when deleting the sleep() statement far above and given, // the modem does not answer until the first read/select, which // is likely, read() returns 0 puts("no data?!"); return; } write(0,answer,bytes); } else { // never happens with cygwin32pl19 puts("timeout!"); return; } } while (1); } void alarm_handler(int dummy) { // never gets called with cygwin32pl19 puts("alarm!"); } --------------C813F10E372EC4054DC38A89-- - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".