#include "poll-loop.h"
#include "util.h"
#include "vlog.h"
-#if AF_PACKET && __linux__
+#if AF_PACKET && LINUX_DATAPATH
#include <linux/if_packet.h>
#endif
#ifdef HAVE_NETLINK
/* #ifdefs make it a pain to maintain code: you have to try to build both ways.
* Thus, this file compiles all of the code regardless of the target, by
- * writing "if (LINUX)" instead of "#ifdef __linux__". */
-#ifdef __linux__
-#define LINUX 1
-#else
-#define LINUX 0
+ * writing "if (LINUX_DATAPATH)" instead of "#ifdef __linux__". */
+#ifndef LINUX_DATAPATH
+#define LINUX_DATAPATH 0
#endif
#ifndef O_DIRECTORY
}
}
-static int
+int
set_dscp(int fd, uint8_t dscp)
{
int val;
: EINVAL);
}
-/* Returns the error condition associated with socket 'fd' and resets the
- * socket's error status. */
-int
-get_socket_error(int fd)
-{
- int error;
-
- if (getsockopt_int(fd, SOL_SOCKET, SO_ERROR, "SO_ERROR", &error)) {
- error = errno;
- }
- return error;
-}
-
int
check_connection_completion(int fd)
{
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10);
struct pollfd pfd;
int retval;
retval = poll(&pfd, 1, 0);
} while (retval < 0 && errno == EINTR);
if (retval == 1) {
- return get_socket_error(fd);
+ if (pfd.revents & POLLERR) {
+ ssize_t n = send(fd, "", 1, MSG_DONTWAIT);
+ if (n < 0) {
+ return errno;
+ } else {
+ VLOG_ERR_RL(&rl, "poll return POLLERR but send succeeded");
+ return EPROTO;
+ }
+ }
+ return 0;
} else if (retval < 0) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10);
VLOG_ERR_RL(&rl, "poll: %s", strerror(errno));
return errno;
} else {
*
* On other Unix-like OSes, MSG_TRUNC has no effect in the flags
* argument. */
- char buffer[LINUX ? 1 : 2048];
+ char buffer[LINUX_DATAPATH ? 1 : 2048];
ssize_t n_bytes = recv(fd, buffer, sizeof buffer,
MSG_TRUNC | MSG_DONTWAIT);
if (n_bytes <= 0 || n_bytes >= rcvbuf) {
if (strlen(name) > MAX_UN_LEN) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
- if (LINUX) {
+ if (LINUX_DATAPATH) {
/* 'name' is too long to fit in a sockaddr_un, but we have a
* workaround for that on Linux: shorten it by opening a file
* descriptor for the directory part of the name and indirecting
}
} else if (fd >= 0) {
close(fd);
+ fd = -1;
}
*fdp = fd;
return error;
}
}
+void
+xpipe_nonblocking(int fds[2])
+{
+ xpipe(fds);
+ xset_nonblocking(fds[0]);
+ xset_nonblocking(fds[1]);
+}
+
void
xsocketpair(int domain, int type, int protocol, int fds[2])
{
}
}
#endif
-#if AF_PACKET && __linux__
+#if AF_PACKET && LINUX_DATAPATH
else if (ss.ss_family == AF_PACKET) {
struct sockaddr_ll sll;
}
-#ifdef __linux__
+#ifdef LINUX_DATAPATH
static void
put_fd_filename(struct ds *string, int fd)
{
: S_ISFIFO(s.st_mode) ? "FIFO"
: S_ISLNK(s.st_mode) ? "symbolic link"
: "unknown"));
-#ifdef __linux__
+#ifdef LINUX_DATAPATH
put_fd_filename(&string, fd);
#endif
}