Hello,

Zhaoming Luo, le lun. 10 mars 2025 16:44:09 +0800, a ecrit:
> I haven't tested this patch again some stress tests as I don't know why
> the `dpkg-buildpackage -B` on my qemu got stuck at:
> 
> ```
> ...
> ../scripts/evaluate-test.sh stdio-common/scanf14 $? false false > 
> /home/1speaker/apt-source/glibc-2.41/build-tree/hurd-i386-libc/stdio-common/scanf14.test-result
> ```

It seems it is related: without your patch the test passes.

Samuel


> ---
>  sysdeps/mach/hurd/dup3.c  | 62 +++++++++++++++++++++++++++++----------
>  sysdeps/mach/hurd/fcntl.c | 52 ++++++++++++++++++++++++--------
>  2 files changed, 86 insertions(+), 28 deletions(-)
> 
> diff --git a/sysdeps/mach/hurd/dup3.c b/sysdeps/mach/hurd/dup3.c
> index 22af45b4..224a803c 100644
> --- a/sysdeps/mach/hurd/dup3.c
> +++ b/sysdeps/mach/hurd/dup3.c
> @@ -69,6 +69,7 @@ __dup3 (int fd, int fd2, int flags)
>       {
>         /* Get a hold of the destination descriptor.  */
>         struct hurd_fd *d2;
> +       error_t err;
>  
>         __mutex_lock (&_hurd_dtable_lock);
>  
> @@ -107,22 +108,51 @@ __dup3 (int fd, int fd2, int flags)
>           }
>         else
>           {
> -           /* Give the ports each a user ref for the new descriptor.  */
> -           __mach_port_mod_refs (__mach_task_self (), port,
> -                                 MACH_PORT_RIGHT_SEND, 1);
> -           if (ctty != MACH_PORT_NULL)
> -             __mach_port_mod_refs (__mach_task_self (), ctty,
> -                                   MACH_PORT_RIGHT_SEND, 1);
> -
> -           /* Install the ports and flags in the new descriptor slot.  */
> -           __spin_lock (&d2->port.lock);
> -           if (flags & O_CLOEXEC)
> -             d2->flags = d_flags | FD_CLOEXEC;
> -           else
> -             /* dup clears FD_CLOEXEC.  */
> -             d2->flags = d_flags & ~FD_CLOEXEC;
> -           _hurd_port_set (&d2->ctty, ctty);
> -           _hurd_port_locked_set (&d2->port, port); /* Unlocks D2.  */
> +           /* Give the io server port a user ref for the new descriptor.  */
> +           err = __mach_port_mod_refs (__mach_task_self (), port,
> +                   MACH_PORT_RIGHT_SEND, 1);
> +
> +           if (err == KERN_UREFS_OVERFLOW)
> +             fd2 = __hurd_fail (EMFILE);
> +           else if (err)
> +             fd2 = __hurd_fail (EINVAL);
> +           else if (ctty != MACH_PORT_NULL)
> +             {
> +               /* We have confirmed the io server port has got a user ref
> +                  count, now give ctty port a user ref for the new
> +                  descriptor.  */
> +               err = __mach_port_mod_refs (__mach_task_self (), ctty,
> +                       MACH_PORT_RIGHT_SEND, 1);
> +
> +               if (err)
> +                 {
> +                   /* In this case the io server port has got a ref count
> +                      but the ctty port fails to get ont, so we need to
> +                      clean the ref count we just assigned.  */
> +                   __mach_port_mod_refs (__mach_task_self (), port,
> +                           MACH_PORT_RIGHT_SEND, -1);
> +                   if (err == KERN_UREFS_OVERFLOW)
> +                     fd2 = __hurd_fail (EMFILE);
> +                   else
> +                     fd2 = __hurd_fail (EINVAL);
> +                 }
> +             }
> +
> +           if (!err)
> +             {
> +               /* The ref counts of the ports are incremented
> +                  successfully.  */
> +               /* Install the ports and flags in the new descriptor slot.  */
> +               __spin_lock (&d2->port.lock);
> +               if (flags & O_CLOEXEC)
> +                 d2->flags = d_flags | FD_CLOEXEC;
> +               else
> +                 /* dup clears FD_CLOEXEC.  */
> +                 d2->flags = d_flags & ~FD_CLOEXEC;
> +               if (ctty != MACH_PORT_NULL)
> +                 _hurd_port_set (&d2->ctty, ctty);
> +               _hurd_port_locked_set (&d2->port, port); /* Unlocks D2.  */
> +             }
>           }
>       }
>  
> diff --git a/sysdeps/mach/hurd/fcntl.c b/sysdeps/mach/hurd/fcntl.c
> index a65c190c..56d850e8 100644
> --- a/sysdeps/mach/hurd/fcntl.c
> +++ b/sysdeps/mach/hurd/fcntl.c
> @@ -83,18 +83,46 @@ __libc_fcntl (int fd, int cmd, ...)
>         result = -1;
>       else
>         {
> -         /* Give the ports each a user ref for the new descriptor.  */
> -         __mach_port_mod_refs (__mach_task_self (), port,
> -                               MACH_PORT_RIGHT_SEND, 1);
> -         if (ctty != MACH_PORT_NULL)
> -           __mach_port_mod_refs (__mach_task_self (), ctty,
> -                                 MACH_PORT_RIGHT_SEND, 1);
> -
> -         /* Install the ports and flags in the new descriptor.  */
> -         if (ctty != MACH_PORT_NULL)
> -           _hurd_port_set (&new->ctty, ctty);
> -         new->flags = flags;
> -         _hurd_port_locked_set (&new->port, port); /* Unlocks NEW.  */
> +         /* Give the io server port a user ref for the new descriptor.  */
> +         err = __mach_port_mod_refs (__mach_task_self (), port,
> +                 MACH_PORT_RIGHT_SEND, 1);
> +
> +         if (err == KERN_UREFS_OVERFLOW)
> +              result = __hurd_fail (EMFILE);
> +            else if (err)
> +              result = __hurd_fail (EINVAL);
> +            else if (ctty != MACH_PORT_NULL)
> +           {
> +                /* We have confirmed the io server port has got a user ref
> +                count, now give ctty port a user ref for the new
> +                descriptor.  */
> +                err = __mach_port_mod_refs (__mach_task_self (), ctty,
> +                     MACH_PORT_RIGHT_SEND, 1);
> +
> +             if (err)
> +               {
> +                    /* In this case the io server port has got a ref count
> +                    but the ctty port fails to get one, so we need to clean
> +                    the ref count we just assigned.  */
> +                    __mach_port_mod_refs (__mach_task_self (), port,
> +                         MACH_PORT_RIGHT_SEND, -1);
> +                    if (err == KERN_UREFS_OVERFLOW)
> +                   result = __hurd_fail (EMFILE);
> +                    else
> +                      result = __hurd_fail (EINVAL);
> +                  }
> +           }
> +
> +         if (!err)
> +           {
> +             /* The ref counts of the ports are incremented successfully.  */
> +             /* Install the ports and flags in the new descriptor.  */
> +             if (ctty != MACH_PORT_NULL)
> +               _hurd_port_set (&new->ctty, ctty);
> +             new->flags = flags;
> +             /* Unlocks NEW.  */
> +             _hurd_port_locked_set (&new->port, port);
> +           }
>         }
>  
>       HURD_CRITICAL_END;
> -- 
> 2.47.2
> 

-- 
Samuel
<N> bon comment on fait de l'investigation pour savoir qui est le vilain ?
<s> on débranche le routeur et on regarde qui s'affole
 -+- #ens-mim administre -+-

Reply via email to