[PATCH RFC v3 2/8] io: make __local_isatty () a function; stub should return 0
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Thu May 8 17:39:27 GMT 2025
On 03/05/25 22:42, H. Peter Anvin wrote:
> Make __local_isatty () an actual function instead of being an inline
> in libio. This allows simpler system-specific implementations that
> don't need to touch errno at all.
>
> Add such an implementation for Linux, with a generic fallback.
>
> The stub implementation for isatty() returned -1, errno == ENOSYS, but
> on a tty-less platform 0, errno == ENOTTY is more correct.
>
> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
> ---
> include/unistd.h | 1 +
> io/Makefile | 1 +
> io/isatty.c | 4 ++--
> io/local_isatty.c | 29 ++++++++++++++++++++++++++
> libio/filedoalloc.c | 12 +----------
> sysdeps/unix/sysv/linux/local_isatty.c | 29 ++++++++++++++++++++++++++
> 6 files changed, 63 insertions(+), 13 deletions(-)
> create mode 100644 io/local_isatty.c
> create mode 100644 sysdeps/unix/sysv/linux/local_isatty.c
>
> diff --git a/include/unistd.h b/include/unistd.h
> index e241603b8131..18d56bc4ee0d 100644
> --- a/include/unistd.h
> +++ b/include/unistd.h
> @@ -152,6 +152,7 @@ libc_hidden_proto (__ttyname_r)
> extern __pid_t _Fork (void);
> libc_hidden_proto (_Fork);
> extern int __isatty (int __fd) attribute_hidden;
> +extern int __local_isatty (int __fd) attribute_hidden;
For other internal implementation that do not set errno, usually they
are name as __symbol_nocancel (like the ones in not-cancel.h).
> extern int __link (const char *__from, const char *__to);
> extern int __symlink (const char *__from, const char *__to);
> extern int __symlinkat (const char *__from, int __fd, const char *__to);
> diff --git a/io/Makefile b/io/Makefile
> index e06f3cb3dba1..cc7309f6530b 100644
> --- a/io/Makefile
> +++ b/io/Makefile
> @@ -96,6 +96,7 @@ routines := \
> lchown \
> link \
> linkat \
> + local_isatty \
> lockf \
> lockf64 \
> lseek \
> diff --git a/io/isatty.c b/io/isatty.c
> index 3f3912d8e52b..4eb95fe33eca 100644
> --- a/io/isatty.c
> +++ b/io/isatty.c
> @@ -22,8 +22,8 @@
> int
> __isatty (int fd)
> {
> - __set_errno (ENOSYS);
> - return -1;
> + __set_errno (ENOTTY);
> + return 0;
> }
>
> weak_alias (__isatty, isatty)
The idea of stub implementation is to future pots, although it is unlikely
we will see any in the future. So ENOSYS is to advertise that if you deploy
glibc and programs are calling isatty, you will need to proper implement it
instead of handling a ENOTTY.
So I think this change is not required.
> diff --git a/io/local_isatty.c b/io/local_isatty.c
> new file mode 100644
> index 000000000000..0044f40f2520
> --- /dev/null
> +++ b/io/local_isatty.c
> @@ -0,0 +1,29 @@
> +/* Copyright (C) 1991-2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <errno.h>
> +#include <unistd.h>
> +
> +/* Return 1 if FD is a terminal, 0 if not, without changing errno */
> +int
> +__local_isatty (int fd)
> +{
> + int save_errno = errno;
> + int res = __isatty (fd);
> + __set_errno (save_errno);
> + return res;
> +}
> diff --git a/libio/filedoalloc.c b/libio/filedoalloc.c
> index 9ddd75b42923..b1cd76e9c967 100644
> --- a/libio/filedoalloc.c
> +++ b/libio/filedoalloc.c
> @@ -61,16 +61,6 @@
> #include <stdlib.h>
> #include <unistd.h>
>
> -/* Return the result of isatty, without changing errno. */
> -static int
> -local_isatty (int fd)
> -{
> - int save_errno = errno;
> - int res = __isatty (fd);
> - __set_errno (save_errno);
> - return res;
> -}
> -
> /* Allocate a file buffer, or switch to unbuffered I/O. Streams for
> TTY devices default to line buffered. */
> int
> @@ -90,7 +80,7 @@ _IO_file_doallocate (FILE *fp)
> #ifdef DEV_TTY_P
> DEV_TTY_P (&st) ||
> #endif
> - local_isatty (fp->_fileno))
> + __local_isatty (fp->_fileno))
> fp->_flags |= _IO_LINE_BUF;
> }
> #if defined _STATBUF_ST_BLKSIZE
> diff --git a/sysdeps/unix/sysv/linux/local_isatty.c b/sysdeps/unix/sysv/linux/local_isatty.c
> new file mode 100644
> index 000000000000..3bd5f67ea7da
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/local_isatty.c
> @@ -0,0 +1,29 @@
> +/* Copyright (C) 1991-2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <termios.h>
> +#include <kernel_termios.h>
> +#include <sys/ioctl.h>
> +
> +/* Return 1 if FD is a terminal, 0 if not, without changing errno */
> +int
> +__local_isatty (int fd)
> +{
> + struct __kernel_termios k_termios;
> + return INTERNAL_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios) == 0;
Use INTERNAL_SYSCALL_CALL macro here, to avoid the need to pass the
number of arguments.
> +}
More information about the Libc-alpha
mailing list