Skip to content

Commit

Permalink
Address review comments and small refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka committed May 24, 2024
1 parent 395860a commit c0abdbb
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
1 change: 1 addition & 0 deletions Lib/test/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ def test_makedev(self):
NODEV = -1
self.assertEqual(posix.major(NODEV), NODEV)
self.assertEqual(posix.minor(NODEV), NODEV)
self.assertEqual(posix.makedev(NODEV, NODEV), NODEV)

def _test_all_chown_common(self, chown_func, first_param, stat_func):
"""Common code for chown, fchown and lchown tests."""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Fix integer conversion in :func:`os.major`, :func:`os.minor`, and
:func:`os.makedev`. Support device numbers larger than ``2**63-1``. Support
non-existent device number.
non-existent device number (``NODEV``).
47 changes: 25 additions & 22 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -12515,6 +12515,28 @@ os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */


static PyObject *
major_minor_conv(unsigned int value)
{
#ifdef NODEV
if (value == (unsigned int)NODEV) {
return PyLong_FromLong((int)NODEV);
}
#endif
return PyLong_FromUnsignedLong(value);
}

static int
major_minor_check(dev_t value)
{
#ifdef NODEV
if (value == NODEV) {
return 1;
}
#endif
return (dev_t)(unsigned int)value == value;
}

#ifdef HAVE_DEVICE_MACROS
/*[clinic input]
os.major
Expand All @@ -12529,13 +12551,7 @@ static PyObject *
os_major_impl(PyObject *module, dev_t device)
/*[clinic end generated code: output=4071ffee17647891 input=b1a0a14ec9448229]*/
{
unsigned int result = major(device);
#ifdef NODEV
if (result == (unsigned int)NODEV) {
return PyLong_FromLong((int)NODEV);
}
#endif
return PyLong_FromUnsignedLong(result);
return major_minor_conv(major(device));
}


Expand All @@ -12552,13 +12568,7 @@ static PyObject *
os_minor_impl(PyObject *module, dev_t device)
/*[clinic end generated code: output=306cb78e3bc5004f input=2f686e463682a9da]*/
{
unsigned int result = minor(device);
#ifdef NODEV
if (result == (unsigned int)NODEV) {
return PyLong_FromLong((int)NODEV);
}
#endif
return PyLong_FromUnsignedLong(result);
return major_minor_conv(minor(device));
}


Expand All @@ -12576,14 +12586,7 @@ static dev_t
os_makedev_impl(PyObject *module, dev_t major, dev_t minor)
/*[clinic end generated code: output=cad6125c51f5af80 input=2146126ec02e55c1]*/
{
#ifdef NODEV
if ((major != NODEV && (dev_t)(unsigned int)major != major) ||
(minor != NODEV && (dev_t)(unsigned int)minor != minor))
#else
if ((dev_t)(unsigned int)major != major) ||
(dev_t)(unsigned int)minor != minor))
#endif
{
if (!major_minor_check(major) || !major_minor_check(minor)) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C unsigned int");
return (dev_t)-1;
Expand Down

0 comments on commit c0abdbb

Please sign in to comment.