summaryrefslogtreecommitdiffstats
path: root/libnetdata/socket/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/socket/socket.c')
-rw-r--r--libnetdata/socket/socket.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/libnetdata/socket/socket.c b/libnetdata/socket/socket.c
index eb8e3a93da..dd36da105e 100644
--- a/libnetdata/socket/socket.c
+++ b/libnetdata/socket/socket.c
@@ -1,5 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-or-later
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE // for POLLRDHUP
+#endif
+
+#ifndef __BSD_VISIBLE
+#define __BSD_VISIBLE // for POLLRDHUP
+#endif
+
#include "../libnetdata.h"
// --------------------------------------------------------------------------------------------------------------------
@@ -11,6 +19,46 @@
#define LARGE_SOCK_SIZE 4096
#endif
+bool fd_is_socket(int fd) {
+ int type;
+ socklen_t len = sizeof(type);
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len) == -1)
+ return false;
+
+ return true;
+}
+
+bool sock_has_output_error(int fd) {
+ if(fd < 0) {
+ //internal_error(true, "invalid socket %d", fd);
+ return false;
+ }
+
+// if(!fd_is_socket(fd)) {
+// //internal_error(true, "fd %d is not a socket", fd);
+// return false;
+// }
+
+ short int errors = POLLERR | POLLHUP | POLLNVAL;
+
+#ifdef POLLRDHUP
+ errors |= POLLRDHUP;
+#endif
+
+ struct pollfd pfd = {
+ .fd = fd,
+ .events = POLLOUT | errors,
+ .revents = 0,
+ };
+
+ if(poll(&pfd, 1, 0) == -1) {
+ //internal_error(true, "poll() failed");
+ return false;
+ }
+
+ return ((pfd.revents & errors) || !(pfd.revents & POLLOUT));
+}
+
int sock_setnonblock(int fd) {
int flags;