@@ -321,89 +321,101 @@ public void doInit(VirtualFrame frame, PFileIO self, Object nameobj, IONodes.IOM
321
321
int flags = processMode (self , mode );
322
322
auditNode .audit (OPEN , nameobj , mode .mode , flags );
323
323
324
- boolean fdIsOwn = false ;
325
- PythonContext ctxt = PythonContext .get (this );
326
- if (fd >= 0 ) {
327
- self .setCloseFD (closefd );
328
- self .setFD (fd , ctxt );
329
- } else {
330
- self .setCloseFD (true );
331
- if (errorProfile .profile (!closefd )) {
332
- throw raise (ValueError , CANNOT_USE_CLOSEFD );
333
- }
334
-
335
- if (opener instanceof PNone ) {
336
- self .setFD (open (frame , name , flags , 0666 , ctxt , posixLib , exceptionProfile ), ctxt );
324
+ try {
325
+ boolean fdIsOwn = false ;
326
+ PythonContext ctxt = PythonContext .get (this );
327
+ if (fd >= 0 ) {
328
+ self .setCloseFD (closefd );
329
+ self .setFD (fd , ctxt );
337
330
} else {
338
- Object fdobj = callOpener . execute ( frame , opener , nameobj , flags );
339
- if (! indexCheckNode . execute ( fdobj )) {
340
- throw raise (TypeError , EXPECTED_INT_FROM_OPENER );
331
+ self . setCloseFD ( true );
332
+ if (errorProfile . profile (! closefd )) {
333
+ throw raise (ValueError , CANNOT_USE_CLOSEFD );
341
334
}
342
335
343
- self .setFD (asSizeNode .executeExact (frame , fdobj ), ctxt );
344
- if (self .getFD () < 0 ) {
345
- /*
346
- * The opener returned a negative but didn't set an exception. See issue
347
- * #27066
348
- */
349
- throw raise (ValueError , OPENER_RETURNED_D , self .getFD ());
336
+ if (opener instanceof PNone ) {
337
+ self .setFD (open (frame , name , flags , 0666 , ctxt , posixLib , exceptionProfile ), ctxt );
338
+ } else {
339
+ Object fdobj = callOpener .execute (frame , opener , nameobj , flags );
340
+ if (!indexCheckNode .execute (fdobj )) {
341
+ throw raise (TypeError , EXPECTED_INT_FROM_OPENER );
342
+ }
343
+
344
+ self .setFD (asSizeNode .executeExact (frame , fdobj ), ctxt );
345
+ if (self .getFD () < 0 ) {
346
+ /*
347
+ * The opener returned a negative but didn't set an exception. See issue
348
+ * #27066
349
+ */
350
+ throw raise (ValueError , OPENER_RETURNED_D , self .getFD ());
351
+ }
350
352
}
353
+ try {
354
+ posixLib .setInheritable (ctxt .getPosixSupport (), self .getFD (), false );
355
+ } catch (PosixSupportLibrary .PosixException e ) {
356
+ exceptionProfile .enter ();
357
+ throw raiseOSErrorFromPosixException (frame , e );
358
+ }
359
+ fdIsOwn = true ;
351
360
}
361
+ self .setBlksize (DEFAULT_BUFFER_SIZE );
352
362
try {
353
- posixLib .setInheritable (ctxt .getPosixSupport (), self .getFD (), false );
354
- } catch (PosixSupportLibrary .PosixException e ) {
355
- exceptionProfile .enter ();
356
- throw raiseOSErrorFromPosixException (frame , e );
357
- }
358
- fdIsOwn = true ;
359
- }
360
- self .setBlksize (DEFAULT_BUFFER_SIZE );
361
- try {
362
- long [] fstatResult = posixLib .fstat (ctxt .getPosixSupport (), self .getFD ());
363
- /*
364
- * On Unix, open will succeed for directories. In Python, there should be no file
365
- * objects referring to directories, so we need a check.
366
- */
367
- if (errorProfile .profile (PosixSupportLibrary .isDIR (fstatResult [0 ]))) {
368
- errorCleanup (frame , self , fdIsOwn , posixClose );
369
- name = name == null ? Integer .toString (fd ) : name ;
370
- throw raiseOSError (frame , OSErrorEnum .EISDIR , name );
371
- }
372
- /*
373
- * // TODO: read fstatResult.st_blksize if (fstatResult[8] > 1)
374
- * self.setBlksize(fstatResult[8]); }
375
- */
376
- } catch (PosixSupportLibrary .PosixException e ) {
377
- exceptionProfile .enter ();
378
- /*
379
- * Tolerate fstat() errors other than EBADF. See Issue #25717, where an anonymous
380
- * file on a Virtual Box shared folder filesystem would raise ENOENT.
381
- */
382
- if (e .getErrorCode () == OSErrorEnum .EBADF .getNumber ()) {
383
- errorCleanup (frame , self , fdIsOwn , posixClose );
384
- throw raiseOSErrorFromPosixException (frame , e );
385
- }
386
- }
387
- setAttr .execute (frame , self , NAME , nameobj );
388
-
389
- if (self .isAppending ()) {
390
- /*
391
- * For consistent behaviour, we explicitly seek to the end of file (otherwise, it
392
- * might be done only on the first write()).
393
- */
394
- try {
395
- long res = posixLib .lseek (ctxt .getPosixSupport (), self .getFD (), 0 , mapPythonSeekWhenceToPosix (SEEK_END ));
396
- self .setSeekable (res >= 0 ? 1 : 0 );
363
+ long [] fstatResult = posixLib .fstat (ctxt .getPosixSupport (), self .getFD ());
364
+ /*
365
+ * On Unix, open will succeed for directories. In Python, there should be no
366
+ * file objects referring to directories, so we need a check.
367
+ */
368
+ if (errorProfile .profile (PosixSupportLibrary .isDIR (fstatResult [0 ]))) {
369
+ errorCleanup (frame , self , fdIsOwn , posixClose );
370
+ name = name == null ? Integer .toString (fd ) : name ;
371
+ throw raiseOSError (frame , OSErrorEnum .EISDIR , name );
372
+ }
373
+ /*
374
+ * TODO: read fstatResult.st_blksize if (fstatResult[8] > 1)
375
+ * self.setBlksize(fstatResult[8]); }
376
+ */
397
377
} catch (PosixSupportLibrary .PosixException e ) {
398
378
exceptionProfile .enter ();
399
- if (self .getSeekable () < 0 ) {
400
- self .setSeekable (0 );
401
- }
402
- if (e .getErrorCode () != OSErrorEnum .ESPIPE .getNumber ()) {
379
+ /*
380
+ * Tolerate fstat() errors other than EBADF. See Issue #25717, where an
381
+ * anonymous file on a Virtual Box shared folder filesystem would raise ENOENT.
382
+ */
383
+ if (e .getErrorCode () == OSErrorEnum .EBADF .getNumber ()) {
403
384
errorCleanup (frame , self , fdIsOwn , posixClose );
404
385
throw raiseOSErrorFromPosixException (frame , e );
405
386
}
406
387
}
388
+ setAttr .execute (frame , self , NAME , nameobj );
389
+
390
+ if (self .isAppending ()) {
391
+ /*
392
+ * For consistent behaviour, we explicitly seek to the end of file (otherwise,
393
+ * it might be done only on the first write()).
394
+ */
395
+ try {
396
+ long res = posixLib .lseek (ctxt .getPosixSupport (), self .getFD (), 0 , mapPythonSeekWhenceToPosix (SEEK_END ));
397
+ self .setSeekable (res >= 0 ? 1 : 0 );
398
+ } catch (PosixSupportLibrary .PosixException e ) {
399
+ exceptionProfile .enter ();
400
+ if (self .getSeekable () < 0 ) {
401
+ self .setSeekable (0 );
402
+ }
403
+ if (e .getErrorCode () != OSErrorEnum .ESPIPE .getNumber ()) {
404
+ errorCleanup (frame , self , fdIsOwn , posixClose );
405
+ throw raiseOSErrorFromPosixException (frame , e );
406
+ }
407
+ }
408
+ }
409
+ } catch (PException e ) {
410
+ /*
411
+ * IMPORTANT: In case of any error that happens during initialization, we need reset
412
+ * the file descriptor such that the finalizer won't close it. This is necessary
413
+ * because the file descriptor value could be reused and then this (broken) instance
414
+ * would incorrectly close another resource that accidentally got the same file
415
+ * descriptor value.
416
+ */
417
+ self .setClosed ();
418
+ throw e ;
407
419
}
408
420
}
409
421
0 commit comments