Skip to content

Commit

Permalink
hashsplit: restore mmap/mincore special case errno suppression
Browse files Browse the repository at this point in the history
Restore the suppression of mmap() EINVAL and ENODEV and mincore()
ENOSYS that was in the original helpers.py code, and report any
munmap() failure after a mincore() failure to stderr.

Signed-off-by: Rob Browning <[email protected]>
Tested-by: Rob Browning <[email protected]>
  • Loading branch information
rlbdv committed Nov 20, 2022
1 parent e32d973 commit 75826b1
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions lib/bup/_hashsplit.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,40 @@ static int HashSplitter_nextfile(HashSplitter *self)

int rc = 0;
unsigned char *addr = mmap(NULL, len, PROT_NONE, MAP_PRIVATE, self->fd, pos);
if (addr != MAP_FAILED)
rc = mincore(addr, len, mcore + outoffs);
if ((addr == MAP_FAILED) || (rc < 0)) {
if (addr == MAP_FAILED) {
free(mcore);
// FIXME: check for error and chain exceptions someday
if (addr == MAP_FAILED)
munmap(addr, len);
PyEval_RestoreThread(thread_state);

if (errno == EINVAL || errno == ENODEV)
// Perhaps the file was a pipe, i.e. "... | bup split ..."
return 0;

PyErr_SetFromErrno(PyExc_IOError);
return -1;
}

rc = mincore(addr, len, mcore + outoffs);

if (rc < 0) {
const int mc_err = errno;
free(mcore);

int mu_err = 0;
if (munmap(addr, len) != 0)
mu_err = errno;

PyEval_RestoreThread(thread_state);

// FIXME: chain exceptions someday
if (mc_err == ENOSYS) {
if (!mu_err)
return 0;
errno = mu_err;
} else {
perror("error: munmap failed after mincore failure");
errno = mc_err;
}

PyErr_SetFromErrno(PyExc_IOError);
return -1;
}
Expand Down

0 comments on commit 75826b1

Please sign in to comment.