Misc fixes
diff --git a/mitmproxy/addons/script.py b/mitmproxy/addons/script.py
index decd07596a..a39ce5ce57 100644
--- a/mitmproxy/addons/script.py
+++ b/mitmproxy/addons/script.py
@@ -148,17 +148,25 @@ def running(self):
     @command.command("script.run")
     def script_run(self, flows: typing.Sequence[flow.Flow], path: mtypes.Path) -> None:
         """
-            Run a script on the specified flows. The script is loaded with
-            default options, and all lifecycle events for each flow are
-            simulated.
+            Run a script on the specified flows. The script is configured with
+            the current options and all lifecycle events for each flow are
+            simulated. Note that the load event is not invoked.
         """
-        try:
-            s = Script(path, False)
-            for f in flows:
-                for evt, arg in eventsequence.iterate(f):
-                    ctx.master.addons.invoke_addon(s, evt, arg)
-        except exceptions.OptionsError as e:
-            script_error_handler(path, e, msg=str(e))
+        if not os.path.isfile(path):
+            ctx.log.error('No such script: %s' % path)
+            return
+        mod = load_script(path)
+        if mod:
+            with addonmanager.safecall():
+                ctx.master.addons.invoke_addon(mod, "running")
+                ctx.master.addons.invoke_addon(
+                    mod,
+                    "configure",
+                    ctx.options.keys()
+                )
+                for f in flows:
+                    for evt, arg in eventsequence.iterate(f):
+                        ctx.master.addons.invoke_addon(mod, evt, arg)
 
     def configure(self, updated):
         if "scripts" in updated:
diff --git a/mitmproxy/controller.py b/mitmproxy/controller.py
index 582a6683f8..6e2190663d 100644
--- a/mitmproxy/controller.py
+++ b/mitmproxy/controller.py
@@ -113,6 +113,8 @@ def ack(self, force=False):
 
     def kill(self, force=False):
         self.send(exceptions.Kill, force)
+        if self._state == "taken":
+            self.commit()
 
     def send(self, msg, force=False):
         if self.state not in {"start", "taken"}:
diff --git a/mitmproxy/net/tcp.py b/mitmproxy/net/tcp.py
index 18429daa6b..2496d47c7b 100644
--- a/mitmproxy/net/tcp.py
+++ b/mitmproxy/net/tcp.py
@@ -1,4 +1,5 @@
 import os
+import errno
 import select
 import socket
 import sys
@@ -585,6 +586,13 @@ def connection_thread(self, connection, client_address):
         with self.handler_counter:
             try:
                 self.handle_client_connection(connection, client_address)
+            except OSError as e:  # pragma: no cover
+                # This catches situations where the underlying connection is
+                # closed beneath us. Syscalls on the connection object at this
+                # point returns EINVAL. If this happens, we close the socket and
+                # move on.
+                if not e.errno == errno.EINVAL:
+                    raise
             except:
                 self.handle_error(connection, client_address)
             finally:
diff --git a/mitmproxy/tools/console/flowlist.py b/mitmproxy/tools/console/flowlist.py
index e6bd1693c3..a9e48af415 100644
--- a/mitmproxy/tools/console/flowlist.py
+++ b/mitmproxy/tools/console/flowlist.py
@@ -39,6 +39,14 @@ class FlowListWalker(urwid.ListWalker):
     def __init__(self, master):
         self.master = master
 
+    def positions(self, reverse=False):
+        # The stub implementation of positions can go once this issue is resolved:
+        # https://github.com/urwid/urwid/issues/294
+        ret = range(len(self.master.view))
+        if reverse:
+            return reversed(ret)
+        return ret
+
     def view_changed(self):
         self._modified()
 
diff --git a/test/mitmproxy/addons/test_script.py b/test/mitmproxy/addons/test_script.py
index 573b36e76b..05472d9a03 100644
--- a/test/mitmproxy/addons/test_script.py
+++ b/test/mitmproxy/addons/test_script.py
@@ -173,16 +173,14 @@ def test_simple(self):
 class TestScriptLoader:
     @pytest.mark.asyncio
     async def test_script_run(self, tdata):
-        rp = tdata.path(
-            "mitmproxy/data/addonscripts/recorder/recorder.py"
-        )
+        rp = tdata.path("mitmproxy/data/addonscripts/recorder/recorder.py")
         sc = script.ScriptLoader()
         with taddons.context(sc) as tctx:
             sc.script_run([tflow.tflow(resp=True)], rp)
             await tctx.master.await_log("recorder response")
             debug = [i.msg for i in tctx.master.logs if i.level == "debug"]
             assert debug == [
-                'recorder load', 'recorder running', 'recorder configure',
+                'recorder running', 'recorder configure',
                 'recorder requestheaders', 'recorder request',
                 'recorder responseheaders', 'recorder response'
             ]
@@ -192,7 +190,7 @@ async def test_script_run_nonexistent(self):
         sc = script.ScriptLoader()
         with taddons.context(sc) as tctx:
             sc.script_run([tflow.tflow(resp=True)], "/")
-            assert await tctx.master.await_log("/: No such script")
+            assert await tctx.master.await_log("No such script")
 
     def test_simple(self, tdata):
         sc = script.ScriptLoader()
