mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Raise EPIPE at broken pipe for the backward compatibility
Instead of SignalException for SIGPIPE, raise `Errno::EPIPE` with instance variable `signo` and re-send that signal at exit. [Feature #14413]
This commit is contained in:
parent
d72fd1e45b
commit
155f64e3c4
Notes:
git
2020-04-15 22:08:49 +09:00
4 changed files with 23 additions and 9 deletions
5
NEWS.md
5
NEWS.md
|
@ -149,9 +149,8 @@ Excluding feature bug fixes.
|
||||||
* This is experimental; if it brings a big incompatibility issue,
|
* This is experimental; if it brings a big incompatibility issue,
|
||||||
it may be reverted until 2.8/3.0 release.
|
it may be reverted until 2.8/3.0 release.
|
||||||
|
|
||||||
* When writing to STDOUT redirected to a closed pipe, SignalException
|
* When writing to STDOUT redirected to a closed pipe, no broken pipe
|
||||||
is raised now instead of Errno::EPIPE, so that no broken pipe error
|
error message will be shown now. [[Feature #14413]]
|
||||||
message will be shown. [[Feature #14413]]
|
|
||||||
|
|
||||||
## Stdlib compatibility issues
|
## Stdlib compatibility issues
|
||||||
|
|
||||||
|
|
6
eval.c
6
eval.c
|
@ -243,6 +243,7 @@ rb_ec_cleanup(rb_execution_context_t *ec, volatile int ex)
|
||||||
state = 0;
|
state = 0;
|
||||||
for (nerr = 0; nerr < numberof(errs); ++nerr) {
|
for (nerr = 0; nerr < numberof(errs); ++nerr) {
|
||||||
VALUE err = ATOMIC_VALUE_EXCHANGE(errs[nerr], Qnil);
|
VALUE err = ATOMIC_VALUE_EXCHANGE(errs[nerr], Qnil);
|
||||||
|
VALUE sig;
|
||||||
|
|
||||||
if (!RTEST(err)) continue;
|
if (!RTEST(err)) continue;
|
||||||
|
|
||||||
|
@ -258,6 +259,11 @@ rb_ec_cleanup(rb_execution_context_t *ec, volatile int ex)
|
||||||
state = NUM2INT(sig);
|
state = NUM2INT(sig);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (rb_obj_is_kind_of(err, rb_eSystemCallError) &&
|
||||||
|
FIXNUM_P(sig = rb_attr_get(err, id_signo))) {
|
||||||
|
state = NUM2INT(sig);
|
||||||
|
break;
|
||||||
|
}
|
||||||
else if (sysex == EXIT_SUCCESS) {
|
else if (sysex == EXIT_SUCCESS) {
|
||||||
sysex = EXIT_FAILURE;
|
sysex = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,6 +474,10 @@ error_handle(rb_execution_context_t *ec, int ex)
|
||||||
rb_ivar_get(errinfo, id_signo) != INT2FIX(SIGSEGV)) {
|
rb_ivar_get(errinfo, id_signo) != INT2FIX(SIGSEGV)) {
|
||||||
/* no message when exiting by signal */
|
/* no message when exiting by signal */
|
||||||
}
|
}
|
||||||
|
else if (rb_obj_is_kind_of(errinfo, rb_eSystemCallError) &&
|
||||||
|
FIXNUM_P(rb_attr_get(errinfo, id_signo))) {
|
||||||
|
/* no message when exiting by error to be mapped to signal */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
rb_ec_error_print(ec, errinfo);
|
rb_ec_error_print(ec, errinfo);
|
||||||
}
|
}
|
||||||
|
|
17
io.c
17
io.c
|
@ -545,10 +545,12 @@ static rb_io_t *flush_before_seek(rb_io_t *fptr);
|
||||||
(fptr)->mode |= FMODE_SIGNAL_ON_EPIPE : \
|
(fptr)->mode |= FMODE_SIGNAL_ON_EPIPE : \
|
||||||
(fptr)->mode &= ~FMODE_SIGNAL_ON_EPIPE)
|
(fptr)->mode &= ~FMODE_SIGNAL_ON_EPIPE)
|
||||||
|
|
||||||
static int
|
extern ID ruby_static_id_signo;
|
||||||
errno_on_write(rb_io_t *fptr)
|
|
||||||
|
NORETURN(static void raise_on_write(rb_io_t *fptr, int e, VALUE errinfo));
|
||||||
|
static void
|
||||||
|
raise_on_write(rb_io_t *fptr, int e, VALUE errinfo)
|
||||||
{
|
{
|
||||||
int e = errno;
|
|
||||||
#if defined EPIPE
|
#if defined EPIPE
|
||||||
if (fptr_signal_on_epipe(fptr) && (e == EPIPE)) {
|
if (fptr_signal_on_epipe(fptr) && (e == EPIPE)) {
|
||||||
const VALUE sig =
|
const VALUE sig =
|
||||||
|
@ -556,14 +558,17 @@ errno_on_write(rb_io_t *fptr)
|
||||||
INT2FIX(SIGPIPE) - INT2FIX(0) +
|
INT2FIX(SIGPIPE) - INT2FIX(0) +
|
||||||
# endif
|
# endif
|
||||||
INT2FIX(0);
|
INT2FIX(0);
|
||||||
rb_exc_raise(rb_class_new_instance(1, &sig, rb_eSignal));
|
rb_ivar_set(errinfo, ruby_static_id_signo, sig);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return e;
|
rb_exc_raise(errinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define rb_sys_fail_on_write(fptr) \
|
#define rb_sys_fail_on_write(fptr) \
|
||||||
rb_syserr_fail_path(errno_on_write(fptr), (fptr)->pathv)
|
do { \
|
||||||
|
int e = errno; \
|
||||||
|
raise_on_write(fptr, e, rb_syserr_new_path(e, (fptr)->pathv)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
|
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
|
||||||
#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) ((fptr)->mode & FMODE_TEXTMODE)
|
#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) ((fptr)->mode & FMODE_TEXTMODE)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue