Cygwin: execve: fix setting O_APPEND file offset for native child

dtable::set_file_pointers_for_exec is called from
child_info_spawn::worker to move the file position of O_APPEND
files to EOF if the child is a native child.

However, this only works correctly for the first O_APPEND
file descriptor:

- set_file_pointers_for_exec calls SetFilePointer.  The higher
  4 bytes of the desired file offset are given to SetFilePointer
  as pointer to a DWORD value.  On return, SetFilePointer returns
  the higher 4 bytes of the new file position in this DWORD.

- So for the second and subsequent descriptors the higher 4 byte
  of the file position depend on what the actual file position
  of the previous file has been set to:

- If the file is > 2 Gigs, the high offset will not be 0 anymore.

- If the desciptor points to a non-seekable file (i.e., a pipe
  or socket), SetFilePosition returns an error and sets the high
  position to -1.

Fix this by calling SetFilePointerEx instead, which does not
modify the incoming position value.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2019-02-09 15:36:02 +01:00
parent 7816cf3636
commit 0be0b8f033
2 changed files with 6 additions and 2 deletions

View File

@ -857,12 +857,13 @@ dtable::set_file_pointers_for_exec ()
{
/* This is not POSIX-compliant so the function is only called for
non-Cygwin processes. */
LONG off_high = 0;
LARGE_INTEGER eof = { QuadPart: 0 };
lock ();
fhandler_base *fh;
for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL && fh->get_flags () & O_APPEND)
SetFilePointer (fh->get_handle (), 0, &off_high, FILE_END);
SetFilePointerEx (fh->get_handle (), eof, NULL, FILE_END);
unlock ();
}

View File

@ -100,3 +100,6 @@ Bug Fixes
- Fix exception handling in pthreads.
Addresses: https://cygwin.com/ml/cygwin/2019-01/msg00149.html
- Fix O_APPEND handling on files when calling non-Cygwin applications
Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00081.html