mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 13:00:26 +02:00
fport_print: handle ttyname ENODEV
In some situations, ttyname may return ENODEV even though isatty is true. From ttyname(3): A process that keeps a file descriptor that refers to a pts(4) device open when switching to another mount namespace that uses a different /dev/ptmx instance may still accidentally find that a device path of the same name for that file descriptor exists. However, this device path refers to a different device and thus can't be used to access the device that the file descriptor refers to. Calling ttyname() or ttyname_r() on the file descriptor in the new mount namespace will cause these functions to return NULL and set errno to ENODEV. Observed in a Debian riscv64 porterbox schroot. When ttyname fails with ENODEV, just include the file descriptor integer value instead. Call ttyname() directly to avoid having to catch the ENODEV. * libguile/fports.c (fport_print): fall back to the integer fd when ttyname() fails with ENODEV.
This commit is contained in:
parent
63756efbc5
commit
48b1c4eff4
2 changed files with 27 additions and 5 deletions
5
NEWS
5
NEWS
|
@ -71,6 +71,11 @@ every line in a file.
|
||||||
tag for their type (e.g. ending up tagged as immediates SCM_IMP()).
|
tag for their type (e.g. ending up tagged as immediates SCM_IMP()).
|
||||||
** `readdir` and `ttyname` now release scm_i_misc_mutex during asyncs
|
** `readdir` and `ttyname` now release scm_i_misc_mutex during asyncs
|
||||||
This avoids potential deadlocks.
|
This avoids potential deadlocks.
|
||||||
|
** Displaying a `port` won't fail when `ttyname` returns ENODEV
|
||||||
|
`ttyname` may return ENODEV even when the port `isatty()`, and
|
||||||
|
previously Guile would pass through the related exception. Now it
|
||||||
|
prints the file descriptor instead (as it does when `ttyname` isn't
|
||||||
|
available or the port isn't a tty).
|
||||||
|
|
||||||
|
|
||||||
Changes in 3.0.10 (since 3.0.9)
|
Changes in 3.0.10 (since 3.0.9)
|
||||||
|
|
|
@ -554,6 +554,7 @@ SCM_DEFINE (scm_adjust_port_revealed_x, "adjust-port-revealed!", 2, 0, 0,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define FUNC_NAME "fport_print"
|
||||||
static int
|
static int
|
||||||
fport_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
|
fport_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -570,12 +571,27 @@ fport_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
|
||||||
scm_putc (' ', port);
|
scm_putc (' ', port);
|
||||||
fdes = (SCM_FSTREAM (exp))->fdes;
|
fdes = (SCM_FSTREAM (exp))->fdes;
|
||||||
|
|
||||||
#if (defined HAVE_TTYNAME) && (defined HAVE_POSIX)
|
#if (!defined HAVE_TTYNAME) || (!defined HAVE_POSIX)
|
||||||
if (isatty (fdes))
|
|
||||||
scm_display (scm_ttyname (exp), port);
|
|
||||||
else
|
|
||||||
#endif /* HAVE_TTYNAME */
|
|
||||||
scm_intprint (fdes, 10, port);
|
scm_intprint (fdes, 10, port);
|
||||||
|
#else
|
||||||
|
if (!isatty (fdes))
|
||||||
|
scm_intprint (fdes, 10, port);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *name = 0;
|
||||||
|
SCM_I_LOCKED_SYSCALL(&scm_i_misc_mutex,
|
||||||
|
char *n = ttyname (fdes);
|
||||||
|
if (n) name = strdup (n));
|
||||||
|
if (name)
|
||||||
|
scm_display (scm_take_locale_string (name), port);
|
||||||
|
else if (errno == ENODEV)
|
||||||
|
// In some situations ttyname may return ENODEV even though
|
||||||
|
// isatty is true. See GNU/Linux ttyname(3) as an example.
|
||||||
|
scm_intprint (fdes, 10, port);
|
||||||
|
else
|
||||||
|
SCM_SYSERROR;
|
||||||
|
}
|
||||||
|
#endif // (defined HAVE_TTYNAME) && (defined HAVE_POSIX)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -586,6 +602,7 @@ fport_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
|
||||||
scm_putc ('>', port);
|
scm_putc ('>', port);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
/* fill a port's read-buffer with a single read. returns the first
|
/* fill a port's read-buffer with a single read. returns the first
|
||||||
char or EOF if end of file. */
|
char or EOF if end of file. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue