@@ -1168,6 +1168,51 @@ void SharedMemoryBase::unlinkFile(const TEXT* expanded_filename) noexcept
1168
1168
1169
1169
#ifdef UNIX
1170
1170
1171
+ static inline void reportError (const char * func, CheckStatusWrapper* statusVector)
1172
+ {
1173
+ if (!statusVector)
1174
+ system_call_failed::raise (func);
1175
+ else
1176
+ error (statusVector, func, errno);
1177
+ }
1178
+
1179
+ bool allocFileSpace (int fd, off_t offset, FB_SIZE_T length, CheckStatusWrapper* statusVector)
1180
+ {
1181
+ #if defined(HAVE_LINUX_FALLOC_H) && defined(HAVE_FALLOCATE)
1182
+ if (fallocate (fd, 0 , offset, length))
1183
+ {
1184
+ reportError (" fallocate" , statusVector);
1185
+ return false ;
1186
+ }
1187
+ #else
1188
+ static const FB_SIZE_T buf128KSize = 131072 ;
1189
+ HalfStaticArray<UCHAR, BUFFER_LARGE> buf;
1190
+ const FB_SIZE_T bufSize = length < buf128KSize ? length : buf128KSize;
1191
+
1192
+ memset (buf.getBuffer (bufSize), 0 , bufSize);
1193
+ os_utils::lseek (fd, LSEEK_OFFSET_CAST offset, SEEK_SET);
1194
+
1195
+ while (length)
1196
+ {
1197
+ const FB_SIZE_T cnt = length < bufSize ? length : bufSize;
1198
+ if (write (fd, buf.begin (), cnt) != (ssize_t ) cnt)
1199
+ {
1200
+ reportError (" write" , statusVector);
1201
+ return false ;
1202
+ }
1203
+ length -= cnt;
1204
+ }
1205
+
1206
+ if (fsync (fd))
1207
+ {
1208
+ reportError (" fsync" , statusVector);
1209
+ return false ;
1210
+ }
1211
+ #endif
1212
+ return true ;
1213
+ }
1214
+
1215
+
1171
1216
void SharedMemoryBase::internalUnmap ()
1172
1217
{
1173
1218
if (sh_mem_header)
@@ -1303,7 +1348,10 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
1303
1348
if (mainLock->setlock (&statusVector, FileLock::FLM_TRY_EXCLUSIVE))
1304
1349
{
1305
1350
if (trunc_flag)
1351
+ {
1306
1352
FB_UNUSED (os_utils::ftruncate (mainLock->getFd (), length));
1353
+ allocFileSpace (mainLock->getFd (), 0 , length, NULL );
1354
+ }
1307
1355
1308
1356
if (callback->initialize (this , true ))
1309
1357
{
@@ -2436,8 +2484,19 @@ bool SharedMemoryBase::remapFile(CheckStatusWrapper* statusVector, ULONG new_len
2436
2484
}
2437
2485
2438
2486
if (flag)
2487
+ {
2439
2488
FB_UNUSED (os_utils::ftruncate (mainLock->getFd (), new_length));
2440
2489
2490
+ if (new_length > sh_mem_length_mapped)
2491
+ {
2492
+ if (!allocFileSpace (mainLock->getFd (), sh_mem_length_mapped,
2493
+ new_length - sh_mem_length_mapped, statusVector))
2494
+ {
2495
+ return false ;
2496
+ }
2497
+ }
2498
+ }
2499
+
2441
2500
MemoryHeader* const address = (MemoryHeader*) os_utils::mmap (0 , new_length,
2442
2501
PROT_READ | PROT_WRITE, MAP_SHARED, mainLock->getFd (), 0 );
2443
2502
0 commit comments