-
- off_t ci;
- for(ci = 0; ci < chunk_count; ci++)
- {
- const off_t pos = chunk_size * ci;
- const size_t msize = chunk_size < st.st_size - pos ? chunk_size : st.st_size - pos;
- void *m = mmap(NULL, msize, PROT_NONE, MAP_SHARED, fd, pos);
- if (m == MAP_FAILED)
- {
- free(result);
- return PyErr_SetFromErrno(PyExc_OSError);
- }
- rc = mincore(m, msize, &result[ci * pages_per_chunk]);
- if (rc != 0)
- {
- const int errno_stash = errno;
- rc = munmap(m, msize);
- if (rc != 0)
- {
- char buf[512];
- char *msg = strerror_r(errno, buf, 512);
- if (rc != 0)
- fprintf(stderr, "%s:%d: strerror_r failed (%d)\n",
- __FILE__, __LINE__, rc < 0 ? errno : rc);
- else
- fprintf(stderr,
- "%s:%d: munmap failed after mincore failed (%s)\n",
- __FILE__, __LINE__, msg);
- }
- free(result);
- errno = errno_stash;
- return PyErr_SetFromErrno(PyExc_OSError);
- }
- rc = munmap(m, msize);
- if (rc != 0)
- {
- free(result);
- return PyErr_SetFromErrno(PyExc_OSError);
- }
- }
- PyObject *py_result = Py_BuildValue("s#", result, page_count);
- free(result);
- return py_result;