Kaydet (Commit) 66150f7c authored tarafından Chris Sinchok's avatar Chris Sinchok Kaydeden (comit) Tim Graham

Fixed #27954 -- Allowed keyboard interrupt to abort queries in PostgreSQL dbshell.

Thanks Tim Martin for review.
üst 7bbb5161
import os
import signal
import subprocess
from django.core.files.temp import NamedTemporaryFile
......@@ -34,6 +35,7 @@ class DatabaseClient(BaseDatabaseClient):
args += [dbname]
temp_pgpass = None
sigint_handler = signal.getsignal(signal.SIGINT)
try:
if passwd:
# Create temporary .pgpass file.
......@@ -54,8 +56,12 @@ class DatabaseClient(BaseDatabaseClient):
# If the current locale can't encode the data, we let
# the user input the password manually.
pass
# Allow SIGINT to pass to psql to abort queries.
signal.signal(signal.SIGINT, signal.SIG_IGN)
subprocess.check_call(args)
finally:
# Restore the orignal SIGINT handler.
signal.signal(signal.SIGINT, sigint_handler)
if temp_pgpass:
temp_pgpass.close()
if 'PGPASSFILE' in os.environ: # unit tests need cleanup
......
import os
import signal
from unittest import mock
from django.db.backends.postgresql.client import DatabaseClient
......@@ -99,3 +100,17 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase):
pgpass_string,
)
)
def test_sigint_handler(self):
"""SIGINT is ignored in Python and passed to psql to abort quries."""
def _mock_subprocess_call(*args):
handler = signal.getsignal(signal.SIGINT)
self.assertEqual(handler, signal.SIG_IGN)
sigint_handler = signal.getsignal(signal.SIGINT)
# The default handler isn't SIG_IGN.
self.assertNotEqual(sigint_handler, signal.SIG_IGN)
with mock.patch('subprocess.check_call', new=_mock_subprocess_call):
DatabaseClient.runshell_db({})
# dbshell restores the orignal handler.
self.assertEqual(sigint_handler, signal.getsignal(signal.SIGINT))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment