#115 write() bytes written and timeout issue

v1.0 (example)
closed-rejected
nobody
None
5
2014-07-17
2012-01-18
No

I might be wrong about this but it appears to me the write() in serialposix.py reports the wrong number of bytes written. I appear to simply report back the number of bytes passed. I also cannot double-check this because on osx 10.6 (serial .version is 11 2 0) it seems to ignore the timeout altogether.

See code from v2.6 here:

def write(self, data):
    """Output the given string over the serial port."""
    if not self._isOpen: raise portNotOpenError
    t = len(data)
    d = data
    if self._writeTimeout is not None and self._writeTimeout > 0:
        timeout = time.time() + self._writeTimeout
    else:
        timeout = None
    while t > 0:
        try:
            n = os.write(self.fd, d)
            if timeout:
                # when timeout is set, use select to wait for being ready
                # with the time left as timeout
                timeleft = timeout - time.time()
                if timeleft < 0:
                    raise writeTimeoutError
                _, ready, _ = select.select([], [self.fd], [], timeleft)
                if not ready:
                    raise writeTimeoutError
            d = d[n:]
            t = t - n
        except OSError, v:
        if v.errno \!= errno.EAGAIN:
            raise SerialException('write failed: %s' % (v,))
    return len(data)

Discussion

  • Chris Liechti
    Chris Liechti
    2013-10-11

    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -2,31 +2,30 @@
    
     See code from v2.6 here:
     =======================
    -def write\(self, data\):
    -"""Output the given string over the serial port."""
    -if not self.\_isOpen: raise portNotOpenError
    -t = len\(data\)
    -d = data
    -if self.\_writeTimeout is not None and self.\_writeTimeout &gt; 0:
    -timeout = time.time\(\) + self.\_writeTimeout
    -else:
    -timeout = None
    -while t &gt; 0:
    -try:
    -n = os.write\(self.fd, d\)
    -if timeout:
    -\# when timeout is set, use select to wait for being ready
    -\# with the time left as timeout
    -timeleft = timeout - time.time\(\)
    -if timeleft &lt; 0:
    -raise writeTimeoutError
    -\_, ready, \_ = select.select\(\[\], \[self.fd\], \[\], timeleft\)
    -if not ready:
    -raise writeTimeoutError
    -d = d\[n:\]
    -t = t - n
    -except OSError, v:
    -if v.errno \!= errno.EAGAIN:
    -raise SerialException\('write failed: %s' % \(v,\)\)
    -return len\(data\)
    -
    +    def write(self, data):
    +        """Output the given string over the serial port."""
    +        if not self._isOpen: raise portNotOpenError
    +        t = len(data)
    +        d = data
    +        if self._writeTimeout is not None and self._writeTimeout > 0:
    +            timeout = time.time() + self._writeTimeout
    +        else:
    +            timeout = None
    +        while t > 0:
    +            try:
    +                n = os.write(self.fd, d)
    +                if timeout:
    +                    # when timeout is set, use select to wait for being ready
    +                    # with the time left as timeout
    +                    timeleft = timeout - time.time()
    +                    if timeleft < 0:
    +                        raise writeTimeoutError
    +                    _, ready, _ = select.select([], [self.fd], [], timeleft)
    +                    if not ready:
    +                        raise writeTimeoutError
    +                d = d[n:]
    +                t = t - n
    +            except OSError, v:
    +            if v.errno \!= errno.EAGAIN:
    +                raise SerialException('write failed: %s' % (v,))
    +        return len(data)
    
    • status: open --> closed-rejected
    • Group: --> v1.0 (example)
     
  • Chris Liechti
    Chris Liechti
    2013-10-11

    Yes it will always return the total number. If there were a write timeout, that would cause an exception and the return statement is never executed.