if (this == original) return this;
RubyIO originalIO = (RubyIO) TypeConverter.convertToTypeWithCheck(original, runtime.getIO(), MethodIndex.TO_IO, "to_io");
OpenFile originalFile = originalIO.getOpenFileChecked();
OpenFile newFile = openFile;
try {
// TODO: I didn't see where MRI has this check, but it seems to be the right place
originalFile.checkClosed(runtime);
if (originalFile.getPipeStream() != null) {
originalFile.getPipeStream().fflush();
originalFile.getMainStream().lseek(0, Stream.SEEK_CUR);
} else if (originalFile.isWritable()) {
originalFile.getMainStream().fflush();
} else {
originalFile.getMainStream().lseek(0, Stream.SEEK_CUR);
}
newFile.setMode(originalFile.getMode());
newFile.setProcess(originalFile.getProcess());
newFile.setLineNumber(originalFile.getLineNumber());
newFile.setPath(originalFile.getPath());
newFile.setFinalizer(originalFile.getFinalizer());
ModeFlags modes;
if (newFile.isReadable()) {
if (newFile.isWritable()) {
if (newFile.getPipeStream() != null) {
modes = new ModeFlags(ModeFlags.RDONLY);
} else {
modes = new ModeFlags(ModeFlags.RDWR);
}
} else {
modes = new ModeFlags(ModeFlags.RDONLY);
}
} else {
if (newFile.isWritable()) {
modes = new ModeFlags(ModeFlags.WRONLY);
} else {
modes = originalFile.getMainStream().getModes();
}
}
ChannelDescriptor descriptor = originalFile.getMainStream().getDescriptor().dup();
newFile.setMainStream(ChannelStream.fdopen(runtime, descriptor, modes));
// TODO: the rest of this...seeking to same position is unnecessary since we share a channel
// but some of this may be needed?
// fseeko(fptr->f, ftello(orig->f), SEEK_SET);
// if (orig->f2) {
// if (fileno(orig->f) != fileno(orig->f2)) {
// fd = ruby_dup(fileno(orig->f2));
// }
// fptr->f2 = rb_fdopen(fd, "w");
// fseeko(fptr->f2, ftello(orig->f2), SEEK_SET);
// }
// if (fptr->mode & FMODE_BINMODE) {
// rb_io_binmode(dest);
// }
// Register the new descriptor
registerDescriptor(newFile.getMainStream().getDescriptor());
} catch (IOException ex) {
throw runtime.newIOError("could not init copy: " + ex);
} catch (BadDescriptorException ex) {
throw runtime.newIOError("could not init copy: " + ex);
} catch (PipeException ex) {