|
19 | 19 | #include "pycore_fileutils.h" // _Py_closerange()
|
20 | 20 | #include "pycore_import.h" // _PyImport_ReInitLock()
|
21 | 21 | #include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
|
| 22 | +#include "pycore_long.h" // _PyLong_IsNegative() |
22 | 23 | #include "pycore_moduleobject.h" // _PyModule_GetState()
|
23 | 24 | #include "pycore_object.h" // _PyObject_LookupSpecial()
|
24 | 25 | #include "pycore_pystate.h" // _PyInterpreterState_GET()
|
@@ -920,16 +921,46 @@ _Py_Gid_Converter(PyObject *obj, gid_t *p)
|
920 | 921 | #endif /* MS_WINDOWS */
|
921 | 922 |
|
922 | 923 |
|
923 |
| -#define _PyLong_FromDev PyLong_FromLongLong |
| 924 | +static PyObject * |
| 925 | +_PyLong_FromDev(dev_t dev) |
| 926 | +{ |
| 927 | +#ifdef NODEV |
| 928 | + if (dev == NODEV) { |
| 929 | + return PyLong_FromLongLong((long long)dev); |
| 930 | + } |
| 931 | +#endif |
| 932 | + return PyLong_FromUnsignedLongLong((unsigned long long)dev); |
| 933 | +} |
924 | 934 |
|
925 | 935 |
|
926 | 936 | #if (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) || defined(HAVE_DEVICE_MACROS)
|
927 | 937 | static int
|
928 | 938 | _Py_Dev_Converter(PyObject *obj, void *p)
|
929 | 939 | {
|
930 |
| - *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); |
931 |
| - if (PyErr_Occurred()) |
| 940 | +#ifdef NODEV |
| 941 | + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { |
| 942 | + int overflow; |
| 943 | + long long result = PyLong_AsLongLongAndOverflow(obj, &overflow); |
| 944 | + if (result == -1 && PyErr_Occurred()) { |
| 945 | + return 0; |
| 946 | + } |
| 947 | + if (!overflow && result == (long long)NODEV) { |
| 948 | + *((dev_t *)p) = NODEV; |
| 949 | + return 1; |
| 950 | + } |
| 951 | + } |
| 952 | +#endif |
| 953 | + |
| 954 | + unsigned long long result = PyLong_AsUnsignedLongLong(obj); |
| 955 | + if (result == (unsigned long long)-1 && PyErr_Occurred()) { |
| 956 | + return 0; |
| 957 | + } |
| 958 | + if ((unsigned long long)(dev_t)result != result) { |
| 959 | + PyErr_SetString(PyExc_OverflowError, |
| 960 | + "Python int too large to convert to C dev_t"); |
932 | 961 | return 0;
|
| 962 | + } |
| 963 | + *((dev_t *)p) = (dev_t)result; |
933 | 964 | return 1;
|
934 | 965 | }
|
935 | 966 | #endif /* (HAVE_MKNOD && HAVE_MAKEDEV) || HAVE_DEVICE_MACROS */
|
@@ -11752,55 +11783,82 @@ os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
|
11752 | 11783 | #endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
|
11753 | 11784 |
|
11754 | 11785 |
|
| 11786 | +static PyObject * |
| 11787 | +major_minor_conv(unsigned int value) |
| 11788 | +{ |
| 11789 | +#ifdef NODEV |
| 11790 | + if (value == (unsigned int)NODEV) { |
| 11791 | + return PyLong_FromLong((int)NODEV); |
| 11792 | + } |
| 11793 | +#endif |
| 11794 | + return PyLong_FromUnsignedLong(value); |
| 11795 | +} |
| 11796 | + |
| 11797 | +static int |
| 11798 | +major_minor_check(dev_t value) |
| 11799 | +{ |
| 11800 | +#ifdef NODEV |
| 11801 | + if (value == NODEV) { |
| 11802 | + return 1; |
| 11803 | + } |
| 11804 | +#endif |
| 11805 | + return (dev_t)(unsigned int)value == value; |
| 11806 | +} |
| 11807 | + |
11755 | 11808 | #ifdef HAVE_DEVICE_MACROS
|
11756 | 11809 | /*[clinic input]
|
11757 |
| -os.major -> unsigned_int |
| 11810 | +os.major |
11758 | 11811 |
|
11759 | 11812 | device: dev_t
|
11760 | 11813 | /
|
11761 | 11814 |
|
11762 | 11815 | Extracts a device major number from a raw device number.
|
11763 | 11816 | [clinic start generated code]*/
|
11764 | 11817 |
|
11765 |
| -static unsigned int |
| 11818 | +static PyObject * |
11766 | 11819 | os_major_impl(PyObject *module, dev_t device)
|
11767 |
| -/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/ |
| 11820 | +/*[clinic end generated code: output=4071ffee17647891 input=b1a0a14ec9448229]*/ |
11768 | 11821 | {
|
11769 |
| - return major(device); |
| 11822 | + return major_minor_conv(major(device)); |
11770 | 11823 | }
|
11771 | 11824 |
|
11772 | 11825 |
|
11773 | 11826 | /*[clinic input]
|
11774 |
| -os.minor -> unsigned_int |
| 11827 | +os.minor |
11775 | 11828 |
|
11776 | 11829 | device: dev_t
|
11777 | 11830 | /
|
11778 | 11831 |
|
11779 | 11832 | Extracts a device minor number from a raw device number.
|
11780 | 11833 | [clinic start generated code]*/
|
11781 | 11834 |
|
11782 |
| -static unsigned int |
| 11835 | +static PyObject * |
11783 | 11836 | os_minor_impl(PyObject *module, dev_t device)
|
11784 |
| -/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/ |
| 11837 | +/*[clinic end generated code: output=306cb78e3bc5004f input=2f686e463682a9da]*/ |
11785 | 11838 | {
|
11786 |
| - return minor(device); |
| 11839 | + return major_minor_conv(minor(device)); |
11787 | 11840 | }
|
11788 | 11841 |
|
11789 | 11842 |
|
11790 | 11843 | /*[clinic input]
|
11791 | 11844 | os.makedev -> dev_t
|
11792 | 11845 |
|
11793 |
| - major: int |
11794 |
| - minor: int |
| 11846 | + major: dev_t |
| 11847 | + minor: dev_t |
11795 | 11848 | /
|
11796 | 11849 |
|
11797 | 11850 | Composes a raw device number from the major and minor device numbers.
|
11798 | 11851 | [clinic start generated code]*/
|
11799 | 11852 |
|
11800 | 11853 | static dev_t
|
11801 |
| -os_makedev_impl(PyObject *module, int major, int minor) |
11802 |
| -/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/ |
| 11854 | +os_makedev_impl(PyObject *module, dev_t major, dev_t minor) |
| 11855 | +/*[clinic end generated code: output=cad6125c51f5af80 input=2146126ec02e55c1]*/ |
11803 | 11856 | {
|
| 11857 | + if (!major_minor_check(major) || !major_minor_check(minor)) { |
| 11858 | + PyErr_SetString(PyExc_OverflowError, |
| 11859 | + "Python int too large to convert to C unsigned int"); |
| 11860 | + return (dev_t)-1; |
| 11861 | + } |
11804 | 11862 | return makedev(major, minor);
|
11805 | 11863 | }
|
11806 | 11864 | #endif /* HAVE_DEVICE_MACROS */
|
|
0 commit comments