diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-08-10 15:43:26 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-08-10 16:02:27 -0700 |
commit | 55cd2351d0b3f81dea45cbb07bc5338a1d5b9973 (patch) | |
tree | 23909117d103edeb4b02eb99c977150d63f3194a /com32/lib/sys/read.c | |
parent | f614a40876843b7de58d8410b47c8c68e2ab6992 (diff) | |
download | syslinux-dynamic.tar.gz syslinux-dynamic.tar.xz syslinux-dynamic.zip |
read: handle the case of partial data from unreaddynamic
Correctly handle the case of partial data from the unread buffer, and
partial data via the device read mechanism. We need to advance the
buffer pointer.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'com32/lib/sys/read.c')
-rw-r--r-- | com32/lib/sys/read.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/com32/lib/sys/read.c b/com32/lib/sys/read.c index 388f6987..a3395c38 100644 --- a/com32/lib/sys/read.c +++ b/com32/lib/sys/read.c @@ -1,6 +1,7 @@ /* ----------------------------------------------------------------------- * * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -40,6 +41,7 @@ ssize_t read(int fd, void *buf, size_t count) { + char *datap = buf; struct file_info *fp = &__file_info[fd]; size_t n0, n1; @@ -48,19 +50,20 @@ ssize_t read(int fd, void *buf, size_t count) return -1; } - if (!count) + if (__unlikely(!count)) return 0; n0 = min(fp->i.unread_bytes, count); - if (n0) { - memcpy(buf, unread_data(fp), n0); + if (__unlikely(n0)) { + memcpy(datap, unread_data(fp), n0); fp->i.unread_bytes -= n0; count -= n0; + datap += n0; if (!count) return n0; } - n1 = fp->iop->read(fp, buf, count); + n1 = fp->iop->read(fp, datap, count); if (n1 == -1 && n0 > 0) return n0; |