diff options
| author | Junio C Hamano <gitster@pobox.com> | 2014-06-25 11:49:48 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2014-06-25 11:49:48 -0700 |
| commit | 1881d2b88c4b889dcb95782ad4bc5395808438e9 (patch) | |
| tree | cab7b82ccfc98e89b355c3dc209b7ec6656e1b93 /wrapper.c | |
| parent | 85785df6d6db50ff37d0ff1878c16ad69a063f6a (diff) | |
| parent | 426ddeead6112955dfb50ccf9bb4af05d1ca9082 (diff) | |
| download | git-1881d2b88c4b889dcb95782ad4bc5395808438e9.tar.gz | |
Merge branch 'ym/fix-opportunistic-index-update-race' into maint
"git status", even though it is a read-only operation, tries to
update the index with refreshed lstat(2) info to optimize future
accesses to the working tree opportunistically, but this could
race with a "read-write" operation that modify the index while it
is running. Detect such a race and avoid overwriting the index.
* ym/fix-opportunistic-index-update-race:
read-cache.c: verify index file before we opportunistically update it
wrapper.c: add xpread() similar to xread()
Diffstat (limited to 'wrapper.c')
| -rw-r--r-- | wrapper.c | 38 |
1 files changed, 38 insertions, 0 deletions
@@ -174,6 +174,24 @@ ssize_t xwrite(int fd, const void *buf, size_t len) } } +/* + * xpread() is the same as pread(), but it automatically restarts pread() + * operations with a recoverable error (EAGAIN and EINTR). xpread() DOES + * NOT GUARANTEE that "len" bytes is read even if the data is available. + */ +ssize_t xpread(int fd, void *buf, size_t len, off_t offset) +{ + ssize_t nr; + if (len > MAX_IO_SIZE) + len = MAX_IO_SIZE; + while (1) { + nr = pread(fd, buf, len, offset); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + ssize_t read_in_full(int fd, void *buf, size_t count) { char *p = buf; @@ -214,6 +232,26 @@ ssize_t write_in_full(int fd, const void *buf, size_t count) return total; } +ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset) +{ + char *p = buf; + ssize_t total = 0; + + while (count > 0) { + ssize_t loaded = xpread(fd, p, count, offset); + if (loaded < 0) + return -1; + if (loaded == 0) + return total; + count -= loaded; + p += loaded; + total += loaded; + offset += loaded; + } + + return total; +} + int xdup(int fd) { int ret = dup(fd); |
