Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

IO.binwrite doesn't truncate the file if an offset is given #726

Merged
merged 3 commits into from

1 participant

@atambo
Collaborator

This reverts #722 and should make IO.binwrite no longer truncate the file when passed an offset.

@atambo atambo merged commit f3374be into master

1 check passed

Details default The Travis CI build passed
@atambo atambo deleted the io_binwrite_dont_truncate_with_offset branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
2  spec/tags/1.9/ruby/core/io/binwrite_tags.txt
@@ -1,5 +1,3 @@
-fails:IO.binwrite doesn't truncate the file and writes the given string if an offset is given
fails:IO.binwrite accepts a :mode option
fails:IO.binwrite raises an error if readonly mode is specified
-fails:IO.binwrite doesn't truncate and writes at the given offset after passing empty opts
fails:IO.binwrite truncates if empty :opts provided and offset skipped
View
34 src/org/jruby/RubyFile.java
@@ -331,15 +331,7 @@ public IRubyObject initialize19(ThreadContext context, IRubyObject[] args, Block
}
}
- RubyBoolean hasOffset = context.runtime.newBoolean(false);
- if (args[args.length - 1] instanceof RubyBoolean) {
- hasOffset = (RubyBoolean) args[args.length - 1];
- IRubyObject[] newArgs = new IRubyObject[args.length - 1];
- System.arraycopy(args, 0, newArgs, 0, newArgs.length);
- args = newArgs;
- }
-
- return openFile19(context, args, hasOffset.isTrue());
+ return openFile19(context, args);
}
@JRubyMethod(required = 1)
@@ -1112,11 +1104,8 @@ public void setEncoding(Encoding encoding) {
// :)
}
- private IRubyObject openFile19(ThreadContext context, IRubyObject args[]) {
- return openFile19(context, args, false);
- }
// mri: rb_open_file + rb_scan_open_args
- private IRubyObject openFile19(ThreadContext context, IRubyObject args[], boolean hasOffset) {
+ private IRubyObject openFile19(ThreadContext context, IRubyObject args[]) {
Ruby runtime = context.runtime;
RubyString filename = get_path(context, args[0]);
@@ -1157,8 +1146,8 @@ private IRubyObject openFile19(ThreadContext context, IRubyObject args[], boolea
int oflags = EncodingUtils.extractModeEncoding(context, this, pm, options, false);
int perm = (pm[EncodingUtils.PERM] != null && !pm[EncodingUtils.PERM].isNil()) ?
RubyNumeric.num2int(pm[EncodingUtils.PERM]) : 0666;
-
- sysopenInternal(path, ModeFlags.createModeFlags(oflags), perm, hasOffset);
+
+ sysopenInternal(path, ModeFlags.createModeFlags(oflags), perm);
return this;
}
@@ -1195,12 +1184,8 @@ private int getFilePermissions(IRubyObject[] args) {
return (args.length > 2 && !args[2].isNil()) ? RubyNumeric.num2int(args[2]) : 438;
}
- protected void sysopenInternal(String path, ModeFlags modes, int perm) {
- sysopenInternal(path, modes, perm, false);
- }
-
// mri: rb_file_open_generic
- protected void sysopenInternal(String path, ModeFlags modes, int perm, boolean hasOffset) {
+ protected void sysopenInternal(String path, ModeFlags modes, int perm) {
if (path.startsWith("jar:")) path = path.substring(4);
openFile = new OpenFile();
@@ -1211,7 +1196,7 @@ protected void sysopenInternal(String path, ModeFlags modes, int perm, boolean h
int umask = getUmaskSafe( getRuntime() );
perm = perm - (perm & umask);
- ChannelDescriptor descriptor = sysopen(path, modes, perm, hasOffset);
+ ChannelDescriptor descriptor = sysopen(path, modes, perm);
openFile.setMainStream(fdopen(descriptor, modes));
if (hasBom) {
// FIXME: Wonky that we acquire RubyEncoding to pass these encodings through
@@ -1253,10 +1238,6 @@ protected void openInternal(String path, String modeString) {
}
private ChannelDescriptor sysopen(String path, ModeFlags modes, int perm) {
- return sysopen(path,modes,perm,false);
- }
-
- private ChannelDescriptor sysopen(String path, ModeFlags modes, int perm, boolean hasOffset) {
try {
ChannelDescriptor descriptor = ChannelDescriptor.open(
getRuntime().getCurrentDirectory(),
@@ -1264,8 +1245,7 @@ private ChannelDescriptor sysopen(String path, ModeFlags modes, int perm, boolea
modes,
perm,
getRuntime().getPosix(),
- getRuntime().getJRubyClassLoader(),
- hasOffset);
+ getRuntime().getJRubyClassLoader());
// TODO: check if too many open files, GC and try again
View
23 src/org/jruby/RubyIO.java
@@ -3605,17 +3605,11 @@ private static IRubyObject read19(ThreadContext context, IRubyObject recv, IRuby
*/
private static IRubyObject write19(ThreadContext context, IRubyObject recv, IRubyObject path, IRubyObject str, IRubyObject offset, RubyHash options) {
// FIXME: process options
- Ruby runtime = context.runtime;
-
- IRubyObject hasOffset = runtime.getNil();
-
- if (!offset.isNil()) hasOffset = runtime.newBoolean(true);
- else hasOffset = runtime.newBoolean(false);
RubyString pathStr = RubyFile.get_path(context, path);
-
+ Ruby runtime = context.runtime;
failIfDirectory(runtime, pathStr);
- RubyIO file = newFile(context, recv, pathStr, context.runtime.newString("w"), hasOffset);
+ RubyIO file = newFile(context, recv, pathStr, context.runtime.newString("w"));
try {
if (!offset.isNil()) file.seek(context, offset);
@@ -3693,7 +3687,7 @@ public static IRubyObject read19(ThreadContext context, IRubyObject recv, IRubyO
return read19(context, recv, path, length, offset, options);
}
- @JRubyMethod(meta = true, required = 2, optional = 1, compat = RUBY1_9)
+ @JRubyMethod(meta = true, required = 2, optional = 2, compat = RUBY1_9)
public static IRubyObject binwrite(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
IRubyObject nil = context.runtime.getNil();
IRubyObject path = args[0];
@@ -3704,7 +3698,16 @@ public static IRubyObject binwrite(ThreadContext context, IRubyObject recv, IRub
if (args.length > 2) {
offset = args[2];
}
- RubyIO file = (RubyIO) Helpers.invoke(context, runtime.getFile(), "new", path, runtime.newString("wb:ASCII-8BIT"));
+
+ long mode = ModeFlags.CREAT | ModeFlags.BINARY;
+
+ if (offset.isNil()) {
+ mode |= ModeFlags.WRONLY;
+ } else {
+ mode |= ModeFlags.RDWR;
+ }
+
+ RubyIO file = (RubyIO) Helpers.invoke(context, runtime.getFile(), "new", path, RubyFixnum.newFixnum(runtime, mode));
try {
if (!offset.isNil()) file.seek(context, offset);
View
8 src/org/jruby/util/io/ChannelDescriptor.java
@@ -790,10 +790,6 @@ public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, i
* @throws java.io.IOException if there is an exception during IO
*/
public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, int perm, POSIX posix, ClassLoader classLoader) throws FileNotFoundException, DirectoryAsFileException, FileExistsException, IOException {
- return open(cwd, path, flags, perm, posix, classLoader, false);
- }
-
- public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, int perm, POSIX posix, ClassLoader classLoader, boolean hasOffset) throws FileNotFoundException, DirectoryAsFileException, FileExistsException, IOException {
boolean fileCreated = false;
if (path.equals("/dev/null") || path.equalsIgnoreCase("nul:") || path.equalsIgnoreCase("nul")) {
Channel nullChannel = new NullChannel();
@@ -881,7 +877,7 @@ public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, i
* we need manual seeking.
*/
boolean isInAppendMode;
- if (flags.isWritable() && !flags.isReadable() && !hasOffset) {
+ if (flags.isWritable() && !flags.isReadable()) {
FileOutputStream fos = new FileOutputStream(theFile, flags.isAppendable());
fileChannel = fos.getChannel();
fileDescriptor = fos.getFD();
@@ -904,7 +900,7 @@ public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, i
}
try {
- if (flags.isTruncate() && !hasOffset) fileChannel.truncate(0);
+ if (flags.isTruncate()) fileChannel.truncate(0);
} catch (IOException ioe) {
if (ioe.getMessage().equals("Illegal seek")) {
// ignore; it's a pipe or fifo that can't be truncated
Something went wrong with that request. Please try again.