MCPcopy Create free account
hub / github.com/clementgallet/libTAS / writeSaveFiles

Function writeSaveFiles

src/library/checkpoint/Checkpoint.cpp:1611–1758  ·  view source on GitHub ↗

Write a memory area into the savestate. Returns the size of the area in bytes */

Source from the content-addressed store, hash-verified

1609
1610/* Write a memory area into the savestate. Returns the size of the area in bytes */
1611static size_t writeSaveFiles(SaveStateSaving &state)
1612{
1613 size_t total_size = 0;
1614
1615 for (auto it = SaveFileList::begin(); it != SaveFileList::end(); it++) {
1616 const std::unique_ptr<SaveFile>& savefile = *it;
1617 /* Don't map if file was closed and removed (TODO: handle this!) */
1618 if (savefile->fd == 0)
1619 continue;
1620
1621 /* Also, skip if we are handling the savefile using our custom
1622 * stream (SaveFileStream), which maps its content in memory. So, it
1623 * is already saved through the memory dumping process. */
1624 if (savefile->fd >= FIRST_SAVEFILE_STREAM_FD)
1625 continue;
1626
1627 Area area;
1628 area.flags = Area::AREA_SAVEFILE;
1629 area.fd = savefile->fd;
1630 strncpy(area.name, savefile->filename.c_str(), Area::FILENAMESIZE-1);
1631
1632 /* Get current file length and map at least this amount of bytes */
1633 struct stat filestat;
1634 int rv = fstat(area.fd, &filestat);
1635
1636 if (rv < 0)
1637 continue;
1638
1639 area.size = filestat.st_size;
1640
1641 if (area.size == 0) {
1642 LOG(LL_DEBUG, LCF_CHECKPOINT | LCF_FILEIO, " Don't map empty/missing file %s with fd %d", savefile->filename.c_str(), savefile->fd);
1643 continue;
1644 }
1645
1646 area.addr = mmap(nullptr, area.size, PROT_READ, MAP_PRIVATE | MAP_FILE, savefile->fd, 0);
1647
1648 if (area.addr == MAP_FAILED) {
1649 LOG(LL_DEBUG, LCF_CHECKPOINT | LCF_FILEIO, " Cound not map file %s with fd %d and size %zu", savefile->filename.c_str(), savefile->fd, area.size);
1650 continue;
1651 }
1652
1653 LOG(LL_DEBUG, LCF_CHECKPOINT | LCF_FILEIO, "Save savefile %s with fd %d and size %zu", savefile->filename.c_str(), savefile->fd, area.size);
1654
1655 /* Map the original file */
1656 int orig_fd = -1;
1657 size_t orig_file_mapped_size = 0;
1658 void* orig_file_mapped_addr = MAP_FAILED;
1659
1660 rv = stat(savefile->filename.c_str(), &filestat);
1661
1662 if (rv < 0)
1663 LOG(LL_DEBUG, LCF_CHECKPOINT | LCF_FILEIO, " No original savefile to use");
1664 else if (! S_ISREG(filestat.st_mode) || (filestat.st_size == 0))
1665 LOG(LL_DEBUG, LCF_CHECKPOINT | LCF_FILEIO, " Original file is missing or not regular, skip it");
1666 else {
1667 orig_fd = open(savefile->filename.c_str(), O_RDONLY);
1668

Callers 1

writeAllAreasFunction · 0.85

Calls 10

fstatFunction · 0.85
closeFunction · 0.85
processAreaMethod · 0.80
queuePageSaveMethod · 0.80
savePageFlagMethod · 0.80
finishSaveMethod · 0.80
statClass · 0.70
beginFunction · 0.50
endFunction · 0.50
c_strMethod · 0.45

Tested by

no test coverage detected