[Nut-upsdev] [windows port] blazer_ser issues, select_read() from serial semantics

Paul Fertser fercerpav at gmail.com
Mon Sep 19 11:10:47 UTC 2011


I tried using 2.6.1 version for windows with a Megatec-compatible UPS
and was surprised to find out it doesn't work at all.

The reason for that is blazer_ser using ser_get_buf specifying a buffer
large enough to accept any reasonably possible response, setting
buflen accordingly. That calls select_read() and it's supposed to wait
until something is available and then to read up all the data from
port, returning the number of bytes read. But the windows version
apparently differs, the way it's currently implemented it either reads
up to buflen bytes or returns an error indicating a timeout.

I can't say for sure how i'd imagine the correct solution as it seems
to me that even *nix version is currently implemented in a fragile
way, making hidden assumptions that might broke under e.g. a heavy
system load.


Something like this might be appropriate for the windows version (tested
here with our UPSes):

diff --git a/common/wincompat.c b/common/wincompat.c
index 86c786f..f271a3a 100644
--- a/common/wincompat.c
+++ b/common/wincompat.c
@@ -411,12 +411,15 @@ int w32_serial_read (serial_handler_t * sh, void *ptr, size_t ulen, DWORD tim
                                                upsdebugx(4,"w32_serial_read : characters are avail
                                        case WAIT_TIMEOUT:
-                                               CancelIo(sh->handle);
-                                               sh->overlapped_armed = 0;
-                                               ResetEvent (sh->io_status.hEvent);
-                                               upsdebugx(4,"w32_serial_read : timeout %d ms ellaps
-                                               errno = EIO;
-                                               return 0;
+                                               if (!tot) {
+                                                       CancelIo(sh->handle);
+                                                       sh->overlapped_armed = 0;
+                                                       ResetEvent (sh->io_status.hEvent);
+                                                       upsdebugx(4,"w32_serial_read : timeout %d m
+                                                       errno = EIO;
+                                                       return 0;
+                                               }
+                                               break;
                                                goto err;

Be free, use free (http://www.gnu.org/philosophy/free-sw.html) software!
mailto:fercerpav at gmail.com

More information about the Nut-upsdev mailing list