39
39
* for a long time, like relation files. It is the caller's responsibility
40
40
* to close them, there is no automatic mechanism in fd.c for that.
41
41
*
42
+ * PathNameCreateTemporaryFile and PathNameOpenTemporaryFile are used for
43
+ * temporary files that may be shared between backends. A File created or
44
+ * opened with these functions is not automatically deleted when the file is
45
+ * closed, but it is automatically closed and end of transaction and counts
46
+ * agains the temporary file limit of the backend that created it. Any File
47
+ * created this way must be explicitly deleted with PathNameDelete. Automatic
48
+ * file deletion is not provided because this interface is designed for use by
49
+ * buffile.c and indirectly by sharedbuffile.c to implement temporary files
50
+ * with shared ownership and cleanup.
51
+ *
42
52
* AllocateFile, AllocateDir, OpenPipeStream and OpenTransientFile are
43
53
* wrappers around fopen(3), opendir(3), popen(3) and open(2), respectively.
44
54
* They behave like the corresponding native functions, except that the handle
@@ -171,7 +181,7 @@ int max_safe_fds = 32; /* default if not changed */
171
181
172
182
/* these are the assigned bits in fdstate below: */
173
183
#define FD_DELETE_AT_CLOSE (1 << 0) /* T = delete when closed */
174
- #define FD_DELETE_AT_EOXACT (1 << 1) /* T = delete at eoXact */
184
+ #define FD_CLOSE_AT_EOXACT (1 << 1) /* T = close at eoXact */
175
185
#define FD_TEMP_FILE_LIMIT (1 << 2) /* T = respect temp_file_limit */
176
186
177
187
typedef struct vfd
@@ -1383,7 +1393,7 @@ OpenTemporaryFile(bool interXact)
1383
1393
/* Register it with the current resource owner */
1384
1394
if (!interXact )
1385
1395
{
1386
- VfdCache [file ].fdstate |= FD_DELETE_AT_EOXACT ;
1396
+ VfdCache [file ].fdstate |= FD_CLOSE_AT_EOXACT ;
1387
1397
1388
1398
ResourceOwnerEnlargeFiles (CurrentResourceOwner );
1389
1399
ResourceOwnerRememberFile (CurrentResourceOwner , file );
@@ -1437,9 +1447,9 @@ OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
1437
1447
1438
1448
/*
1439
1449
* Create a new file, and also the directory that contains it if necessary.
1440
- * Files created this way are subject to temp_file_limit, but are not
1441
- * automatically deleted on close or at end of transaction because they are
1442
- * intended to be shared between cooperating backends. .
1450
+ * Files created this way are subject to temp_file_limit and are automatically
1451
+ * closed at end of transaction, but are not automatically deleted on close
1452
+ * because they are intended to be shared between cooperating backends.
1443
1453
*/
1444
1454
File
1445
1455
PathNameCreateTemporaryFile (char * tempdirpath , char * tempfilepath ,
@@ -1474,10 +1484,56 @@ PathNameCreateTemporaryFile(char *tempdirpath, char *tempfilepath,
1474
1484
tempfilepath );
1475
1485
}
1476
1486
1477
- if (file >= 0 )
1487
+ if (file > 0 )
1478
1488
{
1479
- /* Mark it for temp_file_limit accounting */
1489
+ /* Mark it for temp_file_limit accounting. */
1480
1490
VfdCache [file ].fdstate |= FD_TEMP_FILE_LIMIT ;
1491
+
1492
+ /*
1493
+ * We don't set FD_DELETE_AT_CLOSE for files opened this way, but we
1494
+ * still want to make sure they get closed at end of xact.
1495
+ */
1496
+ ResourceOwnerEnlargeFiles (CurrentResourceOwner );
1497
+ ResourceOwnerRememberFile (CurrentResourceOwner , file );
1498
+ VfdCache [file ].resowner = CurrentResourceOwner ;
1499
+
1500
+ /* Backup mechanism for closing at end of xact. */
1501
+ VfdCache [file ].fdstate |= FD_CLOSE_AT_EOXACT ;
1502
+ have_xact_temporary_files = true;
1503
+ }
1504
+
1505
+ return file ;
1506
+ }
1507
+
1508
+ /*
1509
+ * Open a file that was created with PathNameCreateTemporaryFile in another
1510
+ * backend. Files opened this way don't count agains the temp_file_limit of
1511
+ * the caller, are read-only and are automatically closed at the end of the
1512
+ * transaction but are not deleted on close.
1513
+ */
1514
+ File
1515
+ PathNameOpenTemporaryFile (char * tempfilepath )
1516
+ {
1517
+ File file ;
1518
+
1519
+ /*
1520
+ * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1521
+ * temp file that can be reused.
1522
+ */
1523
+ file = PathNameOpenFile (tempfilepath , O_RDONLY | PG_BINARY , 0 );
1524
+ if (file > 0 )
1525
+ {
1526
+ /*
1527
+ * We don't set FD_DELETE_AT_CLOSE for files opened this way, but we
1528
+ * still want to make sure they get closed at end of xact.
1529
+ */
1530
+ ResourceOwnerEnlargeFiles (CurrentResourceOwner );
1531
+ ResourceOwnerRememberFile (CurrentResourceOwner , file );
1532
+ VfdCache [file ].resowner = CurrentResourceOwner ;
1533
+
1534
+ /* Backup mechanism for closing at end of xact. */
1535
+ VfdCache [file ].fdstate |= FD_CLOSE_AT_EOXACT ;
1536
+ have_xact_temporary_files = true;
1481
1537
}
1482
1538
1483
1539
return file ;
@@ -2659,7 +2715,8 @@ CleanupTempFiles(bool isProcExit)
2659
2715
{
2660
2716
unsigned short fdstate = VfdCache [i ].fdstate ;
2661
2717
2662
- if ((fdstate & FD_DELETE_AT_CLOSE ) && VfdCache [i ].fileName != NULL )
2718
+ if (((fdstate & FD_DELETE_AT_CLOSE ) || (fdstate & FD_CLOSE_AT_EOXACT )) &&
2719
+ VfdCache [i ].fileName != NULL )
2663
2720
{
2664
2721
/*
2665
2722
* If we're in the process of exiting a backend process, close
@@ -2670,7 +2727,7 @@ CleanupTempFiles(bool isProcExit)
2670
2727
*/
2671
2728
if (isProcExit )
2672
2729
FileClose (i );
2673
- else if (fdstate & FD_DELETE_AT_EOXACT )
2730
+ else if (fdstate & FD_CLOSE_AT_EOXACT )
2674
2731
{
2675
2732
elog (WARNING ,
2676
2733
"temporary file %s not closed at end-of-transaction" ,
0 commit comments