ruby-changes:51615
From: nagachika <ko1@a...>
Date: Mon, 2 Jul 2018 18:15:38 +0900 (JST)
Subject: [ruby-changes:51615] nagachika:r63826 (ruby_2_5): merge revision(s) 63304: [Backport #14713]
nagachika 2018-07-02 18:15:33 +0900 (Mon, 02 Jul 2018) New Revision: 63826 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63826 Log: merge revision(s) 63304: [Backport #14713] io.c: workaround for EPROTOTYPE * io.c (internal_write_func, internal_writev_func): retry at unexpected EPROTOTYPE on macOS, to get rid of a kernel bug. [ruby-core:86690] [Bug #14713] * ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto. Modified directories: branches/ruby_2_5/ Modified files: branches/ruby_2_5/ext/socket/init.c branches/ruby_2_5/io.c branches/ruby_2_5/test/net/ftp/test_ftp.rb branches/ruby_2_5/version.h Index: ruby_2_5/test/net/ftp/test_ftp.rb =================================================================== --- ruby_2_5/test/net/ftp/test_ftp.rb (revision 63825) +++ ruby_2_5/test/net/ftp/test_ftp.rb (revision 63826) @@ -425,7 +425,7 @@ class FTPTest < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_5/test/net/ftp/test_ftp.rb#L425 end conn.print(l, "\r\n") end - rescue Errno::EPIPE, Errno::EPROTOTYPE + rescue Errno::EPIPE ensure assert_nil($!) conn.close Index: ruby_2_5/ext/socket/init.c =================================================================== --- ruby_2_5/ext/socket/init.c (revision 63825) +++ ruby_2_5/ext/socket/init.c (revision 63826) @@ -56,6 +56,12 @@ is_socket(int fd) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/ext/socket/init.c#L56 } #endif +#if defined __APPLE__ +# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE) +#else +# define do_write_retry(code) ret = code +#endif + VALUE rsock_init_sock(VALUE sock, int fd) { @@ -83,8 +89,10 @@ rsock_sendto_blocking(void *data) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/ext/socket/init.c#L89 { struct rsock_send_arg *arg = data; VALUE mesg = arg->mesg; - return (VALUE)sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags, arg->to, arg->tolen); + ssize_t ret; + do_write_retry(sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), + arg->flags, arg->to, arg->tolen)); + return (VALUE)ret; } VALUE @@ -92,8 +100,10 @@ rsock_send_blocking(void *data) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/ext/socket/init.c#L100 { struct rsock_send_arg *arg = data; VALUE mesg = arg->mesg; - return (VALUE)send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags); + ssize_t ret; + do_write_retry(send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), + arg->flags)); + return (VALUE)ret; } struct recvfrom_arg { @@ -366,10 +376,18 @@ rsock_write_nonblock(VALUE sock, VALUE s https://github.com/ruby/ruby/blob/trunk/ruby_2_5/ext/socket/init.c#L376 rb_io_flush(sock); } +#ifdef __APPLE__ + again: +#endif n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT); if (n < 0) { int e = errno; +#ifdef __APPLE__ + if (e == EPROTOTYPE) { + goto again; + } +#endif if (e == EWOULDBLOCK || e == EAGAIN) { if (ex == Qfalse) return sym_wait_writable; rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, Index: ruby_2_5/version.h =================================================================== --- ruby_2_5/version.h (revision 63825) +++ ruby_2_5/version.h (revision 63826) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_5/version.h#L1 #define RUBY_VERSION "2.5.2" #define RUBY_RELEASE_DATE "2018-07-02" -#define RUBY_PATCHLEVEL 64 +#define RUBY_PATCHLEVEL 65 #define RUBY_RELEASE_YEAR 2018 #define RUBY_RELEASE_MONTH 7 Index: ruby_2_5/io.c =================================================================== --- ruby_2_5/io.c (revision 63825) +++ ruby_2_5/io.c (revision 63826) @@ -937,11 +937,18 @@ internal_read_func(void *ptr) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/io.c#L937 return read(iis->fd, iis->buf, iis->capa); } +#if defined __APPLE__ +# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE) +#else +# define do_write_retry(code) ret = code +#endif static VALUE internal_write_func(void *ptr) { struct io_internal_write_struct *iis = ptr; - return write(iis->fd, iis->buf, iis->capa); + ssize_t ret; + do_write_retry(write(iis->fd, iis->buf, iis->capa)); + return (VALUE)ret; } static void* @@ -956,7 +963,9 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_5/io.c#L963 internal_writev_func(void *ptr) { struct io_internal_writev_struct *iis = ptr; - return writev(iis->fd, iis->iov, iis->iovcnt); + ssize_t ret; + do_write_retry(writev(iis->fd, iis->iov, iis->iovcnt)); + return (VALUE)ret; } #endif Index: ruby_2_5 =================================================================== --- ruby_2_5 (revision 63825) +++ ruby_2_5 (revision 63826) Property changes on: ruby_2_5 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /trunk:r63304 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/