summaryrefslogtreecommitdiff
path: root/src/udev/udev-ctrl.c
diff options
context:
space:
mode:
authorRichard Yao <ryao@gentoo.org>2012-11-18 02:15:16 -0500
committerRichard Yao <ryao@cs.stonybrook.edu>2012-12-08 09:48:07 -0500
commitbfc850a01b7ba1d961e2f32550c6871ddef909d9 (patch)
tree3757dcc0bd26a21588ed91f00abf767022b167c6 /src/udev/udev-ctrl.c
parent551346ef4d0afc9a376762ac7cb70121c12be920 (diff)
Add fallback path when accept4() is not available.
Commit ff2c503df091e6e4e9ab48cdb6df6ec8b7b525d0 introduced accept4() into udev, which broke compatibility with kernels older than Linux 2.6.32 (or Linux 2.6.36 on ARM). The purpose of accept4() is to permit O_NONBLOCK and O_CLOEXEC to be specified at the accept() call site while previously, they had to be set using fcntl() because Linux does not inherit them. Since accept4() increases the minimum kernel version, we add a fallback path for situations in which it is unavailable. Reported-by: Stephen Klimaszewski <steev@gentoo.org> Signed-off-by: Richard Yao <ryao@gentoo.org>
Diffstat (limited to 'src/udev/udev-ctrl.c')
-rw-r--r--src/udev/udev-ctrl.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index a235912ffb..c0c3fe5ae7 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -10,6 +10,7 @@
*/
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -188,7 +189,28 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl)
conn->refcount = 1;
conn->uctrl = uctrl;
+#if HAVE_DECL_ACCEPT4
conn->sock = accept4(uctrl->sock, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK);
+
+ /* Fallback path when accept4() is unavailable */
+ if ( conn->sock < 0 && (errno == ENOSYS || errno == ENOTSUP) )
+ {
+ conn->sock = accept(uctrl->sock, NULL, NULL);
+
+ if (conn->sock >= 0) {
+ fcntl(conn->sock, F_SETFL, O_NONBLOCK);
+ fcntl(conn->sock, F_SETFD, FD_CLOEXEC);
+ }
+ }
+#else
+ conn->sock = accept(uctrl->sock, NULL, NULL);
+
+ if (conn->sock >= 0) {
+ fcntl(conn->sock, F_SETFL, O_NONBLOCK);
+ fcntl(conn->sock, F_SETFD, FD_CLOEXEC);
+ }
+#endif
+
if (conn->sock < 0) {
if (errno != EINTR)
log_error("unable to receive ctrl connection: %m\n");