[PATCH]: Fix for errant tcgetattr() behavior
Way back in 02/01/2003, a patch of mine was applied that enhanced tcsetattr() to handle setting baud rate B0 correctly (ie. dropping DTR, leave actual baud rate alone), but added some incorrect behavior in tcgetattr(). The correct behavior, I believe, should be as follows: 1) When a baud rate of B0 is passed to tcsetattr(), it should not change the actual baud rate, but instead drop DTR. 2) In tcgetattr(), the presently set baud rate should be returned, regardless of the state of DTR. My earlier patch broke #2. The attached patch fixes this error, and tcgetattr() now returns the correct baud rate regardless of DTR state. Thanks, -Troy Changelog entry: * fhandler_serial.cc (fhandler_serial::tcgetattr): Make tcgetattr() return current baud rate regardless of current DTR state. --- old_fhandler_serial.cc 2005-08-11 09:31:05.202669500 -0600 +++ new_fhandler_serial.cc 2005-08-11 09:38:36.104522300 -0600 @@ -908,55 +908,50 @@ fhandler_serial::tcgetattr (struct termi memset (t, 0, sizeof (*t)); /* -- Baud rate -- */ - - /* If DTR is NOT set, return B0 as our speed */ - if (dtr != TIOCM_DTR) -t-c_cflag = t-c_ospeed = t-c_ispeed = B0; - else -switch (state.BaudRate) - { - case CBR_110: + switch (state.BaudRate) +{ +case CBR_110: t-c_cflag = t-c_ospeed = t-c_ispeed = B110; break; - case CBR_300: +case CBR_300: t-c_cflag = t-c_ospeed = t-c_ispeed = B300; break; - case CBR_600: +case CBR_600: t-c_cflag = t-c_ospeed = t-c_ispeed = B600; break; - case CBR_1200: +case CBR_1200: t-c_cflag = t-c_ospeed = t-c_ispeed = B1200; break; - case CBR_2400: +case CBR_2400: t-c_cflag = t-c_ospeed = t-c_ispeed = B2400; break; - case CBR_4800: +case CBR_4800: t-c_cflag = t-c_ospeed = t-c_ispeed = B4800; break; - case CBR_9600: +case CBR_9600: t-c_cflag = t-c_ospeed = t-c_ispeed = B9600; break; - case CBR_19200: +case CBR_19200: t-c_cflag = t-c_ospeed = t-c_ispeed = B19200; break; - case CBR_38400: +case CBR_38400: t-c_cflag = t-c_ospeed = t-c_ispeed = B38400; break; - case CBR_57600: +case CBR_57600: t-c_cflag = t-c_ospeed = t-c_ispeed = B57600; break; - case CBR_115200: +case CBR_115200: t-c_cflag = t-c_ospeed = t-c_ispeed = B115200; break; - case 230400: /* CBR_230400 - not defined */ +case 230400: /* CBR_230400 - not defined */ t-c_cflag = t-c_ospeed = t-c_ispeed = B230400; break; - default: +default: /* Unsupported baud rate! */ termios_printf (Invalid baud rate %d, state.BaudRate); set_errno (EINVAL); return -1; - } +} /* -- Byte size -- */
Re: Bug in stty or /dev/ttySx handling code
Hi Peter, That was my patch applied back in 02/01/2003 and upon re-examining it, I believe this is an error. The intended behavior was as follows: 1) When a baud rate of B0 is passed to tcsetattr(), it should not change the actual baud rate, but instead drop DTR. 2) In tcgetattr(), the presently set baud rate should be returned, regardless of the state of DTR. My earlier patch violates #2. I am sending a patch to fix this to cygwin-patches right now (CC'ing you, as well.) Thanks for bringing this to my attention - I don't know what I was thinking that day :) -Troy Hi, I'm seeing problems when I run stty. If I run stty -F /dev/ttyS0, it shows 0 baud. I found this thread from may that has the same issue: http://sourceware.org/ml/cygwin/2005-05/msg00399.html and I found that a patch was applied in 02/01/2003 that seems to prevent setting the baud if the DTR is zero. Why is the baud invalid when DTR is not set? It seems like to me that DTR doesn't/shouldn't have an affect on the reported baud. Can anyone shed some light on this? Thanks, Peter -- 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/
230.4Kbps serial support - patch #2
Chris, This patch rounds out the 230.4Kbps support in fhandler_serial::tcsetattr() - this check probably should have been there all along, but now catches any invalid DCB parameters (ie. trying to set an invalid bitrate for a given port) and returns w/ errno = EINVAL as POSIX dictates. Can you review and check this in before 1.3.19 is released? Thanks, -Troy 2003-01-16 Troy Curtiss [EMAIL PROTECTED] * fhandler_serial.cc (fhandler_serial::tcsetattr): return w/ errno = EINVAL if SetCommState() fails w/ invalid DCB parameter (eg. will catch attempts to set bitrates not supported by a given port.) ser_230k4_patch2 Description: Binary data
Re: [PATCH] 230.4Kbps support for serial port
Christopher, You're right, there is no such thing as CBR_230400 in Win32-land as documented/supported by MS. Simply replace CBR_230400 with 230400 and you won't need to touch winbase.h. Thanks, -Troy - Original Message - From: Christopher Faylor [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Thursday, January 09, 2003 1:21 AM Subject: Re: [PATCH] 230.4Kbps support for serial port On Tue, Jan 07, 2003 at 03:48:51PM -0700, Troy Curtiss wrote: Hi, Attached is a patch that enables cygwin to talk at 230400 bps on serial ports that support the higher rate. It also does the necessary error-checking to confirm whether or not a given port is capable of extended bitrates. I added B230400 (for Posix) and CBR_230400 (for Win32) definitions to the appropriate header files (termios.h and winbase.h, respectively). I've been testing for a couple days now and it appears to work as designed. (We use a lot of extended bitrate devices at work, mostly with Win32 code - so this simply brings the paradigm across to the posix side of the house.) Question: Upon failure (ie. trying to configure a non-230.4K capable port to talk 230.4K), I simply return -1... I'm not sure whether POSIX would set errno = EINVAL or not... either way is fine. Let me know if you have any questions, otherwise it sure would be nice to roll this in if possible :) Thanks, I'll apply this patch (with a reformatted changelog) to cygwin but not to winbase.h. I couldn't find any reference to a CBR_230400 anywhere so it wouldn't be technically correct to a windows header file. Thanks, cgf 2003-01-06 Troy Curtiss [EMAIL PROTECTED] * fhandler_serial.cc (fhandler_serial::tcsetattr): Add support and capability checking for B230400 bitrate. * fhandler_serial.cc (fhandler_serial::tcgetattr): Add support for B230400 bitrate. * /cvs/src/src/winsup/w32api/include/winbase.h: Add CBR_230400 definition for Win32 support of 230.4Kbps. * /cvs/src/src/winsup/cygwin/include/sys/termios.h: Add B230400 definition for Posix support of 230.4Kbps.
Re: [PATCH] 230.4Kbps support for serial port
Christopher, Just looked it up and EINVAL is correct, per the SunOS manpage: EINVAL The optional_actions argument is not a supported value, or an attempt was made to change an attribute represented in the termios structure to an unsup- ported value. -Troy - Original Message - From: Troy Curtiss [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Thursday, January 09, 2003 7:20 PM Subject: Re: [PATCH] 230.4Kbps support for serial port I'm thinking the error should be EINVAL - since the DCB parameter is technically invalid for the given device. Note that the code should probably always check the return of SetCommState() to guard against possibly bad/invalid/incompatible information in the Win32 DCB. Let me know if you'd like me to re-architect my patch to follow the old paradigm (possible doing all the SetComm*() at the bottom of the function?) Thanks, -Troy At 04:45 PM 1/9/2003 -0500, you wrote: On Thu, Jan 09, 2003 at 11:18:31AM -0700, Troy Curtiss wrote: Christopher, I see in the latest fhandler_serial::tcsetattr(), the following part of my patch wasn't applied. This piece is necessary in the event the serial device doesn't actually support 230.4Kbps (so tcsetattr() will return an error instead of simply not working.) This piece short circuits lots of subsequent code, however. It's a departure from the way this function used to work. And it does need to set an errno, as you'd indicated. I don't know what the errno would be, though. cgf @@ -723,8 +726,12 @@ fhandler_serial::tcsetattr (int action, state.fAbortOnError = TRUE; /* -- Set state and exit -- */ - if (memcmp (ostate, state, sizeof (state)) != 0) -SetCommState (get_handle (), state); + if ((memcmp (ostate, state, sizeof (state)) != 0) + !SetCommState (get_handle (), state)) +{ + /* Return now if any of the parameters in the DCB didn't take */ + return -1; +} Thanks, -Troy At 03:21 AM 1/9/2003 -0500, you wrote: On Tue, Jan 07, 2003 at 03:48:51PM -0700, Troy Curtiss wrote: Hi, Attached is a patch that enables cygwin to talk at 230400 bps on serial ports that support the higher rate. It also does the necessary error-checking to confirm whether or not a given port is capable of extended bitrates. I added B230400 (for Posix) and CBR_230400 (for Win32) definitions to the appropriate header files (termios.h and winbase.h, respectively). I've been testing for a couple days now and it appears to work as designed. (We use a lot of extended bitrate devices at work, mostly with Win32 code - so this simply brings the paradigm across to the posix side of the house.) Question: Upon failure (ie. trying to configure a non-230.4K capable port to talk 230.4K), I simply return -1... I'm not sure whether POSIX would set errno = EINVAL or not... either way is fine. Let me know if you have any questions, otherwise it sure would be nice to roll this in if possible :) Thanks, I'll apply this patch (with a reformatted changelog) to cygwin but not to winbase.h. I couldn't find any reference to a CBR_230400 anywhere so it wouldn't be technically correct to a windows header file. Thanks, cgf 2003-01-06 Troy Curtiss [EMAIL PROTECTED] * fhandler_serial.cc (fhandler_serial::tcsetattr): Add support and capability checking for B230400 bitrate. * fhandler_serial.cc (fhandler_serial::tcgetattr): Add support for B230400 bitrate. * /cvs/src/src/winsup/w32api/include/winbase.h: Add CBR_230400 definition for Win32 support of 230.4Kbps. * /cvs/src/src/winsup/cygwin/include/sys/termios.h: Add B230400 definition for Posix support of 230.4Kbps.
open() not handling previously opened serial port gracefully?
Hi, I recently ran into a problem where my cygwin-based program was trying to open a serial port that was already opened by another windows app. Instead of the open() call failing returning -1, the cygwin program dumped stack (tracing w/ gdb indicated that the failure was within the open() call - an access violation of some sort.) I don't remember this happening in the past (but don't have my older cygwin1.dll versions to test with) - can anyone verify this (and thus prove that I'm not doing anything silly at my end :) Thanks, -Troy Using: Windows 2000, cygwin.dll 1.3.14-1 or cygwin.dll 1.3.13-2, seems to only affect serial ports Code is as follows: #include stdio.h #include fcntl.h int main(void) { int fd1,fd2; fd1 = open(COM1,O_RDWR); sleep(1); fd2 = open(COM1,O_RDWR); sleep(1); close(fd2); close(fd1); return(0); } Stackdump is as follows: Exception: STATUS_ACCESS_VIOLATION at eip=61015D6A eax= ebx=0003 ecx= edx= esi=615B0968 edi=4080 ebp=0022FA88 esp=0022FA20 program=C:\projects\tools\xxx.exe cs=001B ds=0023 es=0023 fs=0038 gs= ss=0023 Stack trace: Frame Function Args 0022FA88 61015D6A (615B0968, , 0002, 0094) 0022FB08 61028668 (615B0968, 0022FB40, 0002, 0094) 0022FEB8 61076E61 (00401090, 0002, 0094, 002F) 0022FEE0 004010EB (0001, 0A040330, 0A040288, 0001) 0022FF40 61007288 (610C7A34, FFFE, 002C, 610C7958) 0022FF90 6100753D (, , 80430F47, ) 0022FFB0 004026E2 (00401096, 037F0009, 0022FFF0, 77E9CA90) 0022FFC0 0040103C (, , 7FFDF000, ) 0022FFF0 77E9CA90 (00401000, , 00C8, 0100) End of stack trace -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/