bpo-41001: Add os.eventfd() (#20930)
Co-authored-by: Kyle Stanley <aeros167@gmail.com>
This commit is contained in:
parent
bbeb2d266d
commit
cd9fed6afb
|
@ -3276,6 +3276,102 @@ features:
|
|||
.. versionadded:: 3.8
|
||||
|
||||
|
||||
.. function:: eventfd(initval[, flags=os.EFD_CLOEXEC])
|
||||
|
||||
Create and return an event file descriptor. The file descriptors supports
|
||||
raw :func:`read` and :func:`write` with a buffer size of 8,
|
||||
:func:`~select.select`, :func:`~select.poll` and similar. See man page
|
||||
:manpage:`eventfd(2)` for more information. By default, the
|
||||
new file descriptor is :ref:`non-inheritable <fd_inheritance>`.
|
||||
|
||||
*initval* is the initial value of the event counter. The initial value
|
||||
must be an 32 bit unsigned integer. Please note that the initial value is
|
||||
limited to a 32 bit unsigned int although the event counter is an unsigned
|
||||
64 bit integer with a maximum value of 2\ :sup:`64`\ -\ 2.
|
||||
|
||||
*flags* can be constructed from :const:`EFD_CLOEXEC`,
|
||||
:const:`EFD_NONBLOCK`, and :const:`EFD_SEMAPHORE`.
|
||||
|
||||
If :const:`EFD_SEMAPHORE` is specified and the event counter is non-zero,
|
||||
:func:`eventfd_read` returns 1 and decrements the counter by one.
|
||||
|
||||
If :const:`EFD_SEMAPHORE` is not specified and the event counter is
|
||||
non-zero, :func:`eventfd_read` returns the current event counter value and
|
||||
resets the counter to zero.
|
||||
|
||||
If the event counter is zero and :const:`EFD_NONBLOCK` is not
|
||||
specified, :func:`eventfd_read` blocks.
|
||||
|
||||
:func:`eventfd_write` increments the event counter. Write blocks if the
|
||||
write operation would increment the counter to a value larger than
|
||||
2\ :sup:`64`\ -\ 2.
|
||||
|
||||
Example::
|
||||
|
||||
import os
|
||||
|
||||
# semaphore with start value '1'
|
||||
fd = os.eventfd(1, os.EFD_SEMAPHORE | os.EFC_CLOEXEC)
|
||||
try:
|
||||
# acquire semaphore
|
||||
v = os.eventfd_read(fd)
|
||||
try:
|
||||
do_work()
|
||||
finally:
|
||||
# release semaphore
|
||||
os.eventfd_write(fd, v)
|
||||
finally:
|
||||
os.close(fd)
|
||||
|
||||
.. availability:: Linux 2.6.27 or newer with glibc 2.8 or newer.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. function:: eventfd_read(fd)
|
||||
|
||||
Read value from an :func:`eventfd` file descriptor and return a 64 bit
|
||||
unsigned int. The function does not verify that *fd* is an :func:`eventfd`.
|
||||
|
||||
.. availability:: See :func:`eventfd`
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. function:: eventfd_write(fd, value)
|
||||
|
||||
Add value to an :func:`eventfd` file descriptor. *value* must be a 64 bit
|
||||
unsigned int. The function does not verify that *fd* is an :func:`eventfd`.
|
||||
|
||||
.. availability:: See :func:`eventfd`
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. data:: EFD_CLOEXEC
|
||||
|
||||
Set close-on-exec flag for new :func:`eventfd` file descriptor.
|
||||
|
||||
.. availability:: See :func:`eventfd`
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. data:: EFD_NONBLOCK
|
||||
|
||||
Set :const:`O_NONBLOCK` status flag for new :func:`eventfd` file
|
||||
descriptor.
|
||||
|
||||
.. availability:: See :func:`eventfd`
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
.. data:: EFD_SEMAPHORE
|
||||
|
||||
Provide semaphore-like semantics for reads from a :func:`eventfd` file
|
||||
descriptor. On read the internal counter is decremented by one.
|
||||
|
||||
.. availability:: Linux 2.6.30 or newer with glibc 2.8 or newer.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
|
||||
Linux extended attributes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -229,6 +229,10 @@ os
|
|||
Added :func:`os.cpu_count()` support for VxWorks RTOS.
|
||||
(Contributed by Peixing Xin in :issue:`41440`.)
|
||||
|
||||
Added a new function :func:`os.eventfd` and related helpers to wrap the
|
||||
``eventfd2`` syscall on Linux.
|
||||
(Contributed by Christian Heimes in :issue:`41001`.)
|
||||
|
||||
py_compile
|
||||
----------
|
||||
|
||||
|
|
|
@ -15,10 +15,12 @@ import locale
|
|||
import mmap
|
||||
import os
|
||||
import pickle
|
||||
import select
|
||||
import shutil
|
||||
import signal
|
||||
import socket
|
||||
import stat
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
|
@ -59,6 +61,7 @@ try:
|
|||
except ImportError:
|
||||
INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
|
||||
|
||||
|
||||
from test.support.script_helper import assert_python_ok
|
||||
from test.support import unix_shell
|
||||
from test.support.os_helper import FakePath
|
||||
|
@ -3528,6 +3531,89 @@ class MemfdCreateTests(unittest.TestCase):
|
|||
self.assertFalse(os.get_inheritable(fd2))
|
||||
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'eventfd'), 'requires os.eventfd')
|
||||
@support.requires_linux_version(2, 6, 30)
|
||||
class EventfdTests(unittest.TestCase):
|
||||
def test_eventfd_initval(self):
|
||||
def pack(value):
|
||||
"""Pack as native uint64_t
|
||||
"""
|
||||
return struct.pack("@Q", value)
|
||||
size = 8 # read/write 8 bytes
|
||||
initval = 42
|
||||
fd = os.eventfd(initval)
|
||||
self.assertNotEqual(fd, -1)
|
||||
self.addCleanup(os.close, fd)
|
||||
self.assertFalse(os.get_inheritable(fd))
|
||||
|
||||
# test with raw read/write
|
||||
res = os.read(fd, size)
|
||||
self.assertEqual(res, pack(initval))
|
||||
|
||||
os.write(fd, pack(23))
|
||||
res = os.read(fd, size)
|
||||
self.assertEqual(res, pack(23))
|
||||
|
||||
os.write(fd, pack(40))
|
||||
os.write(fd, pack(2))
|
||||
res = os.read(fd, size)
|
||||
self.assertEqual(res, pack(42))
|
||||
|
||||
# test with eventfd_read/eventfd_write
|
||||
os.eventfd_write(fd, 20)
|
||||
os.eventfd_write(fd, 3)
|
||||
res = os.eventfd_read(fd)
|
||||
self.assertEqual(res, 23)
|
||||
|
||||
def test_eventfd_semaphore(self):
|
||||
initval = 2
|
||||
flags = os.EFD_CLOEXEC | os.EFD_SEMAPHORE | os.EFD_NONBLOCK
|
||||
fd = os.eventfd(initval, flags)
|
||||
self.assertNotEqual(fd, -1)
|
||||
self.addCleanup(os.close, fd)
|
||||
|
||||
# semaphore starts has initval 2, two reads return '1'
|
||||
res = os.eventfd_read(fd)
|
||||
self.assertEqual(res, 1)
|
||||
res = os.eventfd_read(fd)
|
||||
self.assertEqual(res, 1)
|
||||
# third read would block
|
||||
with self.assertRaises(BlockingIOError):
|
||||
os.eventfd_read(fd)
|
||||
with self.assertRaises(BlockingIOError):
|
||||
os.read(fd, 8)
|
||||
|
||||
# increase semaphore counter, read one
|
||||
os.eventfd_write(fd, 1)
|
||||
res = os.eventfd_read(fd)
|
||||
self.assertEqual(res, 1)
|
||||
# next read would block, too
|
||||
with self.assertRaises(BlockingIOError):
|
||||
os.eventfd_read(fd)
|
||||
|
||||
def test_eventfd_select(self):
|
||||
flags = os.EFD_CLOEXEC | os.EFD_NONBLOCK
|
||||
fd = os.eventfd(0, flags)
|
||||
self.assertNotEqual(fd, -1)
|
||||
self.addCleanup(os.close, fd)
|
||||
|
||||
# counter is zero, only writeable
|
||||
rfd, wfd, xfd = select.select([fd], [fd], [fd], 0)
|
||||
self.assertEqual((rfd, wfd, xfd), ([], [fd], []))
|
||||
|
||||
# counter is non-zero, read and writeable
|
||||
os.eventfd_write(fd, 23)
|
||||
rfd, wfd, xfd = select.select([fd], [fd], [fd], 0)
|
||||
self.assertEqual((rfd, wfd, xfd), ([fd], [fd], []))
|
||||
self.assertEqual(os.eventfd_read(fd), 23)
|
||||
|
||||
# counter at max, only readable
|
||||
os.eventfd_write(fd, (2**64) - 2)
|
||||
rfd, wfd, xfd = select.select([fd], [fd], [fd], 0)
|
||||
self.assertEqual((rfd, wfd, xfd), ([fd], [], []))
|
||||
os.eventfd_read(fd)
|
||||
|
||||
|
||||
class OSErrorTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
class Str(str):
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Add func:`os.eventfd` to provide a low level interface for Linux's event
|
||||
notification file descriptor.
|
|
@ -7620,6 +7620,134 @@ exit:
|
|||
|
||||
#endif /* defined(HAVE_MEMFD_CREATE) */
|
||||
|
||||
#if defined(HAVE_EVENTFD)
|
||||
|
||||
PyDoc_STRVAR(os_eventfd__doc__,
|
||||
"eventfd($module, /, initval, flags=EFD_CLOEXEC)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Creates and returns an event notification file descriptor.");
|
||||
|
||||
#define OS_EVENTFD_METHODDEF \
|
||||
{"eventfd", (PyCFunction)(void(*)(void))os_eventfd, METH_FASTCALL|METH_KEYWORDS, os_eventfd__doc__},
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_impl(PyObject *module, unsigned int initval, int flags);
|
||||
|
||||
static PyObject *
|
||||
os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"initval", "flags", NULL};
|
||||
static _PyArg_Parser _parser = {NULL, _keywords, "eventfd", 0};
|
||||
PyObject *argsbuf[2];
|
||||
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
|
||||
unsigned int initval;
|
||||
int flags = EFD_CLOEXEC;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyLong_UnsignedInt_Converter(args[0], &initval)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!noptargs) {
|
||||
goto skip_optional_pos;
|
||||
}
|
||||
flags = _PyLong_AsInt(args[1]);
|
||||
if (flags == -1 && PyErr_Occurred()) {
|
||||
goto exit;
|
||||
}
|
||||
skip_optional_pos:
|
||||
return_value = os_eventfd_impl(module, initval, flags);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_EVENTFD) */
|
||||
|
||||
#if defined(HAVE_EVENTFD)
|
||||
|
||||
PyDoc_STRVAR(os_eventfd_read__doc__,
|
||||
"eventfd_read($module, /, fd)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Read eventfd value");
|
||||
|
||||
#define OS_EVENTFD_READ_METHODDEF \
|
||||
{"eventfd_read", (PyCFunction)(void(*)(void))os_eventfd_read, METH_FASTCALL|METH_KEYWORDS, os_eventfd_read__doc__},
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_read_impl(PyObject *module, int fd);
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"fd", NULL};
|
||||
static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_read", 0};
|
||||
PyObject *argsbuf[1];
|
||||
int fd;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = os_eventfd_read_impl(module, fd);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_EVENTFD) */
|
||||
|
||||
#if defined(HAVE_EVENTFD)
|
||||
|
||||
PyDoc_STRVAR(os_eventfd_write__doc__,
|
||||
"eventfd_write($module, /, fd, value)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Write eventfd value.");
|
||||
|
||||
#define OS_EVENTFD_WRITE_METHODDEF \
|
||||
{"eventfd_write", (PyCFunction)(void(*)(void))os_eventfd_write, METH_FASTCALL|METH_KEYWORDS, os_eventfd_write__doc__},
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value);
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"fd", "value", NULL};
|
||||
static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_write", 0};
|
||||
PyObject *argsbuf[2];
|
||||
int fd;
|
||||
unsigned long long value;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyLong_UnsignedLongLong_Converter(args[1], &value)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = os_eventfd_write_impl(module, fd, value);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_EVENTFD) */
|
||||
|
||||
#if (defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL))
|
||||
|
||||
PyDoc_STRVAR(os_get_terminal_size__doc__,
|
||||
|
@ -8884,6 +9012,18 @@ exit:
|
|||
#define OS_MEMFD_CREATE_METHODDEF
|
||||
#endif /* !defined(OS_MEMFD_CREATE_METHODDEF) */
|
||||
|
||||
#ifndef OS_EVENTFD_METHODDEF
|
||||
#define OS_EVENTFD_METHODDEF
|
||||
#endif /* !defined(OS_EVENTFD_METHODDEF) */
|
||||
|
||||
#ifndef OS_EVENTFD_READ_METHODDEF
|
||||
#define OS_EVENTFD_READ_METHODDEF
|
||||
#endif /* !defined(OS_EVENTFD_READ_METHODDEF) */
|
||||
|
||||
#ifndef OS_EVENTFD_WRITE_METHODDEF
|
||||
#define OS_EVENTFD_WRITE_METHODDEF
|
||||
#endif /* !defined(OS_EVENTFD_WRITE_METHODDEF) */
|
||||
|
||||
#ifndef OS_GET_TERMINAL_SIZE_METHODDEF
|
||||
#define OS_GET_TERMINAL_SIZE_METHODDEF
|
||||
#endif /* !defined(OS_GET_TERMINAL_SIZE_METHODDEF) */
|
||||
|
@ -8919,4 +9059,4 @@ exit:
|
|||
#ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
||||
#define OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
||||
#endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */
|
||||
/*[clinic end generated code: output=936f33448cd66ccb input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=49b7ed768242ef7c input=a9049054013a1b77]*/
|
||||
|
|
|
@ -518,6 +518,11 @@ extern char *ctermid_r(char *);
|
|||
# include <linux/memfd.h>
|
||||
#endif
|
||||
|
||||
/* eventfd() */
|
||||
#ifdef HAVE_SYS_EVENTFD_H
|
||||
# include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _Py_MEMORY_SANITIZER
|
||||
# include <sanitizer/msan_interface.h>
|
||||
#endif
|
||||
|
@ -12859,6 +12864,79 @@ os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EVENTFD
|
||||
/*[clinic input]
|
||||
os.eventfd
|
||||
|
||||
initval: unsigned_int
|
||||
flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
|
||||
|
||||
Creates and returns an event notification file descriptor.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
|
||||
/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
|
||||
|
||||
{
|
||||
/* initval is limited to uint32_t, internal counter is uint64_t */
|
||||
int fd;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
fd = eventfd(initval, flags);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (fd == -1) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
return PyLong_FromLong(fd);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
os.eventfd_read
|
||||
|
||||
fd: fildes
|
||||
|
||||
Read eventfd value
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_read_impl(PyObject *module, int fd)
|
||||
/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
|
||||
{
|
||||
eventfd_t value;
|
||||
int result;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result = eventfd_read(fd, &value);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (result == -1) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
return PyLong_FromUnsignedLongLong(value);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
os.eventfd_write
|
||||
|
||||
fd: fildes
|
||||
value: unsigned_long_long
|
||||
|
||||
Write eventfd value.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
|
||||
/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
|
||||
{
|
||||
int result;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result = eventfd_write(fd, value);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (result == -1) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
#endif /* HAVE_EVENTFD */
|
||||
|
||||
/* Terminal size querying */
|
||||
|
||||
PyDoc_STRVAR(TerminalSize_docstring,
|
||||
|
@ -14619,6 +14697,9 @@ static PyMethodDef posix_methods[] = {
|
|||
OS_FSPATH_METHODDEF
|
||||
OS_GETRANDOM_METHODDEF
|
||||
OS_MEMFD_CREATE_METHODDEF
|
||||
OS_EVENTFD_METHODDEF
|
||||
OS_EVENTFD_READ_METHODDEF
|
||||
OS_EVENTFD_WRITE_METHODDEF
|
||||
OS__ADD_DLL_DIRECTORY_METHODDEF
|
||||
OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
||||
OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
||||
|
@ -15127,6 +15208,12 @@ all_ins(PyObject *m)
|
|||
#ifdef MFD_HUGE_16GB
|
||||
if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
|
||||
#endif
|
||||
#endif /* HAVE_MEMFD_CREATE */
|
||||
|
||||
#ifdef HAVE_EVENTFD
|
||||
if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
|
||||
if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
|
||||
if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
@ -15220,6 +15307,10 @@ static const struct have_function {
|
|||
int (*probe)(void);
|
||||
} have_functions[] = {
|
||||
|
||||
#ifdef HAVE_EVENTFD
|
||||
{"HAVE_EVENTFD", NULL},
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FACCESSAT
|
||||
{ "HAVE_FACCESSAT", probe_faccessat },
|
||||
#endif
|
||||
|
|
|
@ -8032,7 +8032,8 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
|
|||
sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
|
||||
libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
|
||||
linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \
|
||||
sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h
|
||||
sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h \
|
||||
sys/mman.h sys/eventfd.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
|
||||
|
@ -12098,6 +12099,36 @@ $as_echo "no" >&6; }
|
|||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for eventfd" >&5
|
||||
$as_echo_n "checking for eventfd... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#ifdef HAVE_SYS_EVENTFD_H
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int x = eventfd(0, EFD_CLOEXEC)
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
$as_echo "#define HAVE_EVENTFD 1" >>confdefs.h
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
# On some systems (eg. FreeBSD 5), we would find a definition of the
|
||||
# functions ctermid_r, setgroups in the library, but no prototype
|
||||
# (e.g. because we use _XOPEN_SOURCE). See whether we can take their
|
||||
|
|
14
configure.ac
14
configure.ac
|
@ -2210,7 +2210,8 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
|
|||
sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
|
||||
libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
|
||||
linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \
|
||||
sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h)
|
||||
sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h \
|
||||
sys/mman.h sys/eventfd.h)
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_MAJOR
|
||||
|
||||
|
@ -3803,6 +3804,17 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|||
[AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(for eventfd)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#ifdef HAVE_SYS_EVENTFD_H
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
]], [[int x = eventfd(0, EFD_CLOEXEC)]])],
|
||||
[AC_DEFINE(HAVE_EVENTFD, 1, Define if you have the 'eventfd' function.)
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
# On some systems (eg. FreeBSD 5), we would find a definition of the
|
||||
# functions ctermid_r, setgroups in the library, but no prototype
|
||||
# (e.g. because we use _XOPEN_SOURCE). See whether we can take their
|
||||
|
|
|
@ -308,6 +308,9 @@
|
|||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#undef HAVE_ERRNO_H
|
||||
|
||||
/* Define if you have the 'eventfd' function. */
|
||||
#undef HAVE_EVENTFD
|
||||
|
||||
/* Define to 1 if you have the `execv' function. */
|
||||
#undef HAVE_EXECV
|
||||
|
||||
|
@ -1119,6 +1122,9 @@
|
|||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
#undef HAVE_SYS_EVENTFD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
#undef HAVE_SYS_EVENT_H
|
||||
|
||||
|
|
Loading…
Reference in New Issue