Skip to content

Commit 002a77d

Browse files
committed
Issue python#12181: select module: Fix struct kevent definition on OpenBSD 64-bit
platforms. Patch by Federico Schwindt.
1 parent d08b210 commit 002a77d

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ Core and Builtins
4747
Library
4848
-------
4949

50+
- Issue #12181: select module: Fix struct kevent definition on OpenBSD 64-bit
51+
platforms. Patch by Federico Schwindt.
52+
5053
- Issue #14173: Avoid crashing when reading a signal handler during
5154
interpreter shutdown.
5255

Modules/selectmodule.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,18 +1571,35 @@ static PyTypeObject kqueue_queue_Type;
15711571
# error uintptr_t does not match int, long, or long long!
15721572
#endif
15731573

1574+
/*
1575+
* kevent is not standard and its members vary across BSDs.
1576+
*/
1577+
#if !defined(__OpenBSD__)
1578+
# define IDENT_TYPE T_UINTPTRT
1579+
# define IDENT_CAST Py_intptr_t
1580+
# define DATA_TYPE T_INTPTRT
1581+
# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1582+
# define IDENT_AsType PyLong_AsUintptr_t
1583+
#else
1584+
# define IDENT_TYPE T_UINT
1585+
# define IDENT_CAST int
1586+
# define DATA_TYPE T_INT
1587+
# define DATA_FMT_UNIT "i"
1588+
# define IDENT_AsType PyLong_AsUnsignedLong
1589+
#endif
1590+
15741591
/* Unfortunately, we can't store python objects in udata, because
15751592
* kevents in the kernel can be removed without warning, which would
15761593
* forever lose the refcount on the object stored with it.
15771594
*/
15781595

15791596
#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
15801597
static struct PyMemberDef kqueue_event_members[] = {
1581-
{"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1598+
{"ident", IDENT_TYPE, KQ_OFF(e.ident)},
15821599
{"filter", T_SHORT, KQ_OFF(e.filter)},
15831600
{"flags", T_USHORT, KQ_OFF(e.flags)},
15841601
{"fflags", T_UINT, KQ_OFF(e.fflags)},
1585-
{"data", T_INTPTRT, KQ_OFF(e.data)},
1602+
{"data", DATA_TYPE, KQ_OFF(e.data)},
15861603
{"udata", T_UINTPTRT, KQ_OFF(e.udata)},
15871604
{NULL} /* Sentinel */
15881605
};
@@ -1608,7 +1625,7 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
16081625
PyObject *pfd;
16091626
static char *kwlist[] = {"ident", "filter", "flags", "fflags",
16101627
"data", "udata", NULL};
1611-
static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
1628+
static char *fmt = "O|hhi" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
16121629

16131630
EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
16141631

@@ -1618,8 +1635,12 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
16181635
return -1;
16191636
}
16201637

1621-
if (PyLong_Check(pfd)) {
1622-
self->e.ident = PyLong_AsUintptr_t(pfd);
1638+
if (PyLong_Check(pfd)
1639+
#if IDENT_TYPE == T_UINT
1640+
&& PyLong_AsUnsignedLong(pfd) <= UINT_MAX
1641+
#endif
1642+
) {
1643+
self->e.ident = IDENT_AsType(pfd);
16231644
}
16241645
else {
16251646
self->e.ident = PyObject_AsFileDescriptor(pfd);
@@ -1647,10 +1668,10 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
16471668
Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
16481669
return NULL;
16491670
}
1650-
if (((result = s->e.ident - o->e.ident) == 0) &&
1671+
if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
16511672
((result = s->e.filter - o->e.filter) == 0) &&
16521673
((result = s->e.flags - o->e.flags) == 0) &&
1653-
((result = s->e.fflags - o->e.fflags) == 0) &&
1674+
((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
16541675
((result = s->e.data - o->e.data) == 0) &&
16551676
((result = s->e.udata - o->e.udata) == 0)
16561677
) {

0 commit comments

Comments
 (0)