From 8ff0574198d1d32c7f80044c611d54f6e3b1aace Mon Sep 17 00:00:00 2001 From: naruse Date: Wed, 7 Jul 2010 01:29:22 +0000 Subject: [PATCH] * missing/close.c: ignore ECONNRESET. FreeBSD wrongly sets ECONNRESET on close(2) and it causes false-negative exceptions. [ruby-dev:41778] * configure.in: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@28561 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 +++++++ configure.in | 7 +++++- include/ruby/ruby.h | 11 +++++++++ missing/close.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 missing/close.c diff --git a/ChangeLog b/ChangeLog index eeef38a33f..8671b4094d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Wed Jul 7 10:26:20 2010 NARUSE, Yui + + * missing/close.c: ignore ECONNRESET. + FreeBSD wrongly sets ECONNRESET on close(2) and + it causes false-negative exceptions. [ruby-dev:41778] + + * configure.in: ditto. + Tue Jul 6 22:57:21 2010 Tanaka Akira * io.c (nogvl_copy_stream_sendfile): jump to retry_sendfile directly diff --git a/configure.in b/configure.in index 679007dacb..a7c9610cca 100644 --- a/configure.in +++ b/configure.in @@ -926,6 +926,10 @@ main() AC_DEFINE(BROKEN_SETREGID, 1) ac_cv_sizeof_rlim_t=8], [freebsd*], [ LIBS="-lm $LIBS" + ac_cv_func_getpeername=no + ac_cv_func_getsockname=no + ac_cv_func_shutdown=no + ac_cv_func_close=no ], [dragonfly*], [ LIBS="-lm $LIBS" ], @@ -1119,6 +1123,7 @@ main() rb_cv_broken_glibc_ia64_erfc=no)]) AS_CASE([$rb_cv_broken_glibc_ia64_erfc],[yes],[ac_cv_func_erf=no]) +AS_CASE(["$target_os"],[freebsd],[],[AC_REPLACE_FUNCS(close)]) AC_REPLACE_FUNCS(dup2 memmove strerror\ strchr strstr crypt flock\ isnan finite isinf hypot acosh erf tgamma lgamma_r cbrt \ @@ -1140,7 +1145,7 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot getcwd eacce setitimer setruid seteuid setreuid setresuid setproctitle socketpair\ setrgid setegid setregid setresgid issetugid pause lchown lchmod\ getpgrp setpgrp getpgid setpgid initgroups getgroups setgroups\ - getpriority getrlimit setrlimit sysconf \ + getpriority getrlimit setrlimit sysconf close\ dlopen sigprocmask sigaction sigsetjmp _setjmp _longjmp\ setsid telldir seekdir fchmod cosh sinh tanh log2 round\ setuid setgid daemon select_large_fdset setenv unsetenv\ diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index d4ffe10d8c..8cb4524824 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -1421,6 +1421,17 @@ int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap); #define snprintf ruby_snprintf #define vsnprintf ruby_vsnprintf +#ifdef __FreeBSD__ +#undef getpeername +#define getpeername ruby_getpeername +#undef getsockname +#define getsockname ruby_getsockname +#undef shutdown +#define shutdown ruby_shutdown +#undef close +#define close ruby_close +#endif + #if defined(__cplusplus) #if 0 { /* satisfy cc-mode */ diff --git a/missing/close.c b/missing/close.c new file mode 100644 index 0000000000..7e743eb204 --- /dev/null +++ b/missing/close.c @@ -0,0 +1,55 @@ +/* Ignore ECONNRESET of FreeBSD */ +#include +#include +#include +#include + +int +ruby_getpeername(int s, struct sockaddr * name, + socklen_t * namelen) +{ + errno = 0; + s = getpeername(s, name, namelen); + if (errno == ECONNRESET) { + errno = 0; + s = 0; + } + return s; +} + +int +ruby_getsockname(int s, struct sockaddr * name, + socklen_t * namelen) +{ + errno = 0; + s = getsockname(s, name, namelen); + if (errno == ECONNRESET) { + errno = 0; + s = 0; + } + return s; +} + +int +ruby_shutdown(int s, int how) +{ + errno = 0; + s = shutdown(s, how); + if (errno == ECONNRESET) { + errno = 0; + s = 0; + } + return s; +} + +int +ruby_close(int s) +{ + errno = 0; + s = close(s); + if (errno == ECONNRESET) { + errno = 0; + s = 0; + } + return s; +}