This is the mail archive of the
cygwin-patches
mailing list for the Cygwin project.
Re: PATCH: pread() return non-zero if read beyond end of file
- From: "Xiaofeng Liu via cygwin-patches" <cygwin-patches at cygwin dot com>
- To: cygwin-patches at cygwin dot com, Corinna Vinschen <corinna-cygwin at cygwin dot com>
- Date: Mon, 6 Nov 2017 21:54:46 +0000 (UTC)
- Subject: Re: PATCH: pread() return non-zero if read beyond end of file
- Authentication-results: sourceware.org; auth=none
- References: <1363864083.3348449.1509996042945.ref@mail.yahoo.com> <1363864083.3348449.1509996042945@mail.yahoo.com> <20171106202335.GI18070@calimero.vinschen.de>
- Reply-to: Xiaofeng Liu <liuxf09 at yahoo dot com>
try again, after saving the diff in linux first.
git diff diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index bc8fead..525cb32 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1525,6 +1525,7 @@ fhandler_disk_file::pread (void *buf, size_t count, off_t offset) IO_STATUS_BLOCK io; LARGE_INTEGER off = { QuadPart:offset };
+ memset(&io, 0, sizeof(io)); if (!prw_handle && prw_open (false)) goto non_atomic; status = NtReadFile (prw_handle, NULL, NULL, NULL, &io, buf, count,
On Monday, November 6, 2017, 12:23:44 PM PST, Corinna Vinschen <corinna-cygwin@cygwin.com> wrote:
Hi,
On Nov 6 19:20, Xiaofeng Liu via cygwin-patches wrote:
> pread() return 0 if read beyond end of file in linux, but not zero in cygwin.
> I have a small code to show the problem:
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <errno.h>
>
> int main()
> {
> const char* file = "/home/xliu/work/exome/a.bam";
> struct stat st;
> stat(file, &st);
> char buf[65536];
> int fd = open(file, O_RDONLY);
> int ret = pread(fd, buf, sizeof buf, st.st_size);
> fprintf(stderr, "filesize %ld, after eof pread() return = %d, errno = %d\n", st.st_size, ret, errno);
> lseek(fd, st.st_size, SEEK_SET);
> ret = read(fd, buf, sizeof buf);
> fprintf(stderr, "filesize %ld, after eof read() return = %d, errno = %d\n", st.st_size, ret, errno);
> }
> $ ./a.exe
> filesize 6126093048, after eof pread() return = 3, errno = 0
> filesize 6126093048, after eof read() return = 0, errno = 0
> The issue is that NtReadFile() return EOF status, but doesn't set io.information to 0. As a result, the current pread() implementation could return an arbitrary number in the stack. The fix is a one line fix: reset io status block.
> diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.ccindex bc8fead..525cb32 100644--- a/winsup/cygwin/fhandler_disk_file.cc+++ b/winsup/cygwin/fhandler_disk_file.cc@@ -1525,6 +1525,7 @@ fhandler_disk_file::pread (void *buf, size_t count, off_t offset) IO_STATUS_BLOCK io; LARGE_INTEGER off = { QuadPart:offset };
> + memset(&io, 0, sizeof(io)); if (!prw_handle && prw_open (false)) goto non_atomic; status = NtReadFile (prw_handle, NULL, NULL, NULL, &io, buf, count,
your mailer screwed up the patch and so it can't apply. Can you please
send it as an attachment?
Thanks,
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat