This patch is quite conservative, only the first mach_port_mod_ref() is checked, as I haven't found an elegant way to check both mach_port_mod_ref()s.
I haven't successfully tested this patch. I have tried several methods to apply the patch and build but failed: - Clone the glibc source code, try to build with '--prefix=' and '--prefix=/usr', and `sudo make install`. The results were a broken system. I cannot run any command, it just output 'XXX.so file not found'. - Run 'apt source glibc', use quilt to apply this patch and build the libc package using `dpkg-buildpackage -B`. I got the same error as [0]. [0]: https://buildd.debian.org/status/fetch.php?pkg=glibc&arch=hurd-i386&ver=2.41-3&stamp=1740910186&raw=0 - Run 'apt source glibc=2.40-7' (as I found this is the newest successful build on the website). I have successfully built a glibc once, but after a `apt upgrade` it failed with the following output: ``` ... /usr/bin/ld: /lib/i386-gnu/liblzma.so.5: undefined reference to `pthread_sigmask@GLIBC_2.41' /usr/bin/ld: /lib/i386-gnu/liblzma.so.5: undefined reference to `pthread_condattr_setclock@GLIBC_2.41' collect2: error: ld returned 1 exit status ... ``` Maybe some downgrade is needed? I'm not very familiar with the Debian building system, maybe I mis-read something in the package building tutorial. Best, Zhaoming --- sysdeps/mach/hurd/fcntl.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/sysdeps/mach/hurd/fcntl.c b/sysdeps/mach/hurd/fcntl.c index a65c190c..d97226cd 100644 --- a/sysdeps/mach/hurd/fcntl.c +++ b/sysdeps/mach/hurd/fcntl.c @@ -83,18 +83,34 @@ __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, + /* Give the ports (i.e. `ctty` and `port`) each a user ref for + the new descriptor. */ + err = __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. */ + + if (err) + { + /* When an error occurs during giving a user ref to the + io server port */ + result = -1; + + if (err == KERN_UREFS_OVERFLOW) + errno = EMFILE; + else + errno = EINVAL; + } + else + { + 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. */ + } } HURD_CRITICAL_END; -- 2.47.2