From f48a67b31781ad6059e36e5aed04fc6406c1e3a9 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 16 Aug 2013 20:44:38 +0200 Subject: Issue #18756: Improve error reporting in os.urandom() when the failure is due to something else than /dev/urandom not existing. --- Lib/test/test_os.py | 18 ++++++++++++++++++ Misc/NEWS | 4 ++++ Python/random.c | 8 ++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index bdbeb01..ccc58d4 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -10,6 +10,10 @@ import sys import signal import subprocess import time +try: + import resource +except ImportError: + resource = None from test import test_support import mmap @@ -563,6 +567,20 @@ class URandomTests (unittest.TestCase): data2 = self.get_urandom_subprocess(16) self.assertNotEqual(data1, data2) + @unittest.skipUnless(resource, "test requires the resource module") + def test_urandom_failure(self): + soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE) + resource.setrlimit(resource.RLIMIT_NOFILE, (1, hard_limit)) + try: + with self.assertRaises(OSError) as cm: + os.urandom(16) + self.assertEqual(cm.exception.errno, errno.EMFILE) + finally: + # We restore the old limit as soon as possible. If doing it + # using addCleanup(), code running in between would fail + # creating any file descriptor. + resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit)) + def test_execvpe_with_bad_arglist(self): self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) diff --git a/Misc/NEWS b/Misc/NEWS index 2aad9bb..e5101f5 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -29,6 +29,10 @@ Core and Builtins Library ------- +- Issue #18756: Improve error reporting in os.urandom() when the failure + is due to something else than /dev/urandom not existing (for example, + exhausting the file descriptor limit). + - Fix tkinter regression introduced by the security fix in issue #16248. - Issue #18676: Change 'positive' to 'non-negative' in queue.py put and get diff --git a/Python/random.c b/Python/random.c index 825260f..73e3cc3 100644 --- a/Python/random.c +++ b/Python/random.c @@ -165,8 +165,12 @@ dev_urandom_python(char *buffer, Py_ssize_t size) Py_END_ALLOW_THREADS if (fd < 0) { - PyErr_SetString(PyExc_NotImplementedError, - "/dev/urandom (or equivalent) not found"); + if (errno == ENOENT || errno == ENXIO || + errno == ENODEV || errno == EACCES) + PyErr_SetString(PyExc_NotImplementedError, + "/dev/urandom (or equivalent) not found"); + else + PyErr_SetFromErrno(PyExc_OSError); return -1; } -- cgit v0.12