mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-27 05:00:15 +00:00
8cbab3b729
There already was a branch checking for this case in _hurd_fd_read () when the data is returned out-of-line. Do the same for inline data, as well as for _hurd_fd_write (). It's also not possible for the length to be negative, since it's stored in an unsigned integer. Not verifying the returned length can confuse the callers who assume the returned length is always reasonable. This manifested as libzstd test suite failing on writes to /dev/zero, even though the write () call appeared to succeed. In fact, the zero store backing /dev/zero was returning a larger written length than the size actually submitted to it, which is a separate bug to be fixed on the Hurd side. With this patch, EGRATUITOUS is now propagated to the caller. Reported-by: Diego Nieto Cid <dnietoc@gmail.com> Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> Message-ID: <20241204112915.540032-1-bugaevc@gmail.com>
47 lines
1.4 KiB
C
47 lines
1.4 KiB
C
/* _hurd_fd_write -- write to a file descriptor; handles job control et al.
|
|
Copyright (C) 1993-2024 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with the GNU C Library; if not, see
|
|
<https://www.gnu.org/licenses/>. */
|
|
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <hurd.h>
|
|
#include <hurd/fd.h>
|
|
|
|
error_t
|
|
_hurd_fd_write (struct hurd_fd *fd,
|
|
const void *buf, size_t *nbytes, loff_t offset)
|
|
{
|
|
error_t err;
|
|
vm_size_t wrote;
|
|
|
|
error_t writefd (io_t port)
|
|
{
|
|
return __io_write (port, buf, *nbytes, offset, &wrote);
|
|
}
|
|
|
|
err = HURD_FD_PORT_USE_CANCEL (fd, _hurd_ctty_output (port, ctty, writefd));
|
|
if (err)
|
|
return err;
|
|
|
|
if (__glibc_unlikely (wrote > *nbytes)) /* Sanity check for bogus server. */
|
|
return EGRATUITOUS;
|
|
|
|
*nbytes = wrote;
|
|
|
|
return 0;
|
|
}
|