summaryrefslogtreecommitdiffstats
path: root/m4/fd_passing.m4
diff options
context:
space:
mode:
Diffstat (limited to 'm4/fd_passing.m4')
-rw-r--r--m4/fd_passing.m493
1 files changed, 93 insertions, 0 deletions
diff --git a/m4/fd_passing.m4 b/m4/fd_passing.m4
new file mode 100644
index 0000000..6b96c0f
--- /dev/null
+++ b/m4/fd_passing.m4
@@ -0,0 +1,93 @@
+dnl * see if fd passing works
+AC_DEFUN([DOVECOT_FD_PASSING], [
+ AC_CACHE_CHECK([whether fd passing works],i_cv_fd_passing,[
+ for i in 1 2; do
+ old_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS -I$srcdir/src/lib $srcdir/src/lib/fdpass.c"
+ if test $i = 2; then
+ CFLAGS="$CFLAGS -DBUGGY_CMSG_MACROS"
+ fi
+
+ AC_TRY_RUN([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/wait.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include "fdpass.h"
+
+ static
+ int nopen(void)
+ {
+ int i, n;
+ struct stat sb;
+ for (i = n = 0; i < 256; i++)
+ if (fstat(i, &sb) == 0) n++;
+ return n;
+ }
+ int main(void)
+ {
+ int fd[2], send_fd, recv_fd, status, n1, n2;
+ struct stat st, st2;
+ char data;
+
+ send_fd = creat("conftest.fdpass", 0600);
+ if (send_fd == -1) return 2;
+ unlink("conftest.fdpass");
+ if (fstat(send_fd, &st) < 0) return 2;
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) return 2;
+ n1 = nopen();
+
+ switch (fork()) {
+ case -1:
+ return 2;
+ case 0:
+ alarm(1);
+ if (fd_send(fd[0], send_fd, &data, 1) != 1) return 2;
+ return 0;
+ default:
+ alarm(2);
+ if (wait(&status) == -1)
+ return 2;
+ if (status != 0)
+ return status;
+ if (fd_read(fd[1], &data, 1, &recv_fd) != 1) return 1;
+ if (fstat(recv_fd, &st2) < 0) return 2;
+ /* nopen check is for making sure that only a single fd
+ was received */
+ n2 = nopen();
+ return st.st_ino == st2.st_ino && n2 == n1 + 1 ? 0 : 1;
+ }
+ }
+ ], [
+ CFLAGS=$old_cflags
+ if test $i = 2; then
+ i_cv_fd_passing=buggy_cmsg_macros
+ else
+ i_cv_fd_passing=yes
+ fi
+ break
+ ], [
+ dnl no, try with BUGGY_CMSG_MACROS
+ CFLAGS=$old_cflags
+ i_cv_fd_passing=no
+ ])
+ done
+ ]);
+
+ case "$host_os" in
+ darwin[[1-9]].*)
+ if test "$i_cv_fd_passing" = "yes"; then
+ i_cv_fd_passing=buggy_cmsg_macros
+ fi
+ ;;
+ esac
+
+ if test $i_cv_fd_passing = buggy_cmsg_macros; then
+ AC_DEFINE(BUGGY_CMSG_MACROS,, [Define if you have buggy CMSG macros])
+ fi
+ if test $i_cv_fd_passing = no; then
+ AC_ERROR([fd passing is required for Dovecot to work])
+ fi
+])