diff --git a/ChangeLog b/ChangeLog index 1ed6d179e..1536daef9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Tue May 4 19:37:58 CEST 2010 (acab) +------------------------------------ + * libclamav/fmap.c: nicely handle EINTR + Tue May 4 18:47:31 CEST 2010 (acab) ------------------------------------ * libclamav: no ERROR on void mapping (bb#1968) diff --git a/libclamav/fmap.c b/libclamav/fmap.c index 291edb6f4..4895f8d83 100644 --- a/libclamav/fmap.c +++ b/libclamav/fmap.c @@ -35,6 +35,7 @@ #include #endif #endif +#include #ifdef C_LINUX #include @@ -210,8 +211,8 @@ static void fmap_aging(fmap_t *m) { static int fmap_readpage(fmap_t *m, unsigned int first_page, unsigned int count, unsigned int lock_count) { - size_t readsz = 0, got; - char *pptr = NULL; + size_t readsz = 0, eintr_off, got; + char *pptr = NULL, err[256]; uint32_t s; unsigned int i, page = first_page, force_read = 0; @@ -278,12 +279,28 @@ static int fmap_readpage(fmap_t *m, unsigned int first_page, unsigned int count, } } - if((got=pread(m->fd, pptr, readsz, m->offset + first_page * m->pgsz)) != readsz) { - cli_warnmsg("pread fail: page %u pages %u map-offset %lu - asked for %lu bytes, got %lu\n", first_page, m->pages, (long unsigned int)m->offset, (long unsigned int)readsz, (long unsigned int)got); + eintr_off = 0; + while(readsz) { + got=pread(m->fd, pptr, readsz, eintr_off + m->offset + first_page * m->pgsz); + + if(got < 0 && errno == EINTR) + continue; + + if(got > 0) { + pptr += got; + eintr_off += got; + readsz -= got; + continue; + } + + if(got <0) + cli_errmsg("fmap_readpage: pread error: %s\n", cli_strerror(errno, err, sizeof(err))); + else + cli_warnmsg("fmap_readpage: pread fail: asked for %lu bytes @ offset %lu, got %lu\n", (long unsigned int)readsz, (long unsigned int)(eintr_off + m->offset + first_page * m->pgsz), (long unsigned int)got); return 1; } + pptr = NULL; - force_read = 0; readsz = 0; continue; }