diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-11-01 04:12:01 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-11-01 04:12:01 +0000 |
commit | 207c35fa9ee1cde68cb992aa2525d96fa86d1f20 (patch) | |
tree | 9c67647652b1e15be8a4fa671f2e7a469b916f5b /libgo | |
parent | 15694fdd6d84dbed29898eff5caabc807d4f3067 (diff) | |
download | gcc-207c35fa9ee1cde68cb992aa2525d96fa86d1f20.zip gcc-207c35fa9ee1cde68cb992aa2525d96fa86d1f20.tar.gz gcc-207c35fa9ee1cde68cb992aa2525d96fa86d1f20.tar.bz2 |
syscall: Portability code for epoll_event on GNU/Linux.
From-SVN: r180729
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/Makefile.am | 30 | ||||
-rw-r--r-- | libgo/Makefile.in | 32 | ||||
-rwxr-xr-x | libgo/configure | 219 | ||||
-rw-r--r-- | libgo/configure.ac | 22 | ||||
-rw-r--r-- | libgo/go/syscall/socket_linux.go | 9 | ||||
-rw-r--r-- | libgo/testsuite/Makefile.in | 2 |
6 files changed, 301 insertions, 13 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am index e3b33a8..2a68019 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -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 = diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 05223a6..da7031f 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -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) diff --git a/libgo/configure b/libgo/configure index b9e6a31..9c619be 100755 --- a/libgo/configure +++ b/libgo/configure @@ -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 @@ -14478,6 +14658,41 @@ fi 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 diff --git a/libgo/configure.ac b/libgo/configure.ac index 206e189..e19b5f3 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -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 diff --git a/libgo/go/syscall/socket_linux.go b/libgo/go/syscall/socket_linux.go index 5c0c645..49aac87 100644 --- a/libgo/go/syscall/socket_linux.go +++ b/libgo/go/syscall/socket_linux.go @@ -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 diff --git a/libgo/testsuite/Makefile.in b/libgo/testsuite/Makefile.in index 3d3bc98..21a7492 100644 --- a/libgo/testsuite/Makefile.in +++ b/libgo/testsuite/Makefile.in @@ -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@ |