summaryrefslogtreecommitdiff
path: root/m4
diff options
context:
space:
mode:
authorWerner Fink <werner@suse.de>2010-01-13 18:39:08 +0000
committerColin Watson <cjwatson@debian.org>2010-01-13 18:39:08 +0000
commit13926e42a04dbe36e9017010ded30b8287e39321 (patch)
tree8c0428d1133d720b8317bfedeb6cba965135691c /m4
parent2f4b8d158ddb499b75baab0370e625ccc82c1202 (diff)
initial socketpair support from https://savannah.nongnu.org/patch/?6741
Diffstat (limited to 'm4')
-rw-r--r--m4/socketpair.m4116
1 files changed, 116 insertions, 0 deletions
diff --git a/m4/socketpair.m4 b/m4/socketpair.m4
new file mode 100644
index 00000000..e082eccb
--- /dev/null
+++ b/m4/socketpair.m4
@@ -0,0 +1,116 @@
+# socketpair.m4
+dnl
+dnl Check if the socketpair(2) system call can be used
+dnl and should be used as a fast replacement for pipe(2)
+dnl
+dnl Author: Werner Fink <werner@suse.de>, 2009
+
+AC_DEFUN([AM_SOCKETPAIR_PIPE],
+[ AC_MSG_CHECKING([if socketpair(2) can be used as fast replacement for pipe(2)])
+ AC_CACHE_VAL(am_cv_socketpair_pipe, [
+ AC_TRY_RUN([
+#include <netdb.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#ifndef SHUT_RD
+# define SHUT_RD 0
+#endif
+#ifndef SHUT_WR
+# define SHUT_WR 1
+#endif
+
+static void sigpipe(int sig)
+{
+ _exit(0);
+}
+
+int main()
+{
+ const char test[] = "May use socketpair(2) instead of pipe(2)\n";
+ char buf[256];
+ int sfd[2], s;
+ pid_t pid;
+ if (socketpair(AF_UNIX,SOCK_STREAM,0,sfd) < 0)
+ return 1;
+ if (shutdown(sfd[1],SHUT_RD) < 0 || shutdown(sfd[0],SHUT_WR) < 0)
+ return 1;
+ if ((pid = fork()) < 0)
+ return 1;
+ if (pid) {
+ close(sfd[1]);
+ waitpid(-1,&s,0);
+ if (read(sfd[0],buf,sizeof(buf)) < 0)
+ return 1;
+ } else {
+ close(sfd[0]);
+ write(sfd[1],test,sizeof(test) - 1);
+ return 0;
+ }
+ close(sfd[0]);
+ signal(SIGPIPE, sigpipe);
+ if (socketpair(AF_UNIX,SOCK_STREAM,0,sfd) < 0)
+ return 1;
+ if (shutdown(sfd[1],SHUT_RD) < 0 || shutdown(sfd[0],SHUT_WR) < 0)
+ return 1;
+ close(sfd[0]);
+ write(sfd[1],test,sizeof(test) - 1);
+ return 1;
+}], [am_cv_socketpair_pipe=yes], [am_cv_socketpair_pipe=no], [am_cv_socketpair_pipe=no])
+ ])
+ AC_MSG_RESULT([$am_cv_socketpair_pipe])
+ if test "$am_cv_socketpair_pipe" = yes; then
+ AC_DEFINE(USE_SOCKETPAIR_PIPE, 1, [Define if socketpair(2) can be used as a fast replacement for pipe(2).])
+ fi
+])
+
+dnl
+dnl Check if shutdown(2) does not set mode for the socket descriptor
+dnl compare with ls -lL /proc/<pid>/fd/
+dnl
+AC_DEFUN([AM_SOCKETPAIR_MODE],
+[ AC_MSG_CHECKING([if shutdown(2) does not set mode for the socket descriptor])
+ AC_CACHE_VAL(am_cv_socketpair_mode, [
+ AC_TRY_RUN([
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifndef SHUT_RD
+# define SHUT_RD 0
+#endif
+#ifndef SHUT_WR
+# define SHUT_WR 1
+#endif
+
+int main()
+{
+ int sfd[2];
+ struct stat st[2];
+ if (socketpair(AF_UNIX,SOCK_STREAM,0,sfd) < 0)
+ return 1;
+ if (shutdown(sfd[1],SHUT_RD) < 0 || shutdown(sfd[0],SHUT_WR) < 0)
+ return 1;
+ if (fstat(sfd[0], &(st[0])) < 0 || fstat(sfd[1], &(st[1])) < 0)
+ return 1;
+ if ((st[0].st_mode & (S_IRUSR|S_IWUSR)) == S_IRUSR && (st[1].st_mode & (S_IRUSR|S_IWUSR)) == S_IWUSR)
+ return 1;
+ if (fchmod(sfd[0], S_IRUSR) < 0 || fchmod(sfd[1], S_IWUSR) < 0)
+ return 1;
+ if (fstat(sfd[0], &(st[0])) < 0 || fstat(sfd[1], &(st[1])) < 0)
+ return 1;
+ if ((st[0].st_mode & (S_IRUSR|S_IWUSR)) != S_IRUSR && (st[1].st_mode & (S_IRUSR|S_IWUSR)) != S_IWUSR)
+ return 1;
+ return 0;
+}], [am_cv_socketpair_mode=yes], [am_cv_socketpair_mode=no], [am_cv_socketpair_mode=no])
+ ])
+ AC_MSG_RESULT([$am_cv_socketpair_mode])
+ if test "$am_cv_socketpair_mode" = yes; then
+ AC_DEFINE(CORRECT_SOCKETPAIR_MODE, 1, [Define if shutdown(2) does not set modes for socket descriptor.])
+ fi
+])