static int rpmidxMap(rpmidxdb idxdb) { struct stat stb; if (idxdb->xdb) { if (rpmxdbMapBlob(idxdb->xdb, idxdb->xdbid, idxdb->rdonly ? O_RDONLY : O_RDWR, mapcb, idxdb)) return RPMRC_FAIL; if (idxdb->file_size < 4096) { rpmxdbUnmapBlob(idxdb->xdb, idxdb->xdbid); return RPMRC_FAIL; } } else { size_t size; void *mapped; if (fstat(idxdb->fd, &stb)) return RPMRC_FAIL; size = stb.st_size; if (size < 4096) return RPMRC_FAIL; /* round up for mmap */ size = (size + idxdb->pagesize - 1) & ~(idxdb->pagesize - 1); mapped = mmap(0, size, idxdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, idxdb->fd, 0); if (mapped == MAP_FAILED) return RPMRC_FAIL; set_mapped(idxdb, mapped, (unsigned int)stb.st_size); } return RPMRC_OK; }
static void rpmidxUnmap(rpmidxdb idxdb) { if (!idxdb->head_mapped) return; if (idxdb->xdb) { rpmxdbUnmapBlob(idxdb->xdb, idxdb->xdbid); } else { size_t size = idxdb->file_size; /* round up for munmap */ size = (size + idxdb->pagesize - 1) & ~(idxdb->pagesize - 1); munmap(idxdb->head_mapped, size); set_mapped(idxdb, 0, 0); } }
/* XDB callbacks */ static void mapcb(rpmxdb xdb, void *data, void *newaddr, size_t newsize) { set_mapped((rpmidxdb)data, newaddr, (unsigned int)newsize); }
void mapped_write(int wid, const char *buf) { set_mapped(wid, !strcmp(buf, "true\n")); }