Skip to content

Commit fa798a2

Browse files
committedFeb 13, 2018
Merge pull request #4795 from alexis779/master
[#4710] nanosecond precision in utime using libc futimens
1 parent cd56bd7 commit fa798a2

File tree

1 file changed

+34
-42
lines changed

1 file changed

+34
-42
lines changed
 

‎core/src/main/java/org/jruby/RubyFile.java

+34-42
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@
3535
***** END LICENSE BLOCK *****/
3636
package org.jruby;
3737

38+
import jnr.constants.platform.OpenFlags;
39+
import jnr.posix.POSIX;
40+
import jnr.posix.util.Platform;
41+
import org.jcodings.Encoding;
42+
import org.jruby.anno.JRubyClass;
43+
import org.jruby.anno.JRubyMethod;
44+
import org.jruby.runtime.*;
45+
import org.jruby.runtime.JavaSites.FileSites;
46+
import org.jruby.runtime.builtin.IRubyObject;
47+
import org.jruby.runtime.encoding.EncodingCapable;
48+
import org.jruby.runtime.encoding.EncodingService;
49+
import org.jruby.util.*;
50+
import org.jruby.util.io.EncodingUtils;
51+
import org.jruby.util.io.IOEncodable;
52+
import org.jruby.util.io.OpenFile;
53+
import org.jruby.util.io.PosixShim;
54+
3855
import java.io.File;
3956
import java.io.IOException;
4057
import java.io.InputStream;
@@ -58,32 +75,7 @@
5875
import java.util.zip.ZipEntry;
5976
import java.util.zip.ZipFile;
6077

61-
import jnr.constants.platform.OpenFlags;
62-
import jnr.posix.POSIX;
63-
import jnr.posix.util.Platform;
64-
import org.jcodings.Encoding;
65-
import org.jruby.anno.JRubyClass;
66-
import org.jruby.anno.JRubyMethod;
67-
import org.jruby.runtime.Block;
68-
import org.jruby.runtime.ClassIndex;
69-
import org.jruby.runtime.JavaSites.FileSites;
70-
import org.jruby.runtime.ObjectAllocator;
71-
import org.jruby.runtime.ThreadContext;
72-
import static org.jruby.runtime.Visibility.*;
73-
import org.jruby.runtime.builtin.IRubyObject;
74-
import org.jruby.runtime.encoding.EncodingCapable;
75-
import org.jruby.util.ByteList;
76-
import org.jruby.util.FileResource;
77-
import org.jruby.util.JRubyFile;
78-
import org.jruby.util.StringSupport;
79-
import org.jruby.util.TypeConverter;
80-
import org.jruby.util.io.EncodingUtils;
81-
import org.jruby.util.io.IOEncodable;
82-
import org.jruby.util.io.OpenFile;
83-
import org.jruby.runtime.Helpers;
84-
import org.jruby.runtime.encoding.EncodingService;
85-
import org.jruby.util.io.PosixShim;
86-
78+
import static org.jruby.runtime.Visibility.PRIVATE;
8779
import static org.jruby.util.io.EncodingUtils.vmode;
8880
import static org.jruby.util.io.EncodingUtils.vperm;
8981

@@ -1150,12 +1142,12 @@ public static IRubyObject umask(ThreadContext context, IRubyObject recv, IRubyOb
11501142
@JRubyMethod(required = 2, rest = true, meta = true)
11511143
public static IRubyObject utime(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
11521144
Ruby runtime = context.runtime;
1153-
long[] atimeval = null;
1154-
long[] mtimeval = null;
1145+
long[] atimespec = null;
1146+
long[] mtimespec = null;
11551147

1156-
if (args[0] != runtime.getNil() || args[1] != runtime.getNil()) {
1157-
atimeval = extractTimeval(context, args[0]);
1158-
mtimeval = extractTimeval(context, args[1]);
1148+
if (args[0] != context.nil || args[1] != context.nil) {
1149+
atimespec = extractTimespec(context, args[0]);
1150+
mtimespec = extractTimespec(context, args[1]);
11591151
}
11601152

11611153
for (int i = 2, j = args.length; i < j; i++) {
@@ -1167,7 +1159,7 @@ public static IRubyObject utime(ThreadContext context, IRubyObject recv, IRubyOb
11671159
throw runtime.newErrnoENOENTError(filename.toString());
11681160
}
11691161

1170-
int result = runtime.getPosix().utimes(fileToTouch.getAbsolutePath(), atimeval, mtimeval);
1162+
int result = runtime.getPosix().utimensat(0, fileToTouch.getAbsolutePath(), atimespec, mtimespec, 0);
11711163
if (result == -1) {
11721164
throw runtime.newErrnoFromInt(runtime.getPosix().errno());
11731165
}
@@ -1554,31 +1546,31 @@ static String adjustRootPathOnWindows(Ruby runtime, String path, String dir) {
15541546
}
15551547

15561548
/**
1557-
* Extract a timeval (an array of 2 longs: seconds and microseconds from epoch) from
1549+
* Extract a timespec (an array of 2 longs: seconds and nanoseconds from epoch) from
15581550
* an IRubyObject.
15591551
*/
1560-
private static long[] extractTimeval(ThreadContext context, IRubyObject value) {
1561-
long[] timeval = new long[2];
1552+
private static long[] extractTimespec(ThreadContext context, IRubyObject value) {
1553+
long[] timespec = new long[2];
15621554

15631555
if (value instanceof RubyFloat) {
1564-
timeval[0] = Platform.IS_32_BIT ? RubyNumeric.num2int(value) : RubyNumeric.num2long(value);
1556+
timespec[0] = Platform.IS_32_BIT ? RubyNumeric.num2int(value) : RubyNumeric.num2long(value);
15651557
double fraction = ((RubyFloat) value).getDoubleValue() % 1.0;
1566-
timeval[1] = (long)(fraction * 1e6 + 0.5);
1558+
timespec[1] = (long)(fraction * 1e9 + 0.5);
15671559
} else if (value instanceof RubyNumeric) {
1568-
timeval[0] = Platform.IS_32_BIT ? RubyNumeric.num2int(value) : RubyNumeric.num2long(value);
1569-
timeval[1] = 0;
1560+
timespec[0] = Platform.IS_32_BIT ? RubyNumeric.num2int(value) : RubyNumeric.num2long(value);
1561+
timespec[1] = 0;
15701562
} else {
15711563
RubyTime time;
15721564
if (value instanceof RubyTime) {
15731565
time = ((RubyTime) value);
15741566
} else {
15751567
time = (RubyTime) TypeConverter.convertToType(context, value, context.runtime.getTime(), sites(context).to_time_checked, true);
15761568
}
1577-
timeval[0] = Platform.IS_32_BIT ? RubyNumeric.num2int(time.to_i()) : RubyNumeric.num2long(time.to_i());
1578-
timeval[1] = Platform.IS_32_BIT ? RubyNumeric.num2int(time.usec()) : RubyNumeric.num2long(time.usec());
1569+
timespec[0] = Platform.IS_32_BIT ? RubyNumeric.num2int(time.to_i()) : RubyNumeric.num2long(time.to_i());
1570+
timespec[1] = Platform.IS_32_BIT ? RubyNumeric.num2int(time.nsec()) : RubyNumeric.num2long(time.nsec());
15791571
}
15801572

1581-
return timeval;
1573+
return timespec;
15821574
}
15831575

15841576
private void checkClosed(ThreadContext context) {

0 commit comments

Comments
 (0)