diff options
author | Werner Fink <werner@suse.de> | 2010-01-13 18:39:08 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2010-01-13 18:39:08 +0000 |
commit | 13926e42a04dbe36e9017010ded30b8287e39321 (patch) | |
tree | 8c0428d1133d720b8317bfedeb6cba965135691c /m4 | |
parent | 2f4b8d158ddb499b75baab0370e625ccc82c1202 (diff) |
initial socketpair support from https://savannah.nongnu.org/patch/?6741
Diffstat (limited to 'm4')
-rw-r--r-- | m4/socketpair.m4 | 116 |
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 +]) |