|
18 | 18 | #include "pycore_fileutils.h" // _Py_closerange()
|
19 | 19 | #include "pycore_import.h" // _PyImport_ReInitLock()
|
20 | 20 | #include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
|
| 21 | +#include "pycore_long.h" // _PyLong_IsNegative() |
21 | 22 | #include "pycore_moduleobject.h" // _PyModule_GetState()
|
22 | 23 | #include "pycore_object.h" // _PyObject_LookupSpecial()
|
23 | 24 | #include "pycore_pylifecycle.h" // _PyOS_URandom()
|
@@ -967,16 +968,46 @@ _Py_Gid_Converter(PyObject *obj, gid_t *p)
|
967 | 968 | #endif /* MS_WINDOWS */
|
968 | 969 |
|
969 | 970 |
|
970 |
| -#define _PyLong_FromDev PyLong_FromLongLong |
| 971 | +static PyObject * |
| 972 | +_PyLong_FromDev(dev_t dev) |
| 973 | +{ |
| 974 | +#ifdef NODEV |
| 975 | + if (dev == NODEV) { |
| 976 | + return PyLong_FromLongLong((long long)dev); |
| 977 | + } |
| 978 | +#endif |
| 979 | + return PyLong_FromUnsignedLongLong((unsigned long long)dev); |
| 980 | +} |
971 | 981 |
|
972 | 982 |
|
973 | 983 | #if (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) || defined(HAVE_DEVICE_MACROS)
|
974 | 984 | static int
|
975 | 985 | _Py_Dev_Converter(PyObject *obj, void *p)
|
976 | 986 | {
|
977 |
| - *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); |
978 |
| - if (PyErr_Occurred()) |
| 987 | +#ifdef NODEV |
| 988 | + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { |
| 989 | + int overflow; |
| 990 | + long long result = PyLong_AsLongLongAndOverflow(obj, &overflow); |
| 991 | + if (result == -1 && PyErr_Occurred()) { |
| 992 | + return 0; |
| 993 | + } |
| 994 | + if (!overflow && result == (long long)NODEV) { |
| 995 | + *((dev_t *)p) = NODEV; |
| 996 | + return 1; |
| 997 | + } |
| 998 | + } |
| 999 | +#endif |
| 1000 | + |
| 1001 | + unsigned long long result = PyLong_AsUnsignedLongLong(obj); |
| 1002 | + if (result == (unsigned long long)-1 && PyErr_Occurred()) { |
| 1003 | + return 0; |
| 1004 | + } |
| 1005 | + if ((unsigned long long)(dev_t)result != result) { |
| 1006 | + PyErr_SetString(PyExc_OverflowError, |
| 1007 | + "Python int too large to convert to C dev_t"); |
979 | 1008 | return 0;
|
| 1009 | + } |
| 1010 | + *((dev_t *)p) = (dev_t)result; |
980 | 1011 | return 1;
|
981 | 1012 | }
|
982 | 1013 | #endif /* (HAVE_MKNOD && HAVE_MAKEDEV) || HAVE_DEVICE_MACROS */
|
@@ -12517,55 +12548,82 @@ os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
|
12517 | 12548 | #endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
|
12518 | 12549 |
|
12519 | 12550 |
|
| 12551 | +static PyObject * |
| 12552 | +major_minor_conv(unsigned int value) |
| 12553 | +{ |
| 12554 | +#ifdef NODEV |
| 12555 | + if (value == (unsigned int)NODEV) { |
| 12556 | + return PyLong_FromLong((int)NODEV); |
| 12557 | + } |
| 12558 | +#endif |
| 12559 | + return PyLong_FromUnsignedLong(value); |
| 12560 | +} |
| 12561 | + |
| 12562 | +static int |
| 12563 | +major_minor_check(dev_t value) |
| 12564 | +{ |
| 12565 | +#ifdef NODEV |
| 12566 | + if (value == NODEV) { |
| 12567 | + return 1; |
| 12568 | + } |
| 12569 | +#endif |
| 12570 | + return (dev_t)(unsigned int)value == value; |
| 12571 | +} |
| 12572 | + |
12520 | 12573 | #ifdef HAVE_DEVICE_MACROS
|
12521 | 12574 | /*[clinic input]
|
12522 |
| -os.major -> unsigned_int |
| 12575 | +os.major |
12523 | 12576 |
|
12524 | 12577 | device: dev_t
|
12525 | 12578 | /
|
12526 | 12579 |
|
12527 | 12580 | Extracts a device major number from a raw device number.
|
12528 | 12581 | [clinic start generated code]*/
|
12529 | 12582 |
|
12530 |
| -static unsigned int |
| 12583 | +static PyObject * |
12531 | 12584 | os_major_impl(PyObject *module, dev_t device)
|
12532 |
| -/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/ |
| 12585 | +/*[clinic end generated code: output=4071ffee17647891 input=b1a0a14ec9448229]*/ |
12533 | 12586 | {
|
12534 |
| - return major(device); |
| 12587 | + return major_minor_conv(major(device)); |
12535 | 12588 | }
|
12536 | 12589 |
|
12537 | 12590 |
|
12538 | 12591 | /*[clinic input]
|
12539 |
| -os.minor -> unsigned_int |
| 12592 | +os.minor |
12540 | 12593 |
|
12541 | 12594 | device: dev_t
|
12542 | 12595 | /
|
12543 | 12596 |
|
12544 | 12597 | Extracts a device minor number from a raw device number.
|
12545 | 12598 | [clinic start generated code]*/
|
12546 | 12599 |
|
12547 |
| -static unsigned int |
| 12600 | +static PyObject * |
12548 | 12601 | os_minor_impl(PyObject *module, dev_t device)
|
12549 |
| -/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/ |
| 12602 | +/*[clinic end generated code: output=306cb78e3bc5004f input=2f686e463682a9da]*/ |
12550 | 12603 | {
|
12551 |
| - return minor(device); |
| 12604 | + return major_minor_conv(minor(device)); |
12552 | 12605 | }
|
12553 | 12606 |
|
12554 | 12607 |
|
12555 | 12608 | /*[clinic input]
|
12556 | 12609 | os.makedev -> dev_t
|
12557 | 12610 |
|
12558 |
| - major: int |
12559 |
| - minor: int |
| 12611 | + major: dev_t |
| 12612 | + minor: dev_t |
12560 | 12613 | /
|
12561 | 12614 |
|
12562 | 12615 | Composes a raw device number from the major and minor device numbers.
|
12563 | 12616 | [clinic start generated code]*/
|
12564 | 12617 |
|
12565 | 12618 | static dev_t
|
12566 |
| -os_makedev_impl(PyObject *module, int major, int minor) |
12567 |
| -/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/ |
| 12619 | +os_makedev_impl(PyObject *module, dev_t major, dev_t minor) |
| 12620 | +/*[clinic end generated code: output=cad6125c51f5af80 input=2146126ec02e55c1]*/ |
12568 | 12621 | {
|
| 12622 | + if (!major_minor_check(major) || !major_minor_check(minor)) { |
| 12623 | + PyErr_SetString(PyExc_OverflowError, |
| 12624 | + "Python int too large to convert to C unsigned int"); |
| 12625 | + return (dev_t)-1; |
| 12626 | + } |
12569 | 12627 | return makedev(major, minor);
|
12570 | 12628 | }
|
12571 | 12629 | #endif /* HAVE_DEVICE_MACROS */
|
|
0 commit comments