prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  attach is causing an "Invalid Argument" exception from os.read
  ``` python
  stream = client.attach(container, stream=True, stdout=True, stderr=True)
  for chunk in stream:
      pass
  ```
  
  Results in:
  
  ```
    File "/Users/michael/work/oss/marina/marina/build.py", line 695, in watcher
      for chunk in stream:
    File ".venv/lib/python3.5/site-packages/docker/utils/socket.py", line 67, in frames_iter
      yield read(socket, n)
    File ".venv/lib/python3.5/site-packages/docker/utils/socket.py", line 25, in read
      return os.read(socket.fileno(), n)
  OSError: [Errno 22] Invalid argument
  ```
  
  Using docker-py 1.10.2 on OS X 10.11.6 with docker for mac 1.12.0-rc3. Reverting to 1.9.0 fixes the issue.
  
  
  </issue>
  <code>
  [start of docker/utils/socket.py]
  1 import errno
  2 import os
  3 import select
  4 import struct
  5 
  6 import six
  7 
  8 try:
  9     from ..transport import NpipeSocket
  10 except ImportError:
  11     NpipeSocket = type(None)
  12 
  13 
  14 class SocketError(Exception):
  15     pass
  16 
  17 
  18 def read(socket, n=4096):
  19     """
  20     Reads at most n bytes from socket
  21     """
  22 
  23     recoverable_errors = (errno.EINTR, errno.EDEADLK, errno.EWOULDBLOCK)
  24 
  25     # wait for data to become available
  26     if not isinstance(socket, NpipeSocket):
  27         select.select([socket], [], [])
  28 
  29     try:
  30         if hasattr(socket, 'recv'):
  31             return socket.recv(n)
  32         return os.read(socket.fileno(), n)
  33     except EnvironmentError as e:
  34         if e.errno not in recoverable_errors:
  35             raise
  36 
  37 
  38 def read_exactly(socket, n):
  39     """
  40     Reads exactly n bytes from socket
  41     Raises SocketError if there isn't enough data
  42     """
  43     data = six.binary_type()
  44     while len(data) < n:
  45         next_data = read(socket, n - len(data))
  46         if not next_data:
  47             raise SocketError("Unexpected EOF")
  48         data += next_data
  49     return data
  50 
  51 
  52 def next_frame_size(socket):
  53     """
  54     Returns the size of the next frame of data waiting to be read from socket,
  55     according to the protocol defined here:
  56 
  57     https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/attach-to-a-container
  58     """
  59     try:
  60         data = read_exactly(socket, 8)
  61     except SocketError:
  62         return 0
  63 
  64     _, actual = struct.unpack('>BxxxL', data)
  65     return actual
  66 
  67 
  68 def frames_iter(socket):
  69     """
  70     Returns a generator of frames read from socket
  71     """
  72     n = next_frame_size(socket)
  73     while n > 0:
  74         yield read(socket, n)
  75         n = next_frame_size(socket)
  76
  [end of docker/utils/socket.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/docker/utils/socket.py b/docker/utils/socket.py
  --- a/docker/utils/socket.py
  +++ b/docker/utils/socket.py
  @@ -69,7 +69,11 @@
       """
       Returns a generator of frames read from socket
       """
  -    n = next_frame_size(socket)
  -    while n > 0:
  -        yield read(socket, n)
  +    while True:
           n = next_frame_size(socket)
  +        if n == 0:
  +            break
  +        while n > 0:
  +            result = read(socket, n)
  +            n -= len(result)
  +            yield result
  
verification_info: {"golden_diff": "diff --git a/docker/utils/socket.py b/docker/utils/socket.py\n--- a/docker/utils/socket.py\n+++ b/docker/utils/socket.py\n@@ -69,7 +69,11 @@\n     \"\"\"\n     Returns a generator of frames read from socket\n     \"\"\"\n-    n = next_frame_size(socket)\n-    while n > 0:\n-        yield read(socket, n)\n+    while True:\n         n = next_frame_size(socket)\n+        if n == 0:\n+            break\n+        while n > 0:\n+            result = read(socket, n)\n+            n -= len(result)\n+            yield result\n", "issue": "attach is causing an \"Invalid Argument\" exception from os.read\n``` python\nstream = client.attach(container, stream=True, stdout=True, stderr=True)\nfor chunk in stream:\n    pass\n```\n\nResults in:\n\n```\n  File \"/Users/michael/work/oss/marina/marina/build.py\", line 695, in watcher\n    for chunk in stream:\n  File \".venv/lib/python3.5/site-packages/docker/utils/socket.py\", line 67, in frames_iter\n    yield read(socket, n)\n  File \".venv/lib/python3.5/site-packages/docker/utils/socket.py\", line 25, in read\n    return os.read(socket.fileno(), n)\nOSError: [Errno 22] Invalid argument\n```\n\nUsing docker-py 1.10.2 on OS X 10.11.6 with docker for mac 1.12.0-rc3. Reverting to 1.9.0 fixes the issue.\n\n", "before_files": [{"content": "import errno\nimport os\nimport select\nimport struct\n\nimport six\n\ntry:\n    from ..transport import NpipeSocket\nexcept ImportError:\n    NpipeSocket = type(None)\n\n\nclass SocketError(Exception):\n    pass\n\n\ndef read(socket, n=4096):\n    \"\"\"\n    Reads at most n bytes from socket\n    \"\"\"\n\n    recoverable_errors = (errno.EINTR, errno.EDEADLK, errno.EWOULDBLOCK)\n\n    # wait for data to become available\n    if not isinstance(socket, NpipeSocket):\n        select.select([socket], [], [])\n\n    try:\n        if hasattr(socket, 'recv'):\n            return socket.recv(n)\n        return os.read(socket.fileno(), n)\n    except EnvironmentError as e:\n        if e.errno not in recoverable_errors:\n            raise\n\n\ndef read_exactly(socket, n):\n    \"\"\"\n    Reads exactly n bytes from socket\n    Raises SocketError if there isn't enough data\n    \"\"\"\n    data = six.binary_type()\n    while len(data) < n:\n        next_data = read(socket, n - len(data))\n        if not next_data:\n            raise SocketError(\"Unexpected EOF\")\n        data += next_data\n    return data\n\n\ndef next_frame_size(socket):\n    \"\"\"\n    Returns the size of the next frame of data waiting to be read from socket,\n    according to the protocol defined here:\n\n    https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/attach-to-a-container\n    \"\"\"\n    try:\n        data = read_exactly(socket, 8)\n    except SocketError:\n        return 0\n\n    _, actual = struct.unpack('>BxxxL', data)\n    return actual\n\n\ndef frames_iter(socket):\n    \"\"\"\n    Returns a generator of frames read from socket\n    \"\"\"\n    n = next_frame_size(socket)\n    while n > 0:\n        yield read(socket, n)\n        n = next_frame_size(socket)\n", "path": "docker/utils/socket.py"}]}