OSDN Git Service

syscall: Portability code for epoll_event on GNU/Linux.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Nov 2011 04:12:01 +0000 (04:12 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Nov 2011 04:12:01 +0000 (04:12 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180729 138bc75d-0d04-0410-961f-82ee72b054a4

libgo/Makefile.am
libgo/Makefile.in
libgo/configure
libgo/configure.ac
libgo/go/syscall/socket_linux.go
libgo/testsuite/Makefile.in

index e3b33a8..2a68019 100644 (file)
@@ -1498,7 +1498,7 @@ endif # !LIBGO_IS_LINUX
 
 # Define socket sizes and types.
 if LIBGO_IS_LINUX
-syscall_socket_file = go/syscall/socket_linux.go
+syscall_socket_file = go/syscall/socket_linux.go epoll.go
 else
 if LIBGO_IS_SOLARIS
 syscall_socket_file = go/syscall/socket_solaris.go
@@ -1582,6 +1582,34 @@ s-sysinfo: $(srcdir)/mksysinfo.sh config.h
        $(SHELL) $(srcdir)/../move-if-change tmp-sysinfo.go sysinfo.go
        $(STAMP) $@
 
+# The epoll struct has an embedded union and is packed on x86_64,
+# which is too complicated for mksysinfo.sh.  We find the offset of
+# the only field we care about in configure.ac, and generate the
+# struct here.
+epoll.go: s-epoll; @true
+s-epoll: Makefile
+       rm -f epoll.go.tmp
+       echo 'package syscall' > epoll.go.tmp
+       echo 'type EpollEvent struct {' >> epoll.go.tmp
+       echo '  Events uint32' >> epoll.go.tmp
+       case "$(SIZEOF_STRUCT_EPOLL_EVENT),$(STRUCT_EPOLL_EVENT_FD_OFFSET)" in \
+       0,0) echo 1>&2 "*** struct epoll_event data.fd offset unknown"; \
+          exit 1; ;; \
+       8,4) echo '     Fd int32' >> epoll.go.tmp; ;; \
+       12,4) echo '    Fd int32' >> epoll.go.tmp; \
+          echo '       Pad [4]byte' >> epoll.go.tmp; ;; \
+       12,8) echo '    Pad [4]byte' >> epoll.go.tmp; \
+          echo '       Fd int32' >> epoll.go.tmp; ;; \
+       16,8) echo '    Pad [4]byte' >> epoll.go.tmp; \
+          echo '       Fd int32' >> epoll.go.tmp; \
+          echo '       Pad2 [4]byte' >> epoll.go.tmp; ;; \
+       *) echo 1>&2 "*** struct epoll_event unsupported"; \
+          exit 1; ;; \
+       esac
+       echo '}' >> epoll.go.tmp
+       $(SHELL) $(srcdir)/../move-if-change epoll.go.tmp epoll.go
+       $(STAMP) $@
+
 if LIBGO_IS_LINUX
 # os_lib_inotify_lo = os/inotify.lo
 os_lib_inotify_lo =
index 05223a6..da7031f 100644 (file)
@@ -424,9 +424,11 @@ RANLIB = @RANLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SIZEOF_STRUCT_EPOLL_EVENT = @SIZEOF_STRUCT_EPOLL_EVENT@
 SPLIT_STACK = @SPLIT_STACK@
 STRINGOPS_FLAG = @STRINGOPS_FLAG@
 STRIP = @STRIP@
+STRUCT_EPOLL_EVENT_FD_OFFSET = @STRUCT_EPOLL_EVENT_FD_OFFSET@
 VERSION = @VERSION@
 WARN_FLAGS = @WARN_FLAGS@
 WERROR = @WERROR@
@@ -1868,7 +1870,7 @@ go_testing_script_files = \
 @LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@syscall_socket_file = go/syscall/socket_solaris.go
 
 # Define socket sizes and types.
-@LIBGO_IS_LINUX_TRUE@syscall_socket_file = go/syscall/socket_linux.go
+@LIBGO_IS_LINUX_TRUE@syscall_socket_file = go/syscall/socket_linux.go epoll.go
 @LIBGO_IS_386_FALSE@@LIBGO_IS_SOLARIS_TRUE@syscall_uname_file = go/syscall/libcall_uname.go
 
 # Support for uname.
@@ -4475,6 +4477,34 @@ s-sysinfo: $(srcdir)/mksysinfo.sh config.h
        $(SHELL) $(srcdir)/../move-if-change tmp-sysinfo.go sysinfo.go
        $(STAMP) $@
 
+# The epoll struct has an embedded union and is packed on x86_64,
+# which is too complicated for mksysinfo.sh.  We find the offset of
+# the only field we care about in configure.ac, and generate the
+# struct here.
+epoll.go: s-epoll; @true
+s-epoll: Makefile
+       rm -f epoll.go.tmp
+       echo 'package syscall' > epoll.go.tmp
+       echo 'type EpollEvent struct {' >> epoll.go.tmp
+       echo '  Events uint32' >> epoll.go.tmp
+       case "$(SIZEOF_STRUCT_EPOLL_EVENT),$(STRUCT_EPOLL_EVENT_FD_OFFSET)" in \
+       0,0) echo 1>&2 "*** struct epoll_event data.fd offset unknown"; \
+          exit 1; ;; \
+       8,4) echo '     Fd int32' >> epoll.go.tmp; ;; \
+       12,4) echo '    Fd int32' >> epoll.go.tmp; \
+          echo '       Pad [4]byte' >> epoll.go.tmp; ;; \
+       12,8) echo '    Pad [4]byte' >> epoll.go.tmp; \
+          echo '       Fd int32' >> epoll.go.tmp; ;; \
+       16,8) echo '    Pad [4]byte' >> epoll.go.tmp; \
+          echo '       Fd int32' >> epoll.go.tmp; \
+          echo '       Pad2 [4]byte' >> epoll.go.tmp; ;; \
+       *) echo 1>&2 "*** struct epoll_event unsupported"; \
+          exit 1; ;; \
+       esac
+       echo '}' >> epoll.go.tmp
+       $(SHELL) $(srcdir)/../move-if-change epoll.go.tmp epoll.go
+       $(STAMP) $@
+
 asn1/asn1.lo: $(go_asn1_files) big.gox bytes.gox fmt.gox io.gox os.gox \
                reflect.gox strconv.gox strings.gox time.gox
        $(BUILDPACKAGE)
