@@ -66,6 +66,10 @@ public class RubyFileStat extends RubyObject {
66
66
private FileResource file ;
67
67
private FileStat stat ;
68
68
69
+ private void checkInitialized () {
70
+ if (stat == null ) throw getRuntime ().newTypeError ("uninitialized File::Stat" );
71
+ }
72
+
69
73
private static ObjectAllocator ALLOCATOR = new ObjectAllocator () {
70
74
@ Override
71
75
public IRubyObject allocate (Ruby runtime , RubyClass klass ) {
@@ -148,31 +152,37 @@ public IRubyObject initialize19(IRubyObject fname, Block unusedBlock) {
148
152
149
153
@ JRubyMethod (name = "atime" )
150
154
public IRubyObject atime () {
155
+ checkInitialized ();
151
156
return getRuntime ().newTime (stat .atime () * 1000 );
152
157
}
153
158
154
159
@ JRubyMethod (name = "blksize" )
155
160
public RubyFixnum blksize () {
161
+ checkInitialized ();
156
162
return getRuntime ().newFixnum (stat .blockSize ());
157
163
}
158
164
159
165
@ JRubyMethod (name = "blockdev?" )
160
166
public IRubyObject blockdev_p () {
167
+ checkInitialized ();
161
168
return getRuntime ().newBoolean (stat .isBlockDev ());
162
169
}
163
170
164
171
@ JRubyMethod (name = "blocks" )
165
172
public IRubyObject blocks () {
173
+ checkInitialized ();
166
174
return getRuntime ().newFixnum (stat .blocks ());
167
175
}
168
176
169
177
@ JRubyMethod (name = "chardev?" )
170
178
public IRubyObject chardev_p () {
179
+ checkInitialized ();
171
180
return getRuntime ().newBoolean (stat .isCharDev ());
172
181
}
173
182
174
183
@ JRubyMethod (name = "<=>" , required = 1 )
175
184
public IRubyObject cmp (IRubyObject other ) {
185
+ checkInitialized ();
176
186
if (!(other instanceof RubyFileStat )) return getRuntime ().getNil ();
177
187
178
188
long time1 = stat .mtime ();
@@ -189,63 +199,75 @@ public IRubyObject cmp(IRubyObject other) {
189
199
190
200
@ JRubyMethod (name = "ctime" )
191
201
public IRubyObject ctime () {
202
+ checkInitialized ();
192
203
return getRuntime ().newTime (stat .ctime () * 1000 );
193
204
}
194
205
195
206
@ JRubyMethod (name = "birthtime" )
196
207
public IRubyObject birthtime () {
208
+ checkInitialized ();
197
209
FileTime btime = RubyFile .getBirthtimeWithNIO (file .absolutePath ());
198
210
if (btime != null ) return getRuntime ().newTime (btime .toMillis ());
199
211
return ctime ();
200
212
}
201
213
202
214
@ JRubyMethod (name = "dev" )
203
215
public IRubyObject dev () {
216
+ checkInitialized ();
204
217
return getRuntime ().newFixnum (stat .dev ());
205
218
}
206
219
207
220
@ JRubyMethod (name = "dev_major" )
208
221
public IRubyObject devMajor () {
222
+ checkInitialized ();
209
223
return getRuntime ().newFixnum (stat .major (stat .dev ()));
210
224
}
211
225
212
226
@ JRubyMethod (name = "dev_minor" )
213
227
public IRubyObject devMinor () {
228
+ checkInitialized ();
214
229
return getRuntime ().newFixnum (stat .minor (stat .dev ()));
215
230
}
216
231
217
232
@ JRubyMethod (name = "directory?" )
218
233
public RubyBoolean directory_p () {
234
+ checkInitialized ();
219
235
return getRuntime ().newBoolean (stat .isDirectory ());
220
236
}
221
237
222
238
@ JRubyMethod (name = "executable?" )
223
239
public IRubyObject executable_p () {
240
+ checkInitialized ();
224
241
return getRuntime ().newBoolean (stat .isExecutable ());
225
242
}
226
243
227
244
@ JRubyMethod (name = "executable_real?" )
228
245
public IRubyObject executableReal_p () {
246
+ checkInitialized ();
229
247
return getRuntime ().newBoolean (stat .isExecutableReal ());
230
248
}
231
249
232
250
@ JRubyMethod (name = "file?" )
233
251
public RubyBoolean file_p () {
252
+ checkInitialized ();
234
253
return getRuntime ().newBoolean (stat .isFile ());
235
254
}
236
255
237
256
@ JRubyMethod (name = "ftype" )
238
257
public RubyString ftype () {
258
+ checkInitialized ();
239
259
return getRuntime ().newString (stat .ftype ());
240
260
}
241
261
242
262
@ JRubyMethod (name = "gid" )
243
263
public IRubyObject gid () {
264
+ checkInitialized ();
244
265
return getRuntime ().newFixnum (stat .gid ());
245
266
}
246
267
247
268
@ JRubyMethod (name = "grpowned?" )
248
269
public IRubyObject group_owned_p () {
270
+ checkInitialized ();
249
271
return getRuntime ().newBoolean (stat .isGroupOwned ());
250
272
}
251
273
@@ -268,6 +290,7 @@ public IRubyObject initialize_copy(IRubyObject original) {
268
290
269
291
@ JRubyMethod (name = "ino" )
270
292
public IRubyObject ino () {
293
+ checkInitialized ();
271
294
return getRuntime ().newFixnum (stat .ino ());
272
295
}
273
296
@@ -276,41 +299,48 @@ public IRubyObject ino() {
276
299
public IRubyObject inspect () {
277
300
StringBuilder buf = new StringBuilder ("#<" );
278
301
buf .append (getMetaClass ().getRealClass ().getName ());
279
- buf .append (" " );
280
- // FIXME: Obvious issue that not all platforms can display all attributes. Ugly hacks.
281
- // Using generic posix library makes pushing inspect behavior into specific system impls
282
- // rather painful.
283
- try { buf .append ("dev=0x" ).append (Long .toHexString (stat .dev ())); } catch (Exception e ) {} finally { buf .append (", " ); }
284
- try { buf .append ("ino=" ).append (stat .ino ()); } catch (Exception e ) {} finally { buf .append (", " ); }
285
- buf .append ("mode=0" ).append (Integer .toOctalString (stat .mode ())).append (", " );
286
- try { buf .append ("nlink=" ).append (stat .nlink ()); } catch (Exception e ) {} finally { buf .append (", " ); }
287
- try { buf .append ("uid=" ).append (stat .uid ()); } catch (Exception e ) {} finally { buf .append (", " ); }
288
- try { buf .append ("gid=" ).append (stat .gid ()); } catch (Exception e ) {} finally { buf .append (", " ); }
289
- try { buf .append ("rdev=0x" ).append (Long .toHexString (stat .rdev ())); } catch (Exception e ) {} finally { buf .append (", " ); }
290
- buf .append ("size=" ).append (sizeInternal ()).append (", " );
291
- try { buf .append ("blksize=" ).append (stat .blockSize ()); } catch (Exception e ) {} finally { buf .append (", " ); }
292
- try { buf .append ("blocks=" ).append (stat .blocks ()); } catch (Exception e ) {} finally { buf .append (", " ); }
293
-
294
- buf .append ("atime=" ).append (atime ()).append (", " );
295
- buf .append ("mtime=" ).append (mtime ()).append (", " );
296
- buf .append ("ctime=" ).append (ctime ());
302
+ if (stat == null ) {
303
+ buf .append (": uninitialized" );
304
+ } else {
305
+ buf .append (" " );
306
+ // FIXME: Obvious issue that not all platforms can display all attributes. Ugly hacks.
307
+ // Using generic posix library makes pushing inspect behavior into specific system impls
308
+ // rather painful.
309
+ try { buf .append ("dev=0x" ).append (Long .toHexString (stat .dev ())); } catch (Exception e ) {} finally { buf .append (", " ); }
310
+ try { buf .append ("ino=" ).append (stat .ino ()); } catch (Exception e ) {} finally { buf .append (", " ); }
311
+ buf .append ("mode=0" ).append (Integer .toOctalString (stat .mode ())).append (", " );
312
+ try { buf .append ("nlink=" ).append (stat .nlink ()); } catch (Exception e ) {} finally { buf .append (", " ); }
313
+ try { buf .append ("uid=" ).append (stat .uid ()); } catch (Exception e ) {} finally { buf .append (", " ); }
314
+ try { buf .append ("gid=" ).append (stat .gid ()); } catch (Exception e ) {} finally { buf .append (", " ); }
315
+ try { buf .append ("rdev=0x" ).append (Long .toHexString (stat .rdev ())); } catch (Exception e ) {} finally { buf .append (", " ); }
316
+ buf .append ("size=" ).append (sizeInternal ()).append (", " );
317
+ try { buf .append ("blksize=" ).append (stat .blockSize ()); } catch (Exception e ) {} finally { buf .append (", " ); }
318
+ try { buf .append ("blocks=" ).append (stat .blocks ()); } catch (Exception e ) {} finally { buf .append (", " ); }
319
+
320
+ buf .append ("atime=" ).append (atime ()).append (", " );
321
+ buf .append ("mtime=" ).append (mtime ()).append (", " );
322
+ buf .append ("ctime=" ).append (ctime ());
323
+ }
297
324
buf .append (">" );
298
325
299
326
return getRuntime ().newString (buf .toString ());
300
327
}
301
328
302
329
@ JRubyMethod (name = "uid" )
303
330
public IRubyObject uid () {
331
+ checkInitialized ();
304
332
return getRuntime ().newFixnum (stat .uid ());
305
333
}
306
334
307
335
@ JRubyMethod (name = "mode" )
308
336
public IRubyObject mode () {
337
+ checkInitialized ();
309
338
return getRuntime ().newFixnum (stat .mode ());
310
339
}
311
340
312
341
@ JRubyMethod (name = "mtime" )
313
342
public IRubyObject mtime () {
343
+ checkInitialized ();
314
344
return getRuntime ().newTime (stat .mtime () * 1000 );
315
345
}
316
346
@@ -328,55 +358,66 @@ public IRubyObject mtimeLessThan(IRubyObject other) {
328
358
329
359
@ JRubyMethod (name = "nlink" )
330
360
public IRubyObject nlink () {
361
+ checkInitialized ();
331
362
return getRuntime ().newFixnum (stat .nlink ());
332
363
}
333
364
334
365
@ JRubyMethod (name = "owned?" )
335
366
public IRubyObject owned_p () {
367
+ checkInitialized ();
336
368
return getRuntime ().newBoolean (stat .isOwned ());
337
369
}
338
370
339
371
@ JRubyMethod (name = "pipe?" )
340
372
public IRubyObject pipe_p () {
373
+ checkInitialized ();
341
374
return getRuntime ().newBoolean (stat .isNamedPipe ());
342
375
}
343
376
344
377
@ JRubyMethod (name = "rdev" )
345
378
public IRubyObject rdev () {
379
+ checkInitialized ();
346
380
return getRuntime ().newFixnum (stat .rdev ());
347
381
}
348
382
349
383
@ JRubyMethod (name = "rdev_major" )
350
384
public IRubyObject rdevMajor () {
385
+ checkInitialized ();
351
386
return getRuntime ().newFixnum (stat .major (stat .rdev ()));
352
387
}
353
388
354
389
@ JRubyMethod (name = "rdev_minor" )
355
390
public IRubyObject rdevMinor () {
391
+ checkInitialized ();
356
392
return getRuntime ().newFixnum (stat .minor (stat .rdev ()));
357
393
}
358
394
359
395
@ JRubyMethod (name = "readable?" )
360
396
public IRubyObject readable_p () {
397
+ checkInitialized ();
361
398
return getRuntime ().newBoolean (stat .isReadable ());
362
399
}
363
400
364
401
@ JRubyMethod (name = "readable_real?" )
365
402
public IRubyObject readableReal_p () {
403
+ checkInitialized ();
366
404
return getRuntime ().newBoolean (stat .isReadableReal ());
367
405
}
368
406
369
407
@ JRubyMethod (name = "setgid?" )
370
408
public IRubyObject setgid_p () {
409
+ checkInitialized ();
371
410
return getRuntime ().newBoolean (stat .isSetgid ());
372
411
}
373
412
374
413
@ JRubyMethod (name = "setuid?" )
375
414
public IRubyObject setuid_p () {
415
+ checkInitialized ();
376
416
return getRuntime ().newBoolean (stat .isSetuid ());
377
417
}
378
418
379
419
private long sizeInternal () {
420
+ checkInitialized ();
380
421
// Workaround for JRUBY-4149
381
422
if (Platform .IS_WINDOWS && file != null ) {
382
423
try {
@@ -405,11 +446,13 @@ public IRubyObject size_p() {
405
446
406
447
@ JRubyMethod (name = "socket?" )
407
448
public IRubyObject socket_p () {
449
+ checkInitialized ();
408
450
return getRuntime ().newBoolean (stat .isSocket ());
409
451
}
410
452
411
453
@ JRubyMethod (name = "sticky?" )
412
454
public IRubyObject sticky_p () {
455
+ checkInitialized ();
413
456
Ruby runtime = getRuntime ();
414
457
415
458
if (runtime .getPosix ().isNative ()) {
@@ -421,21 +464,25 @@ public IRubyObject sticky_p() {
421
464
422
465
@ JRubyMethod (name = "symlink?" )
423
466
public IRubyObject symlink_p () {
467
+ checkInitialized ();
424
468
return getRuntime ().newBoolean (stat .isSymlink ());
425
469
}
426
470
427
471
@ JRubyMethod (name = "writable?" )
428
472
public IRubyObject writable_p () {
473
+ checkInitialized ();
429
474
return getRuntime ().newBoolean (stat .isWritable ());
430
475
}
431
476
432
477
@ JRubyMethod (name = "writable_real?" )
433
478
public IRubyObject writableReal_p () {
479
+ checkInitialized ();
434
480
return getRuntime ().newBoolean (stat .isWritableReal ());
435
481
}
436
482
437
483
@ JRubyMethod (name = "zero?" )
438
484
public IRubyObject zero_p () {
485
+ checkInitialized ();
439
486
return getRuntime ().newBoolean (stat .isEmpty ());
440
487
}
441
488
@@ -450,6 +497,7 @@ public IRubyObject worldWritable(ThreadContext context) {
450
497
}
451
498
452
499
private IRubyObject getWorldMode (ThreadContext context , int mode ) {
500
+ checkInitialized ();
453
501
if ((stat .mode () & mode ) == mode ) {
454
502
return RubyNumeric .int2fix (context .runtime ,
455
503
(stat .mode () & (S_IRUGO | S_IWUGO | S_IXUGO ) ));
0 commit comments