Bug #13085 » 0001-io.c-io_fwrite-temporarily-freeze-string-when-writin.patch
| io.c | ||
|---|---|---|
| return str; | ||
| } | ||
| struct fwrite_tmp_freeze { | ||
| VALUE str; | ||
| union { | ||
| rb_io_t *fptr; | ||
| long written; | ||
| } as; | ||
| int nosync; | ||
| }; | ||
| static VALUE | ||
| fwrite_freeze(VALUE p) | ||
| { | ||
| struct fwrite_tmp_freeze *x = (struct fwrite_tmp_freeze *)p; | ||
| const char *ptr; | ||
| long len; | ||
| OBJ_FREEZE_RAW(x->str); | ||
| RSTRING_GETMEM(x->str, ptr, len); | ||
| x->as.written = io_binwrite(x->str, ptr, len, x->as.fptr, x->nosync); | ||
| return Qfalse; | ||
| } | ||
| static VALUE | ||
| fwrite_unfreeze(VALUE str) | ||
| { | ||
| FL_UNSET_RAW(str, FL_FREEZE); | ||
| return Qfalse; | ||
| } | ||
| static long | ||
| io_fwrite(VALUE str, rb_io_t *fptr, int nosync) | ||
| { | ||
| ... | ... | |
| str = do_writeconv(str, fptr, &converted); | ||
| if (converted) | ||
| OBJ_FREEZE(str); | ||
| else | ||
| str = rb_str_new_frozen(str); | ||
| else if (!OBJ_FROZEN_RAW(str)) { | ||
| struct fwrite_tmp_freeze x; | ||
| x.str = str; | ||
| x.as.fptr = fptr; | ||
| x.nosync = nosync; | ||
| rb_ensure(fwrite_freeze, (VALUE)&x, fwrite_unfreeze, str); | ||
| return x.as.written; | ||
| } | ||
| return io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str), | ||
| fptr, nosync); | ||
| - | ||