We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Close stdin for processes called from qutebrowser
When running this as userscript:

```bash
#!/bin/bash
buku --debug --add "$QUTE_URL"
echo "message-info 'Bookmark added to Buku!'" >> "$QUTE_FIFO"
```

[buku](https://github.com/jarun/Buku) just hangs, without producing any output (not even when adding `&> /tmp/buku.log` to the `buku` call).

Running `QUTE_URL=https://www.example.com/ ./buku.sh` works fine though, and every other python application I've seen so far works...

@jarun - do you have any idea what could be going wrong here?

cc @Chinggis6

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `qutebrowser/misc/guiprocess.py`
Content:
```
1 # vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
2 
3 # Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
4 #
5 # This file is part of qutebrowser.
6 #
7 # qutebrowser is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # qutebrowser is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.
19 
20 """A QProcess which shows notifications in the GUI."""
21 
22 import shlex
23 
24 from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,
25                           QProcessEnvironment)
26 
27 from qutebrowser.utils import message, log
28 
29 # A mapping of QProcess::ErrorCode's to human-readable strings.
30 
31 ERROR_STRINGS = {
32     QProcess.FailedToStart: "The process failed to start.",
33     QProcess.Crashed: "The process crashed.",
34     QProcess.Timedout: "The last waitFor...() function timed out.",
35     QProcess.WriteError: ("An error occurred when attempting to write to the "
36                           "process."),
37     QProcess.ReadError: ("An error occurred when attempting to read from the "
38                          "process."),
39     QProcess.UnknownError: "An unknown error occurred.",
40 }
41 
42 
43 class GUIProcess(QObject):
44 
45     """An external process which shows notifications in the GUI.
46 
47     Args:
48         cmd: The command which was started.
49         args: A list of arguments which gets passed.
50         verbose: Whether to show more messages.
51         _started: Whether the underlying process is started.
52         _proc: The underlying QProcess.
53         _what: What kind of thing is spawned (process/editor/userscript/...).
54                Used in messages.
55 
56     Signals:
57         error/finished/started signals proxied from QProcess.
58     """
59 
60     error = pyqtSignal(QProcess.ProcessError)
61     finished = pyqtSignal(int, QProcess.ExitStatus)
62     started = pyqtSignal()
63 
64     def __init__(self, what, *, verbose=False, additional_env=None,
65                  parent=None):
66         super().__init__(parent)
67         self._what = what
68         self.verbose = verbose
69         self._started = False
70         self.cmd = None
71         self.args = None
72 
73         self._proc = QProcess(self)
74         self._proc.error.connect(self.on_error)
75         self._proc.error.connect(self.error)
76         self._proc.finished.connect(self.on_finished)
77         self._proc.finished.connect(self.finished)
78         self._proc.started.connect(self.on_started)
79         self._proc.started.connect(self.started)
80 
81         if additional_env is not None:
82             procenv = QProcessEnvironment.systemEnvironment()
83             for k, v in additional_env.items():
84                 procenv.insert(k, v)
85             self._proc.setProcessEnvironment(procenv)
86 
87     @pyqtSlot(QProcess.ProcessError)
88     def on_error(self, error):
89         """Show a message if there was an error while spawning."""
90         msg = ERROR_STRINGS[error]
91         message.error("Error while spawning {}: {}".format(self._what, msg))
92 
93     @pyqtSlot(int, QProcess.ExitStatus)
94     def on_finished(self, code, status):
95         """Show a message when the process finished."""
96         self._started = False
97         log.procs.debug("Process finished with code {}, status {}.".format(
98             code, status))
99         if status == QProcess.CrashExit:
100             message.error("{} crashed!".format(self._what.capitalize()))
101         elif status == QProcess.NormalExit and code == 0:
102             if self.verbose:
103                 message.info("{} exited successfully.".format(
104                     self._what.capitalize()))
105         else:
106             assert status == QProcess.NormalExit
107             # We call this 'status' here as it makes more sense to the user -
108             # it's actually 'code'.
109             message.error("{} exited with status {}.".format(
110                 self._what.capitalize(), code))
111 
112             stderr = bytes(self._proc.readAllStandardError()).decode('utf-8')
113             stdout = bytes(self._proc.readAllStandardOutput()).decode('utf-8')
114             if stdout:
115                 log.procs.error("Process stdout:\n" + stdout.strip())
116             if stderr:
117                 log.procs.error("Process stderr:\n" + stderr.strip())
118 
119     @pyqtSlot()
120     def on_started(self):
121         """Called when the process started successfully."""
122         log.procs.debug("Process started.")
123         assert not self._started
124         self._started = True
125 
126     def _pre_start(self, cmd, args):
127         """Prepare starting of a QProcess."""
128         if self._started:
129             raise ValueError("Trying to start a running QProcess!")
130         self.cmd = cmd
131         self.args = args
132         fake_cmdline = ' '.join(shlex.quote(e) for e in [cmd] + list(args))
133         log.procs.debug("Executing: {}".format(fake_cmdline))
134         if self.verbose:
135             message.info('Executing: ' + fake_cmdline)
136 
137     def start(self, cmd, args, mode=None):
138         """Convenience wrapper around QProcess::start."""
139         log.procs.debug("Starting process.")
140         self._pre_start(cmd, args)
141         if mode is None:
142             self._proc.start(cmd, args)
143         else:
144             self._proc.start(cmd, args, mode)
145 
146     def start_detached(self, cmd, args, cwd=None):
147         """Convenience wrapper around QProcess::startDetached."""
148         log.procs.debug("Starting detached.")
149         self._pre_start(cmd, args)
150         ok, _pid = self._proc.startDetached(cmd, args, cwd)
151 
152         if ok:
153             log.procs.debug("Process started.")
154             self._started = True
155         else:
156             message.error("Error while spawning {}: {}.".format(
157                 self._what, self._proc.error()))
158 
159     def exit_status(self):
160         return self._proc.exitStatus()
161
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py
--- a/qutebrowser/misc/guiprocess.py
+++ b/qutebrowser/misc/guiprocess.py
@@ -142,6 +142,7 @@
             self._proc.start(cmd, args)
         else:
             self._proc.start(cmd, args, mode)
+        self._proc.closeWriteChannel()
 
     def start_detached(self, cmd, args, cwd=None):
         """Convenience wrapper around QProcess::startDetached."""

{"golden_diff": "diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py\n--- a/qutebrowser/misc/guiprocess.py\n+++ b/qutebrowser/misc/guiprocess.py\n@@ -142,6 +142,7 @@\n             self._proc.start(cmd, args)\n         else:\n             self._proc.start(cmd, args, mode)\n+        self._proc.closeWriteChannel()\n \n     def start_detached(self, cmd, args, cwd=None):\n         \"\"\"Convenience wrapper around QProcess::startDetached.\"\"\"\n", "issue": "Close stdin for processes called from qutebrowser\nWhen running this as userscript:\r\n\r\n```bash\r\n#!/bin/bash\r\nbuku --debug --add \"$QUTE_URL\"\r\necho \"message-info 'Bookmark added to Buku!'\" >> \"$QUTE_FIFO\"\r\n```\r\n\r\n[buku](https://github.com/jarun/Buku) just hangs, without producing any output (not even when adding `&> /tmp/buku.log` to the `buku` call).\r\n\r\nRunning `QUTE_URL=https://www.example.com/ ./buku.sh` works fine though, and every other python application I've seen so far works...\r\n\r\n@jarun - do you have any idea what could be going wrong here?\r\n\r\ncc @Chinggis6\n", "before_files": [{"content": "# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:\n\n# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>\n#\n# This file is part of qutebrowser.\n#\n# qutebrowser is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# qutebrowser is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.\n\n\"\"\"A QProcess which shows notifications in the GUI.\"\"\"\n\nimport shlex\n\nfrom PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,\n                          QProcessEnvironment)\n\nfrom qutebrowser.utils import message, log\n\n# A mapping of QProcess::ErrorCode's to human-readable strings.\n\nERROR_STRINGS = {\n    QProcess.FailedToStart: \"The process failed to start.\",\n    QProcess.Crashed: \"The process crashed.\",\n    QProcess.Timedout: \"The last waitFor...() function timed out.\",\n    QProcess.WriteError: (\"An error occurred when attempting to write to the \"\n                          \"process.\"),\n    QProcess.ReadError: (\"An error occurred when attempting to read from the \"\n                         \"process.\"),\n    QProcess.UnknownError: \"An unknown error occurred.\",\n}\n\n\nclass GUIProcess(QObject):\n\n    \"\"\"An external process which shows notifications in the GUI.\n\n    Args:\n        cmd: The command which was started.\n        args: A list of arguments which gets passed.\n        verbose: Whether to show more messages.\n        _started: Whether the underlying process is started.\n        _proc: The underlying QProcess.\n        _what: What kind of thing is spawned (process/editor/userscript/...).\n               Used in messages.\n\n    Signals:\n        error/finished/started signals proxied from QProcess.\n    \"\"\"\n\n    error = pyqtSignal(QProcess.ProcessError)\n    finished = pyqtSignal(int, QProcess.ExitStatus)\n    started = pyqtSignal()\n\n    def __init__(self, what, *, verbose=False, additional_env=None,\n                 parent=None):\n        super().__init__(parent)\n        self._what = what\n        self.verbose = verbose\n        self._started = False\n        self.cmd = None\n        self.args = None\n\n        self._proc = QProcess(self)\n        self._proc.error.connect(self.on_error)\n        self._proc.error.connect(self.error)\n        self._proc.finished.connect(self.on_finished)\n        self._proc.finished.connect(self.finished)\n        self._proc.started.connect(self.on_started)\n        self._proc.started.connect(self.started)\n\n        if additional_env is not None:\n            procenv = QProcessEnvironment.systemEnvironment()\n            for k, v in additional_env.items():\n                procenv.insert(k, v)\n            self._proc.setProcessEnvironment(procenv)\n\n    @pyqtSlot(QProcess.ProcessError)\n    def on_error(self, error):\n        \"\"\"Show a message if there was an error while spawning.\"\"\"\n        msg = ERROR_STRINGS[error]\n        message.error(\"Error while spawning {}: {}\".format(self._what, msg))\n\n    @pyqtSlot(int, QProcess.ExitStatus)\n    def on_finished(self, code, status):\n        \"\"\"Show a message when the process finished.\"\"\"\n        self._started = False\n        log.procs.debug(\"Process finished with code {}, status {}.\".format(\n            code, status))\n        if status == QProcess.CrashExit:\n            message.error(\"{} crashed!\".format(self._what.capitalize()))\n        elif status == QProcess.NormalExit and code == 0:\n            if self.verbose:\n                message.info(\"{} exited successfully.\".format(\n                    self._what.capitalize()))\n        else:\n            assert status == QProcess.NormalExit\n            # We call this 'status' here as it makes more sense to the user -\n            # it's actually 'code'.\n            message.error(\"{} exited with status {}.\".format(\n                self._what.capitalize(), code))\n\n            stderr = bytes(self._proc.readAllStandardError()).decode('utf-8')\n            stdout = bytes(self._proc.readAllStandardOutput()).decode('utf-8')\n            if stdout:\n                log.procs.error(\"Process stdout:\\n\" + stdout.strip())\n            if stderr:\n                log.procs.error(\"Process stderr:\\n\" + stderr.strip())\n\n    @pyqtSlot()\n    def on_started(self):\n        \"\"\"Called when the process started successfully.\"\"\"\n        log.procs.debug(\"Process started.\")\n        assert not self._started\n        self._started = True\n\n    def _pre_start(self, cmd, args):\n        \"\"\"Prepare starting of a QProcess.\"\"\"\n        if self._started:\n            raise ValueError(\"Trying to start a running QProcess!\")\n        self.cmd = cmd\n        self.args = args\n        fake_cmdline = ' '.join(shlex.quote(e) for e in [cmd] + list(args))\n        log.procs.debug(\"Executing: {}\".format(fake_cmdline))\n        if self.verbose:\n            message.info('Executing: ' + fake_cmdline)\n\n    def start(self, cmd, args, mode=None):\n        \"\"\"Convenience wrapper around QProcess::start.\"\"\"\n        log.procs.debug(\"Starting process.\")\n        self._pre_start(cmd, args)\n        if mode is None:\n            self._proc.start(cmd, args)\n        else:\n            self._proc.start(cmd, args, mode)\n\n    def start_detached(self, cmd, args, cwd=None):\n        \"\"\"Convenience wrapper around QProcess::startDetached.\"\"\"\n        log.procs.debug(\"Starting detached.\")\n        self._pre_start(cmd, args)\n        ok, _pid = self._proc.startDetached(cmd, args, cwd)\n\n        if ok:\n            log.procs.debug(\"Process started.\")\n            self._started = True\n        else:\n            message.error(\"Error while spawning {}: {}.\".format(\n                self._what, self._proc.error()))\n\n    def exit_status(self):\n        return self._proc.exitStatus()\n", "path": "qutebrowser/misc/guiprocess.py"}], "after_files": [{"content": "# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:\n\n# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>\n#\n# This file is part of qutebrowser.\n#\n# qutebrowser is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# qutebrowser is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.\n\n\"\"\"A QProcess which shows notifications in the GUI.\"\"\"\n\nimport shlex\n\nfrom PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,\n                          QProcessEnvironment)\n\nfrom qutebrowser.utils import message, log\n\n# A mapping of QProcess::ErrorCode's to human-readable strings.\n\nERROR_STRINGS = {\n    QProcess.FailedToStart: \"The process failed to start.\",\n    QProcess.Crashed: \"The process crashed.\",\n    QProcess.Timedout: \"The last waitFor...() function timed out.\",\n    QProcess.WriteError: (\"An error occurred when attempting to write to the \"\n                          \"process.\"),\n    QProcess.ReadError: (\"An error occurred when attempting to read from the \"\n                         \"process.\"),\n    QProcess.UnknownError: \"An unknown error occurred.\",\n}\n\n\nclass GUIProcess(QObject):\n\n    \"\"\"An external process which shows notifications in the GUI.\n\n    Args:\n        cmd: The command which was started.\n        args: A list of arguments which gets passed.\n        verbose: Whether to show more messages.\n        _started: Whether the underlying process is started.\n        _proc: The underlying QProcess.\n        _what: What kind of thing is spawned (process/editor/userscript/...).\n               Used in messages.\n\n    Signals:\n        error/finished/started signals proxied from QProcess.\n    \"\"\"\n\n    error = pyqtSignal(QProcess.ProcessError)\n    finished = pyqtSignal(int, QProcess.ExitStatus)\n    started = pyqtSignal()\n\n    def __init__(self, what, *, verbose=False, additional_env=None,\n                 parent=None):\n        super().__init__(parent)\n        self._what = what\n        self.verbose = verbose\n        self._started = False\n        self.cmd = None\n        self.args = None\n\n        self._proc = QProcess(self)\n        self._proc.error.connect(self.on_error)\n        self._proc.error.connect(self.error)\n        self._proc.finished.connect(self.on_finished)\n        self._proc.finished.connect(self.finished)\n        self._proc.started.connect(self.on_started)\n        self._proc.started.connect(self.started)\n\n        if additional_env is not None:\n            procenv = QProcessEnvironment.systemEnvironment()\n            for k, v in additional_env.items():\n                procenv.insert(k, v)\n            self._proc.setProcessEnvironment(procenv)\n\n    @pyqtSlot(QProcess.ProcessError)\n    def on_error(self, error):\n        \"\"\"Show a message if there was an error while spawning.\"\"\"\n        msg = ERROR_STRINGS[error]\n        message.error(\"Error while spawning {}: {}\".format(self._what, msg))\n\n    @pyqtSlot(int, QProcess.ExitStatus)\n    def on_finished(self, code, status):\n        \"\"\"Show a message when the process finished.\"\"\"\n        self._started = False\n        log.procs.debug(\"Process finished with code {}, status {}.\".format(\n            code, status))\n        if status == QProcess.CrashExit:\n            message.error(\"{} crashed!\".format(self._what.capitalize()))\n        elif status == QProcess.NormalExit and code == 0:\n            if self.verbose:\n                message.info(\"{} exited successfully.\".format(\n                    self._what.capitalize()))\n        else:\n            assert status == QProcess.NormalExit\n            # We call this 'status' here as it makes more sense to the user -\n            # it's actually 'code'.\n            message.error(\"{} exited with status {}.\".format(\n                self._what.capitalize(), code))\n\n            stderr = bytes(self._proc.readAllStandardError()).decode('utf-8')\n            stdout = bytes(self._proc.readAllStandardOutput()).decode('utf-8')\n            if stdout:\n                log.procs.error(\"Process stdout:\\n\" + stdout.strip())\n            if stderr:\n                log.procs.error(\"Process stderr:\\n\" + stderr.strip())\n\n    @pyqtSlot()\n    def on_started(self):\n        \"\"\"Called when the process started successfully.\"\"\"\n        log.procs.debug(\"Process started.\")\n        assert not self._started\n        self._started = True\n\n    def _pre_start(self, cmd, args):\n        \"\"\"Prepare starting of a QProcess.\"\"\"\n        if self._started:\n            raise ValueError(\"Trying to start a running QProcess!\")\n        self.cmd = cmd\n        self.args = args\n        fake_cmdline = ' '.join(shlex.quote(e) for e in [cmd] + list(args))\n        log.procs.debug(\"Executing: {}\".format(fake_cmdline))\n        if self.verbose:\n            message.info('Executing: ' + fake_cmdline)\n\n    def start(self, cmd, args, mode=None):\n        \"\"\"Convenience wrapper around QProcess::start.\"\"\"\n        log.procs.debug(\"Starting process.\")\n        self._pre_start(cmd, args)\n        if mode is None:\n            self._proc.start(cmd, args)\n        else:\n            self._proc.start(cmd, args, mode)\n        self._proc.closeWriteChannel()\n\n    def start_detached(self, cmd, args, cwd=None):\n        \"\"\"Convenience wrapper around QProcess::startDetached.\"\"\"\n        log.procs.debug(\"Starting detached.\")\n        self._pre_start(cmd, args)\n        ok, _pid = self._proc.startDetached(cmd, args, cwd)\n\n        if ok:\n            log.procs.debug(\"Process started.\")\n            self._started = True\n        else:\n            message.error(\"Error while spawning {}: {}.\".format(\n                self._what, self._proc.error()))\n\n    def exit_status(self):\n        return self._proc.exitStatus()\n", "path": "qutebrowser/misc/guiprocess.py"}]}