• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

llnl / dftracer-utils / 23730905027

30 Mar 2026 06:22AM UTC coverage: 51.451% (+0.4%) from 51.022%
23730905027

push

github

rayandrew
chore(docs)!: regenerate C++ API reference pages from Doxygen XML

- Add generate_api_index.py script for automated API doc generation
- Rename core_common.rst to core_infrastructure.rst
- Update all API reference pages with current class/function signatures
- Add doxygen group annotations to public headers

BREAKING CHANGE: API reference page structure reorganized

23019 of 57787 branches covered (39.83%)

Branch coverage included in aggregate %.

20057 of 25936 relevant lines covered (77.33%)

13268.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.6
/src/dftracer/utils/core/sqlite/vfs.cpp
1
#include <dftracer/utils/core/io/io_backend.h>
2
#include <dftracer/utils/core/pipeline/executor.h>
3
#include <dftracer/utils/core/sqlite/vfs.h>
4
#include <fcntl.h>
5
#include <sqlite3.h>
6
#include <sys/mman.h>
7
#include <sys/stat.h>
8
#include <unistd.h>
9

10
#include <cerrno>
11
#include <cstdio>
12
#include <cstdlib>
13
#include <cstring>
14

15
namespace dftracer::utils::sqlite {
16

17
// Forward declarations of all VFS methods
18
static int dftracer_sqlite_vfs_open(sqlite3_vfs *pVfs, const char *zName,
19
                                    sqlite3_file *pFile, int flags,
20
                                    int *pOutFlags);
21
static int dftracer_sqlite_vfs_delete(sqlite3_vfs *pVfs, const char *zPath,
22
                                      int dirSync);
23
static int dftracer_sqlite_vfs_access(sqlite3_vfs *pVfs, const char *zPath,
24
                                      int flags, int *pResOut);
25
static int dftracer_sqlite_vfs_fullpathname(sqlite3_vfs *pVfs,
26
                                            const char *zName, int nOut,
27
                                            char *zOut);
28
static int dftracer_sqlite_vfs_get_last_error(sqlite3_vfs *pVfs, int nBuf,
29
                                              char *zBuf);
30

31
// Forward declarations of all io_methods
32
static int dftracer_sqlite_vfs_close(sqlite3_file *pFile);
33
static int dftracer_sqlite_vfs_read(sqlite3_file *pFile, void *buf, int amt,
34
                                    sqlite3_int64 offset);
35
static int dftracer_sqlite_vfs_write(sqlite3_file *pFile, const void *buf,
36
                                     int amt, sqlite3_int64 offset);
37
static int dftracer_sqlite_vfs_truncate(sqlite3_file *pFile,
38
                                        sqlite3_int64 size);
39
static int dftracer_sqlite_vfs_sync(sqlite3_file *pFile, int flags);
40
static int dftracer_sqlite_vfs_file_size(sqlite3_file *pFile,
41
                                         sqlite3_int64 *pSize);
42
static int dftracer_sqlite_vfs_lock(sqlite3_file *pFile, int eLock);
43
static int dftracer_sqlite_vfs_unlock(sqlite3_file *pFile, int eLock);
44
static int dftracer_sqlite_vfs_check_reserved_lock(sqlite3_file *pFile,
45
                                                   int *pResOut);
46
static int dftracer_sqlite_vfs_file_control(sqlite3_file *pFile, int op,
47
                                            void *pArg);
48
static int dftracer_sqlite_vfs_sector_size(sqlite3_file *pFile);
49
static int dftracer_sqlite_vfs_device_characteristics(sqlite3_file *pFile);
50
static int dftracer_sqlite_vfs_shm_map(sqlite3_file *pFile, int iRegion,
51
                                       int szRegion, int bExtend,
52
                                       void volatile **pp);
53
static int dftracer_sqlite_vfs_shm_lock(sqlite3_file *pFile, int offset, int n,
54
                                        int flags);
55
static void dftracer_sqlite_vfs_shm_barrier(sqlite3_file *pFile);
56
static int dftracer_sqlite_vfs_shm_unmap(sqlite3_file *pFile, int deleteFlag);
57
static int dftracer_sqlite_vfs_fetch(sqlite3_file *pFile, sqlite3_int64 offset,
58
                                     int amt, void **pp);
59
static int dftracer_sqlite_vfs_unfetch(sqlite3_file *pFile,
60
                                       sqlite3_int64 offset, void *p);
61

62
// Static io_methods struct (iVersion=3 for WAL + mmap)
63
static sqlite3_io_methods dftracer_sqlite_vfs_io_methods = {
64
    3,                                           // iVersion
65
    dftracer_sqlite_vfs_close,                   // xClose
66
    dftracer_sqlite_vfs_read,                    // xRead
67
    dftracer_sqlite_vfs_write,                   // xWrite
68
    dftracer_sqlite_vfs_truncate,                // xTruncate
69
    dftracer_sqlite_vfs_sync,                    // xSync
70
    dftracer_sqlite_vfs_file_size,               // xFileSize
71
    dftracer_sqlite_vfs_lock,                    // xLock
72
    dftracer_sqlite_vfs_unlock,                  // xUnlock
73
    dftracer_sqlite_vfs_check_reserved_lock,     // xCheckReservedLock
74
    dftracer_sqlite_vfs_file_control,            // xFileControl
75
    dftracer_sqlite_vfs_sector_size,             // xSectorSize
76
    dftracer_sqlite_vfs_device_characteristics,  // xDeviceCharacteristics
77
    dftracer_sqlite_vfs_shm_map,                 // xShmMap
78
    dftracer_sqlite_vfs_shm_lock,                // xShmLock
79
    dftracer_sqlite_vfs_shm_barrier,             // xShmBarrier
80
    dftracer_sqlite_vfs_shm_unmap,               // xShmUnmap
81
    dftracer_sqlite_vfs_fetch,                   // xFetch
82
    dftracer_sqlite_vfs_unfetch,                 // xUnfetch
83
};
84

85
// Static VFS instance and app data
86
static sqlite3_vfs dftracer_vfs_instance;
87
static DfTracerSqliteVfsAppData *dftracer_vfs_app_data = nullptr;
88
static bool dftracer_vfs_registered = false;
89

90
// ============================================================================
91
// sqlite3_io_methods implementations
92
// ============================================================================
93

94
static int dftracer_sqlite_vfs_close(sqlite3_file *pFile) {
×
95
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
96

97
    // Clean up SHM resources
98
    for (int i = 0; i < vf->n_shm_region; ++i) {
×
99
        if (vf->shm_regions[i] != nullptr) {
×
100
            ::munmap(vf->shm_regions[i], 32768);
×
101
            vf->shm_regions[i] = nullptr;
×
102
        }
103
    }
104
    if (vf->shm_fd >= 0) {
×
105
        ::close(vf->shm_fd);
×
106
        vf->shm_fd = -1;
×
107
    }
108

109
    if (vf->fd >= 0) {
×
110
        ::close(vf->fd);
×
111
        vf->fd = -1;
×
112
    }
113

114
    vf->path[0] = '\0';
×
115

116
    return SQLITE_OK;
×
117
}
118

119
static int dftracer_sqlite_vfs_read(sqlite3_file *pFile, void *buf, int amt,
×
120
                                    sqlite3_int64 offset) {
121
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
122

123
    if (vf->backend == nullptr) {
×
124
        ssize_t n = ::pread(vf->fd, buf, static_cast<std::size_t>(amt),
×
125
                            static_cast<off_t>(offset));
126
        if (n == amt) return SQLITE_OK;
×
127
        if (n >= 0) {
×
128
            std::memset(static_cast<char *>(buf) + n, 0, amt - n);
×
129
            return SQLITE_IOERR_SHORT_READ;
×
130
        }
131
        return SQLITE_IOERR_READ;
×
132
    }
133

134
    ssize_t result = vf->backend->submit_read_sync(
×
135
        vf->fd, buf, static_cast<std::size_t>(amt), static_cast<off_t>(offset));
136

137
    if (result == amt) return SQLITE_OK;
×
138
    if (result >= 0) {
×
139
        std::memset(static_cast<char *>(buf) + result, 0, amt - result);
×
140
        return SQLITE_IOERR_SHORT_READ;
×
141
    }
142
    return SQLITE_IOERR_READ;
×
143
}
144

145
static int dftracer_sqlite_vfs_write(sqlite3_file *pFile, const void *buf,
×
146
                                     int amt, sqlite3_int64 offset) {
147
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
148

149
    if (vf->backend == nullptr) {
×
150
        ssize_t n = ::pwrite(vf->fd, buf, static_cast<std::size_t>(amt),
×
151
                             static_cast<off_t>(offset));
152
        if (n == amt) return SQLITE_OK;
×
153
        return SQLITE_IOERR_WRITE;
×
154
    }
155

156
    ssize_t result = vf->backend->submit_write_sync(
×
157
        vf->fd, buf, static_cast<std::size_t>(amt), static_cast<off_t>(offset));
158

159
    if (result == amt) return SQLITE_OK;
×
160
    return SQLITE_IOERR_WRITE;
×
161
}
162

163
static int dftracer_sqlite_vfs_truncate(sqlite3_file *pFile,
×
164
                                        sqlite3_int64 size) {
165
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
166

167
    if (vf->backend == nullptr) {
×
168
        if (::ftruncate(vf->fd, static_cast<off_t>(size)) != 0) {
×
169
            return SQLITE_IOERR_TRUNCATE;
×
170
        }
171
        return SQLITE_OK;
×
172
    }
173

174
    int rc =
175
        vf->backend->submit_ftruncate_sync(vf->fd, static_cast<off_t>(size));
×
176
    if (rc != 0) return SQLITE_IOERR_TRUNCATE;
×
177
    return SQLITE_OK;
×
178
}
179

180
static int dftracer_sqlite_vfs_sync(sqlite3_file *pFile, int /*flags*/) {
×
181
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
182

183
    if (vf->backend == nullptr) {
×
184
        if (::fsync(vf->fd) != 0) return SQLITE_IOERR_FSYNC;
×
185
        return SQLITE_OK;
×
186
    }
187

188
    int rc = vf->backend->submit_fsync_sync(vf->fd);
×
189
    if (rc != 0) return SQLITE_IOERR_FSYNC;
×
190
    return SQLITE_OK;
×
191
}
192

193
static int dftracer_sqlite_vfs_file_size(sqlite3_file *pFile,
×
194
                                         sqlite3_int64 *pSize) {
195
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
196
    struct stat st;
197

198
    if (vf->backend == nullptr) {
×
199
        if (::fstat(vf->fd, &st) != 0) return SQLITE_IOERR_FSTAT;
×
200
        *pSize = st.st_size;
×
201
        return SQLITE_OK;
×
202
    }
203

204
    int rc = vf->backend->submit_fstat_sync(vf->fd, &st);
×
205
    if (rc != 0) return SQLITE_IOERR_FSTAT;
×
206
    *pSize = st.st_size;
×
207
    return SQLITE_OK;
×
208
}
209

210
static int dftracer_sqlite_vfs_lock(sqlite3_file *pFile, int eLock) {
×
211
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
212

213
    struct flock fl;
214
    std::memset(&fl, 0, sizeof(fl));
×
215

216
    if (eLock == SQLITE_LOCK_NONE) {
×
217
        return SQLITE_OK;
×
218
    }
219

220
    if (eLock == SQLITE_LOCK_SHARED) {
×
221
        fl.l_type = F_RDLCK;
×
222
    } else {
223
        fl.l_type = F_WRLCK;
×
224
    }
225
    fl.l_whence = SEEK_SET;
×
226
    fl.l_start = 0;
×
227
    fl.l_len = 0;
×
228

229
    if (::fcntl(vf->fd, F_SETLK, &fl) == -1) {
×
230
        if (errno == EACCES || errno == EAGAIN) {
×
231
            return SQLITE_BUSY;
×
232
        }
233
        return SQLITE_IOERR_LOCK;
×
234
    }
235
    return SQLITE_OK;
×
236
}
237

238
static int dftracer_sqlite_vfs_unlock(sqlite3_file *pFile, int /*eLock*/) {
×
239
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
240

241
    struct flock fl;
242
    std::memset(&fl, 0, sizeof(fl));
×
243
    fl.l_type = F_UNLCK;
×
244
    fl.l_whence = SEEK_SET;
×
245
    fl.l_start = 0;
×
246
    fl.l_len = 0;
×
247

248
    if (::fcntl(vf->fd, F_SETLK, &fl) == -1) {
×
249
        return SQLITE_IOERR_UNLOCK;
×
250
    }
251
    return SQLITE_OK;
×
252
}
253

254
static int dftracer_sqlite_vfs_check_reserved_lock(sqlite3_file *pFile,
×
255
                                                   int *pResOut) {
256
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
257

258
    struct flock fl;
259
    std::memset(&fl, 0, sizeof(fl));
×
260
    fl.l_type = F_WRLCK;
×
261
    fl.l_whence = SEEK_SET;
×
262
    fl.l_start = 0;
×
263
    fl.l_len = 1;
×
264

265
    if (::fcntl(vf->fd, F_GETLK, &fl) == -1) {
×
266
        *pResOut = 0;
×
267
        return SQLITE_IOERR_CHECKRESERVEDLOCK;
×
268
    }
269

270
    *pResOut = (fl.l_type != F_UNLCK) ? 1 : 0;
×
271
    return SQLITE_OK;
×
272
}
273

274
static int dftracer_sqlite_vfs_file_control(sqlite3_file * /*pFile*/, int op,
×
275
                                            void * /*pArg*/) {
276
    if (op == SQLITE_FCNTL_LOCKSTATE) {
×
277
        return SQLITE_OK;
×
278
    }
279
    return SQLITE_NOTFOUND;
×
280
}
281

282
static int dftracer_sqlite_vfs_sector_size(sqlite3_file * /*pFile*/) {
×
283
    return 4096;
×
284
}
285

286
static int dftracer_sqlite_vfs_device_characteristics(
×
287
    sqlite3_file * /*pFile*/) {
288
    return SQLITE_IOCAP_ATOMIC512 | SQLITE_IOCAP_SAFE_APPEND;
×
289
}
290

291
// ============================================================================
292
// SHM methods (WAL shared memory)
293
// ============================================================================
294

295
static int dftracer_sqlite_vfs_shm_map(sqlite3_file *pFile, int iRegion,
×
296
                                       int szRegion, int bExtend,
297
                                       void volatile **pp) {
298
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
299

300
    if (iRegion >= 32) {
×
301
        *pp = nullptr;
×
302
        return SQLITE_IOERR;
×
303
    }
304

305
    // Open SHM file if not yet opened
306
    if (vf->shm_fd < 0) {
×
307
        char shm_path[1024];
308
        std::snprintf(shm_path, sizeof(shm_path), "%s-shm", vf->path);
×
309
        int oflags = O_RDWR | O_CREAT;
×
310
        vf->shm_fd = ::open(shm_path, oflags, 0644);
×
311
        if (vf->shm_fd < 0) {
×
312
            *pp = nullptr;
×
313
            return SQLITE_IOERR;
×
314
        }
315
    }
316

317
    // Extend file if needed
318
    off_t required_size =
×
319
        static_cast<off_t>(iRegion + 1) * static_cast<off_t>(szRegion);
×
320
    struct stat st;
321
    if (::fstat(vf->shm_fd, &st) != 0) {
×
322
        *pp = nullptr;
×
323
        return SQLITE_IOERR;
×
324
    }
325
    if (st.st_size < required_size) {
×
326
        if (!bExtend) {
×
327
            *pp = nullptr;
×
328
            return SQLITE_OK;
×
329
        }
330
        if (::ftruncate(vf->shm_fd, required_size) != 0) {
×
331
            *pp = nullptr;
×
332
            return SQLITE_IOERR;
×
333
        }
334
    }
335

336
    // Map the region if not already mapped
337
    if (iRegion >= vf->n_shm_region || vf->shm_regions[iRegion] == nullptr) {
×
338
        off_t map_offset =
×
339
            static_cast<off_t>(iRegion) * static_cast<off_t>(szRegion);
×
340
        void *mapped =
341
            ::mmap(nullptr, static_cast<std::size_t>(szRegion),
×
342
                   PROT_READ | PROT_WRITE, MAP_SHARED, vf->shm_fd, map_offset);
343
        if (mapped == MAP_FAILED) {
×
344
            *pp = nullptr;
×
345
            return SQLITE_IOERR;
×
346
        }
347
        vf->shm_regions[iRegion] = mapped;
×
348
        if (iRegion >= vf->n_shm_region) {
×
349
            vf->n_shm_region = iRegion + 1;
×
350
        }
351
    }
352

353
    *pp = vf->shm_regions[iRegion];
×
354
    return SQLITE_OK;
×
355
}
356

357
static int dftracer_sqlite_vfs_shm_lock(sqlite3_file *pFile, int offset, int n,
×
358
                                        int flags) {
359
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
360

361
    if (vf->shm_fd < 0) return SQLITE_IOERR;
×
362

363
    struct flock fl;
364
    std::memset(&fl, 0, sizeof(fl));
×
365

366
    if (flags & SQLITE_SHM_UNLOCK) {
×
367
        fl.l_type = F_UNLCK;
×
368
    } else if (flags & SQLITE_SHM_EXCLUSIVE) {
×
369
        fl.l_type = F_WRLCK;
×
370
    } else {
371
        fl.l_type = F_RDLCK;
×
372
    }
373
    fl.l_whence = SEEK_SET;
×
374
    fl.l_start = offset;
×
375
    fl.l_len = n;
×
376

377
    if (::fcntl(vf->shm_fd, F_SETLK, &fl) == -1) {
×
378
        if (errno == EACCES || errno == EAGAIN) {
×
379
            return SQLITE_BUSY;
×
380
        }
381
        return SQLITE_IOERR;
×
382
    }
383
    return SQLITE_OK;
×
384
}
385

386
static void dftracer_sqlite_vfs_shm_barrier(sqlite3_file * /*pFile*/) {
×
387
    __atomic_thread_fence(__ATOMIC_SEQ_CST);
×
388
}
×
389

390
static int dftracer_sqlite_vfs_shm_unmap(sqlite3_file *pFile, int deleteFlag) {
×
391
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
392

393
    for (int i = 0; i < vf->n_shm_region; ++i) {
×
394
        if (vf->shm_regions[i] != nullptr) {
×
395
            ::munmap(vf->shm_regions[i], 32768);
×
396
            vf->shm_regions[i] = nullptr;
×
397
        }
398
    }
399
    vf->n_shm_region = 0;
×
400

401
    if (vf->shm_fd >= 0) {
×
402
        ::close(vf->shm_fd);
×
403
        if (deleteFlag) {
×
404
            char shm_path[1024];
405
            std::snprintf(shm_path, sizeof(shm_path), "%s-shm", vf->path);
×
406
            ::unlink(shm_path);
×
407
        }
408
        vf->shm_fd = -1;
×
409
    }
410

411
    return SQLITE_OK;
×
412
}
413

414
// ============================================================================
415
// mmap methods (version 3)
416
// ============================================================================
417

418
static int dftracer_sqlite_vfs_fetch(sqlite3_file * /*pFile*/,
×
419
                                     sqlite3_int64 /*offset*/, int /*amt*/,
420
                                     void **pp) {
421
    // Disable mmap — returning nullptr tells SQLite to use
422
    // xRead instead. This avoids tracking mmap sizes for munmap.
423
    *pp = nullptr;
×
424
    return SQLITE_OK;
×
425
}
426

427
static int dftracer_sqlite_vfs_unfetch(sqlite3_file * /*pFile*/,
×
428
                                       sqlite3_int64 /*offset*/, void *p) {
429
    (void)p;
430
    return SQLITE_OK;
×
431
}
432

433
// ============================================================================
434
// sqlite3_vfs implementations
435
// ============================================================================
436

437
static int dftracer_sqlite_vfs_open(sqlite3_vfs *pVfs, const char *zName,
×
438
                                    sqlite3_file *pFile, int flags,
439
                                    int *pOutFlags) {
440
    auto *app = static_cast<DfTracerSqliteVfsAppData *>(pVfs->pAppData);
×
441
    auto *vf = reinterpret_cast<DfTracerSqliteVfsFile *>(pFile);
×
442

443
    // Zero the sqlite3_file base (C struct, safe to memset)
444
    std::memset(&vf->base, 0, sizeof(vf->base));
×
445
    vf->backend = nullptr;
×
446
    vf->executor = nullptr;
×
447
    vf->fd = -1;
×
448
    vf->read_only = false;
×
449
    vf->shm_fd = -1;
×
450
    vf->n_shm_region = 0;
×
451
    for (int i = 0; i < 32; ++i) {
×
452
        vf->shm_regions[i] = nullptr;
×
453
    }
454

455
    std::snprintf(vf->path, sizeof(vf->path), "%s", zName ? zName : "");
×
456

457
    vf->backend = app ? app->backend : nullptr;
×
458
    vf->executor = app ? app->executor : nullptr;
×
459
    vf->read_only = (flags & SQLITE_OPEN_READONLY) != 0;
×
460

461
    // Build open flags
462
    int oflags = 0;
×
463
    if (flags & SQLITE_OPEN_EXCLUSIVE) {
×
464
        oflags |= O_EXCL;
×
465
    }
466
    if (flags & SQLITE_OPEN_CREATE) {
×
467
        oflags |= O_CREAT;
×
468
    }
469
    if (flags & SQLITE_OPEN_READONLY) {
×
470
        oflags = O_RDONLY;
×
471
    } else if (flags & SQLITE_OPEN_READWRITE) {
×
472
        oflags |= O_RDWR;
×
473
    }
474

475
    // Handle temp/journal files without a name
476
    if (zName == nullptr) {
×
477
        const char *tmpdir = std::getenv("TMPDIR");
×
478
        if (!tmpdir) tmpdir = "/tmp";
×
479
        std::snprintf(vf->path, sizeof(vf->path), "%s/dftracer_sqlite_XXXXXX",
×
480
                      tmpdir);
481
        vf->fd = ::mkstemp(vf->path);
×
482
        if (vf->fd < 0) {
×
483
            return SQLITE_CANTOPEN;
×
484
        }
485
        ::unlink(vf->path);
×
486
    } else {
487
        vf->fd = ::open(zName, oflags, 0644);
×
488
        if (vf->fd < 0) {
×
489
            return SQLITE_CANTOPEN;
×
490
        }
491
    }
492

493
    if (pOutFlags != nullptr) {
×
494
        *pOutFlags = flags;
×
495
    }
496

497
    pFile->pMethods = &dftracer_sqlite_vfs_io_methods;
×
498
    return SQLITE_OK;
×
499
}
500

501
static int dftracer_sqlite_vfs_delete(sqlite3_vfs * /*pVfs*/, const char *zPath,
×
502
                                      int dirSync) {
503
    if (::unlink(zPath) != 0) {
×
504
        if (errno == ENOENT) return SQLITE_OK;
×
505
        return SQLITE_IOERR_DELETE;
×
506
    }
507

508
    if (dirSync) {
×
509
        // Sync the parent directory
510
        char dir[1024];
511
        std::snprintf(dir, sizeof(dir), "%s", zPath);
×
512
        char *slash = std::strrchr(dir, '/');
×
513
        if (slash) {
×
514
            if (slash == dir) {
×
515
                dir[1] = '\0';  // root "/"
×
516
            } else {
517
                *slash = '\0';
×
518
            }
519
        } else {
520
            dir[0] = '.';
×
521
            dir[1] = '\0';
×
522
        }
523
        int dfd = ::open(dir, O_RDONLY);
×
524
        if (dfd >= 0) {
×
525
            ::fsync(dfd);
×
526
            ::close(dfd);
×
527
        }
528
    }
529

530
    return SQLITE_OK;
×
531
}
532

533
static int dftracer_sqlite_vfs_access(sqlite3_vfs * /*pVfs*/, const char *zPath,
×
534
                                      int flags, int *pResOut) {
535
    int mode = F_OK;
×
536
    if (flags == SQLITE_ACCESS_READWRITE) {
×
537
        mode = R_OK | W_OK;
×
538
    } else if (flags == SQLITE_ACCESS_READ) {
×
539
        mode = R_OK;
×
540
    }
541

542
    *pResOut = (::access(zPath, mode) == 0) ? 1 : 0;
×
543
    return SQLITE_OK;
×
544
}
545

546
static int dftracer_sqlite_vfs_fullpathname(sqlite3_vfs * /*pVfs*/,
×
547
                                            const char *zName, int nOut,
548
                                            char *zOut) {
549
    char *resolved = ::realpath(zName, nullptr);
×
550
    if (resolved != nullptr) {
×
551
        std::strncpy(zOut, resolved, static_cast<std::size_t>(nOut));
×
552
        zOut[nOut - 1] = '\0';
×
553
        ::free(resolved);
×
554
    } else {
555
        // If realpath fails (file doesn't exist yet), copy as-is
556
        std::strncpy(zOut, zName, static_cast<std::size_t>(nOut));
×
557
        zOut[nOut - 1] = '\0';
×
558
    }
559
    return SQLITE_OK;
×
560
}
561

562
static int dftracer_sqlite_vfs_get_last_error(sqlite3_vfs * /*pVfs*/, int nBuf,
×
563
                                              char *zBuf) {
564
    if (nBuf > 0 && zBuf != nullptr) {
×
565
        std::strncpy(zBuf, std::strerror(errno),
×
566
                     static_cast<std::size_t>(nBuf));
567
        zBuf[nBuf - 1] = '\0';
×
568
    }
569
    return errno;
×
570
}
571

572
// ============================================================================
573
// VFS Registration
574
// ============================================================================
575

576
void register_dftracer_sqlite_vfs(io::IoBackend *backend, Executor *executor) {
876✔
577
    if (dftracer_vfs_registered) return;
876✔
578

579
    sqlite3_vfs *default_vfs = sqlite3_vfs_find(nullptr);
874✔
580

581
    dftracer_vfs_app_data = new DfTracerSqliteVfsAppData{backend, executor};
874✔
582

583
    std::memset(&dftracer_vfs_instance, 0, sizeof(dftracer_vfs_instance));
874✔
584
    dftracer_vfs_instance.iVersion = 3;
874✔
585
    dftracer_vfs_instance.szOsFile =
874✔
586
        static_cast<int>(sizeof(DfTracerSqliteVfsFile));
587
    dftracer_vfs_instance.mxPathname = VFS_MAX_PATHNAME;
874✔
588
    dftracer_vfs_instance.pNext = nullptr;
874✔
589
    dftracer_vfs_instance.zName = "dftracer_sqlite";
874✔
590
    dftracer_vfs_instance.pAppData = dftracer_vfs_app_data;
874✔
591
    dftracer_vfs_instance.xOpen = dftracer_sqlite_vfs_open;
874✔
592
    dftracer_vfs_instance.xDelete = dftracer_sqlite_vfs_delete;
874✔
593
    dftracer_vfs_instance.xAccess = dftracer_sqlite_vfs_access;
874✔
594
    dftracer_vfs_instance.xFullPathname = dftracer_sqlite_vfs_fullpathname;
874✔
595
    dftracer_vfs_instance.xGetLastError = dftracer_sqlite_vfs_get_last_error;
874✔
596

597
    // Delegate time/random/sleep to default VFS
598
    if (default_vfs != nullptr) {
874✔
599
        dftracer_vfs_instance.xRandomness = default_vfs->xRandomness;
874✔
600
        dftracer_vfs_instance.xSleep = default_vfs->xSleep;
874✔
601
        dftracer_vfs_instance.xCurrentTime = default_vfs->xCurrentTime;
874✔
602
        dftracer_vfs_instance.xCurrentTimeInt64 =
874✔
603
            default_vfs->xCurrentTimeInt64;
874✔
604
    }
437✔
605

606
    sqlite3_vfs_register(&dftracer_vfs_instance, 0);
874✔
607
    dftracer_vfs_registered = true;
874✔
608
}
438✔
609

610
void unregister_dftracer_sqlite_vfs() {
876✔
611
    if (!dftracer_vfs_registered) return;
876✔
612

613
    sqlite3_vfs_unregister(&dftracer_vfs_instance);
874✔
614

615
    delete dftracer_vfs_app_data;
874✔
616
    dftracer_vfs_app_data = nullptr;
874✔
617
    dftracer_vfs_registered = false;
874✔
618
}
438✔
619

620
}  // namespace dftracer::utils::sqlite
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc