Project

General

Profile

Actions

Bug #862

closed

1.4.3: src/unix-manager.c: Solaris doesn't define MSG_NOSIGNAL or SO_NOSIGPIPE

Added by Mark Solaris almost 11 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
Affected Versions:
Effort:
Difficulty:
Label:

Description

Solaris doesn't have MSG_NOSIGNAL or SO_NOSIGPIPE so the UnixCommandSendCallback() function in src/unix-manager.c won't compile.

After reading these links I've created the diff below. It compiles but I haven't finished porting suricata yet to test if it works :D

http://krokisplace.blogspot.com.au/2010/02/suppressing-sigpipe-in-library.html
https://groups.google.com/forum/?fromgroups#!topic/comp.unix.programmer/Spk9NrhSMPk

--- suricata-1.4.3/src/unix-manager.c.orig      Mon Jul  8 12:20:13 2013
+++ suricata-1.4.3/src/unix-manager.c   Mon Jul  8 15:30:49 2013
@@ -41,11 +41,11 @@
 #include <jansson.h>

 // MSG_NOSIGNAL does not exists on OS X
-#ifdef OS_DARWIN
-# ifndef MSG_NOSIGNAL
+#ifndef MSG_NOSIGNAL
+#if defined(SO_NOSIGPIPE)
 #   define MSG_NOSIGNAL SO_NOSIGPIPE
-# endif
 #endif
+#endif

 #define SOCKET_PATH LOCAL_STATE_DIR "/run/suricata/" 
 #define SOCKET_FILENAME "suricata-command.socket" 
@@ -235,6 +235,45 @@
     SCFree(item);
 }

+#if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE) /* Solaris needs this */
+static ssize_t nosigpipe_send(int fd, const void *buffer, size_t size) {
+/*
+* SIGPIPE handling similar to the approach described in
+* http://krokisplace.blogspot.com/2010/02/suppressing-sigpipe-in-library.html
+*
+* and
+* https://groups.google.com/forum/?fromgroups#!topic/comp.unix.programmer/Spk9NrhSMPk
+*/
+       sigset_t pending, blocked, set;
+       ssize_t count;
+       int saved, error;
+
+       sigpending(&pending); 
+       if (!sigismember(&pending, SIGPIPE)) {
+               sigemptyset(&set);
+               sigaddset(&set, SIGPIPE); 
+               if ((error = pthread_sigmask(SIG_BLOCK, (const sigset_t *)&set, (sigset_t *)&blocked)))
+               goto error;
+       } 
+       count = send(fd, buffer, size, 0); 
+       if (!sigismember(&pending, SIGPIPE)) {
+               saved = errno; 
+               if (count == -1 && errno == EPIPE) {
+                       sigemptyset(&set);
+                       sigaddset(&set, SIGPIPE);
+                       while (-1 == sigtimedwait(&set, NULL, &(struct timespec){ 0, 0 }) && errno == EINTR)
+                               ;;
+               } 
+               if ((error = pthread_sigmask(SIG_SETMASK, (const sigset_t *)&blocked, (sigset_t *)NULL))) goto error; 
+               errno = saved;
+       } 
+       return count;
+       error:
+       errno = error; 
+       return -1;
+}
+#endif 
+
 /**
  * \brief Callback function used to send message to socket
  */
@@ -242,7 +281,11 @@
 {
     int fd = *(int *) data;

+#if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE) /* Solaris needs this */
+    if (nosigpipe_send(fd, buffer, size) == -1) {
+#else 
     if (send(fd, buffer, size, MSG_NOSIGNAL) == -1) {
+#endif
         SCLogInfo("Unable to send block: %s", strerror(errno));
         return -1;
     }
Actions #1

Updated by Victor Julien over 10 years ago

  • Target version set to TBD
Actions #2

Updated by Mark Solaris over 10 years ago

Minor morph of the patch to suit the OS_SOLARIS test

--- ../../suricata-master.orig/src/unix-manager.c       2013-12-01 21:37:52.000000000 +1100
+++ unix-manager.c      2013-12-04 15:23:04.087284018 +1100
@@ -236,6 +236,45 @@
     SCFree(item);
 }

+#if (!defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)) || defined(OS_SOLARIS)
+static ssize_t nosigpipe_send(int fd, const void *buffer, size_t size) {
+/*
+* SIGPIPE handling similar to the approach described in
+* http://krokisplace.blogspot.com/2010/02/suppressing-sigpipe-in-library.html
+*
+* and
+* https://groups.google.com/forum/?fromgroups#!topic/comp.unix.programmer/Spk9NrhSMPk
+*/
+    sigset_t pending, blocked, set;
+    ssize_t count;
+    int saved, error;
+
+    sigpending(&pending);
+    if (!sigismember(&pending, SIGPIPE)) {
+        sigemptyset(&set);
+        sigaddset(&set, SIGPIPE);
+        if ((error = pthread_sigmask(SIG_BLOCK, (const sigset_t *)&set, (sigset_t *)&blocked)))
+        goto error;
+    }
+    count = send(fd, buffer, size, 0);
+    if (!sigismember(&pending, SIGPIPE)) {
+        saved = errno;
+        if (count == -1 && errno == EPIPE) {
+            sigemptyset(&set);
+            sigaddset(&set, SIGPIPE);
+            while (-1 == sigtimedwait(&set, NULL, &(struct timespec){ 0, 0 }) && errno == EINTR)
+                ;;
+        }
+        if ((error = pthread_sigmask(SIG_SETMASK, (const sigset_t *)&blocked, (sigset_t *)NULL))) goto error;
+        errno = saved;
+    }
+    return count;
+    error:
+    errno = error;
+    return -1;
+}
+#endif
+
 /**
  * \brief Callback function used to send message to socket
  */
@@ -243,7 +282,11 @@
 {
     int fd = *(int *) data;

+#if (!defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)) || defined(OS_SOLARIS)
+    if (nosigpipe_send(fd, buffer, size) == -1) {
+#else
     if (send(fd, buffer, size, MSG_NOSIGNAL) == -1) {
+#endif
         SCLogInfo("Unable to send block: %s", strerror(errno));
         return -1;
     }
Actions #3

Updated by Andreas Herz over 8 years ago

  • Status changed from New to Closed
Actions #4

Updated by Victor Julien over 6 years ago

  • Target version deleted (TBD)
Actions

Also available in: Atom PDF