mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +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()).
|
||||
** `readdir` and `ttyname` now release scm_i_misc_mutex during asyncs
|
||||
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)
|
||||
|
|
|
@ -554,6 +554,7 @@ SCM_DEFINE (scm_adjust_port_revealed_x, "adjust-port-revealed!", 2, 0, 0,
|
|||
|
||||
|
||||
|
||||
#define FUNC_NAME "fport_print"
|
||||
static int
|
||||
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);
|
||||
fdes = (SCM_FSTREAM (exp))->fdes;
|
||||
|
||||
#if (defined HAVE_TTYNAME) && (defined HAVE_POSIX)
|
||||
if (isatty (fdes))
|
||||
scm_display (scm_ttyname (exp), port);
|
||||
#if (!defined HAVE_TTYNAME) || (!defined HAVE_POSIX)
|
||||
scm_intprint (fdes, 10, port);
|
||||
#else
|
||||
if (!isatty (fdes))
|
||||
scm_intprint (fdes, 10, port);
|
||||
else
|
||||
#endif /* HAVE_TTYNAME */
|
||||
scm_intprint (fdes, 10, port);
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -586,6 +602,7 @@ fport_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
|
|||
scm_putc ('>', port);
|
||||
return 1;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
/* fill a port's read-buffer with a single read. returns the first
|
||||
char or EOF if end of file. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue