Actions
Bug #862
closed1.4.3: src/unix-manager.c: Solaris doesn't define MSG_NOSIGNAL or SO_NOSIGPIPE
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