index b9e6a31..9c619be 100755 (executable)
@@ -602,6 +602,8 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+STRUCT_EPOLL_EVENT_FD_OFFSET
+SIZEOF_STRUCT_EPOLL_EVENT
 STRINGOPS_FLAG
 HAVE_WAIT4_FALSE
 HAVE_WAIT4_TRUE
@@ -1949,6 +1951,184 @@ $as_echo "$ac_res" >&6; }
   eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_type
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+                       if test $ac_lo -le $ac_mid; then
+                         ac_lo= ac_hi=
+                         break
+                       fi
+                       as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+                       if test $ac_mid -le $ac_hi; then
+                         ac_lo= ac_hi=
+                         break
+                       fi
+                       as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+       return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+       return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_compute_int
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -10916,7 +11096,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10919 "configure"
+#line 11099 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11022,7 +11202,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11025 "configure"
+#line 11205 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 
 CFLAGS=$CFLAGS_hold
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking epoll_event size" >&5
+$as_echo_n "checking epoll_event size... " >&6; }
+if test "${libgo_cv_c_epoll_event_size+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "sizeof (struct epoll_event)" "libgo_cv_c_epoll_event_size"        "#include <sys/epoll.h>"; then :
+
+else
+  libgo_cv_c_epoll_event_size=0
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_c_epoll_event_size" >&5
+$as_echo "$libgo_cv_c_epoll_event_size" >&6; }
+SIZEOF_STRUCT_EPOLL_EVENT=${libgo_cv_c_epoll_event_size}
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking epoll_event data.fd offset" >&5
+$as_echo_n "checking epoll_event data.fd offset... " >&6; }
+if test "${libgo_cv_c_epoll_event_fd_offset+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "offsetof (struct epoll_event, data.fd)" "libgo_cv_c_epoll_event_fd_offset"        "#include <stddef.h>
+#include <sys/epoll.h>"; then :
+
+else
+  libgo_cv_c_epoll_event_fd_offset=0
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_c_epoll_event_fd_offset" >&5
+$as_echo "$libgo_cv_c_epoll_event_fd_offset" >&6; }
+STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
+
+
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
index 206e189..e19b5f3 100644 (file)
@@ -505,6 +505,28 @@ CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
 AC_CHECK_TYPES(off64_t)
 CFLAGS=$CFLAGS_hold
 
+dnl Work out the size of the epoll_events struct on GNU/Linux.
+AC_CACHE_CHECK([epoll_event size],
+[libgo_cv_c_epoll_event_size],
+[AC_COMPUTE_INT(libgo_cv_c_epoll_event_size,
+[sizeof (struct epoll_event)],
+[#include <sys/epoll.h>],
+[libgo_cv_c_epoll_event_size=0])])
+SIZEOF_STRUCT_EPOLL_EVENT=${libgo_cv_c_epoll_event_size}
+AC_SUBST(SIZEOF_STRUCT_EPOLL_EVENT)
+
+dnl Work out the offset of the fd field in the epoll_events struct on
+dnl GNU/Linux.
+AC_CACHE_CHECK([epoll_event data.fd offset],
+[libgo_cv_c_epoll_event_fd_offset],
+[AC_COMPUTE_INT(libgo_cv_c_epoll_event_fd_offset,
+[offsetof (struct epoll_event, data.fd)],
+[#include <stddef.h>
+#include <sys/epoll.h>],
+[libgo_cv_c_epoll_event_fd_offset=0])])
+STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
+AC_SUBST(STRUCT_EPOLL_EVENT_FD_OFFSET)
+
 AC_CACHE_SAVE
 
 if test ${multilib} = yes; then
index 5c0c645..49aac87 100644 (file)
@@ -164,15 +164,6 @@ func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, int) {
        return nil, EAFNOSUPPORT
 }
 
-// We don't take this type directly from the header file because it
-// uses a union.  FIXME.
-
-type EpollEvent struct {
-       Events uint32
-       Fd int32
-       Pad int32
-}
-
 //sysnb        EpollCreate(size int) (fd int, errno int)
 //epoll_create(size int) int
 
index 3d3bc98..21a7492 100644 (file)
@@ -133,9 +133,11 @@ RANLIB = @RANLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SIZEOF_STRUCT_EPOLL_EVENT = @SIZEOF_STRUCT_EPOLL_EVENT@
 SPLIT_STACK = @SPLIT_STACK@
 STRINGOPS_FLAG = @STRINGOPS_FLAG@
 STRIP = @STRIP@
+STRUCT_EPOLL_EVENT_FD_OFFSET = @STRUCT_EPOLL_EVENT_FD_OFFSET@
 VERSION = @VERSION@
 WARN_FLAGS = @WARN_FLAGS@
 WERROR = @WERROR@