bug#81060: tee: version 9.11: regression

Pádraig Brady <[email protected]> Sun, 17 May 2026 12:02:35 +0100
Newsgroups gmane.comp.gnu.core-utils.bugs
Message-ID <[email protected]>
On 17/05/2026 03:56, Collin Funk wrote:
> Collin Funk <[email protected]> writes:
> 
>>> Note 3: Regardless whether the tee(1) infloop happens or not, the terminal is showing
>>> some debris after terminating tee(1):
>>>
>>>    :1+r6E616D65=787465726D2D323536636F6C6F72^[\^[[8;61;270t^[[61;10R^[[61;270R^[[8;61;270t^[[61;1R^[[61;270R
>>
>> This one confuses me, since I also see it with coreutils-9.10. Perhaps
>> it is a bug that was introduced earlier than the previously discussed
>> commit?
> 
> I think it is safe to ignore. It will be printed if you run the
> following command:
> 
>      $ cat typescript
>      [...]
>      $ :1+r6E616D65=787465726D2D323536636F6C6F72^[\^[[8;57;254t^[[57;10R^[[57;254R^[[8;57;254t^[[57;1R^[[57;254R
> 
> It is caused by this line:
> 
>      $ sed -n 197p typescript
>      2nd stage started in virtual machine
>      $ :1+r6E616D65=787465726D2D323536636F6C6F72^[\^[[8;57;254t^[[57;10R^[[57;254R^[[8;57;254t^[[57;1R^[[57;254R
>      $ sed 197d typescript
>      [...]
>      $ hello
>      Hello, world!
> 
> While looking at this code again, I wonder if write_wait should be
> written a bit more defensively. E.g., like this:
> 
> diff --git a/src/iopoll.c b/src/iopoll.c
> index de20bc8d9..93895bd48 100644
> --- a/src/iopoll.c
> +++ b/src/iopoll.c
> @@ -208,23 +208,23 @@ close_wait (int fd)
>   /* wrapper for write() that also waits for FD if non blocking.  */
>   
>   extern bool
> -write_wait (int fd, void const *buffer, size_t size)
> +write_wait (int fd, void const *buffer, ssize_t size)

It would be best to keep the same types as write()

>   {
>     unsigned char const *buf = buffer;
>   
> -  while (true)
> +  while (0 < size)

I wouldn't avoid the write() with a zero size,
as that can be used to probe an fd.
(I know we don't currently, but best to leave that possibility).

>       {
>         ssize_t written = write (fd, buf, size);
> -      if (written < 0)
> -        written = 0;
> -
> -      size -= written;
> -      if (size <= 0)  /* everything written */

Yes the < 0 can't happen, so it would be good to adjust this.

> -        return true;
> -
> -      if (! wait_for_nonblocking_write (fd))
> -        return false;
> -
> +      if (written <= 0)
> +        {
> +          /* Continue if FD becomes writable.  */
> +          if (wait_for_nonblocking_write (fd))
> +            continue;
> +          return false;
> +        }
>         buf += written;
> +      size -= written;
>       }
> +
> +  return true;
>   }
> 
> Is it possible/common for write to return zero bytes when the given size
> is greater than zero?
Potentially yes.

thanks,
Padraig