Merge "<termios.h>: add two new POSIX functions." into main am: b130e6dae0
am: f9189bb67d
am: 0e87776adc
am: 42fd8dbd98
Original change: https://android-review.googlesource.com/c/platform/bionic/+/2729340 Change-Id: I602ab8133e3460918a579cd673f2ff52ed98f2be Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
678e06ac31
8 changed files with 145 additions and 0 deletions
|
@ -56,6 +56,7 @@ list of POSIX functions implemented by glibc but not by bionic.
|
|||
Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
|
||||
|
||||
New libc functions in V (API level 35):
|
||||
* `tcgetwinsize`, `tcsetwinsize` (POSIX Issue 8 additions).
|
||||
* `timespec_getres` (C23 addition).
|
||||
* `localtime_rz`, `mktime_z`, `tzalloc`, and `tzfree` (NetBSD
|
||||
extensions implemented in tzcode, and the "least non-standard"
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#define __BIONIC_TERMIOS_INLINE /* Out of line. */
|
||||
#include <bits/termios_inlines.h>
|
||||
|
||||
// POSIX added a couple more functions much later, so do the same for them.
|
||||
#define __BIONIC_TERMIOS_WINSIZE_INLINE /* Out of line. */
|
||||
#include <bits/termios_winsize_inlines.h>
|
||||
|
||||
// Actually declared in <unistd.h>, present on all API levels.
|
||||
pid_t tcgetpgrp(int fd) {
|
||||
pid_t pid;
|
||||
|
|
|
@ -43,3 +43,10 @@
|
|||
#include <bits/termios_inlines.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if __ANDROID_API__ < 35
|
||||
|
||||
#define __BIONIC_TERMIOS_WINSIZE_INLINE static __inline
|
||||
#include <bits/termios_winsize_inlines.h>
|
||||
|
||||
#endif
|
||||
|
|
52
libc/include/bits/termios_winsize_inlines.h
Normal file
52
libc/include/bits/termios_winsize_inlines.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
|
||||
#if !defined(__BIONIC_TERMIOS_WINSIZE_INLINE)
|
||||
#define __BIONIC_TERMIOS_WINSIZE_INLINE static __inline
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
__BIONIC_TERMIOS_WINSIZE_INLINE int tcgetwinsize(int __fd, struct winsize* _Nonnull __size) {
|
||||
return ioctl(__fd, TIOCGWINSZ, __size);
|
||||
}
|
||||
|
||||
__BIONIC_TERMIOS_WINSIZE_INLINE int tcsetwinsize(int __fd, const struct winsize* _Nonnull __size) {
|
||||
return ioctl(__fd, TIOCSWINSZ, __size);
|
||||
}
|
||||
|
||||
__END_DECLS
|
|
@ -149,6 +149,25 @@ int tcsetattr(int __fd, int __optional_actions, const struct termios* _Nonnull _
|
|||
|
||||
#endif
|
||||
|
||||
#if __ANDROID_API__ >= 35
|
||||
// These two functions were POSIX Issue 8 additions that we can also trivially
|
||||
// implement as inlines for older OS version.
|
||||
|
||||
/**
|
||||
* tcgetwinsize(3) gets the window size of the given terminal.
|
||||
*
|
||||
* Returns 0 on success and returns -1 and sets `errno` on failure.
|
||||
*/
|
||||
int tcgetwinsize(int __fd, struct winsize* _Nonnull __size);
|
||||
|
||||
/**
|
||||
* tcsetwinsize(3) sets the window size of the given terminal.
|
||||
*
|
||||
* Returns 0 on success and returns -1 and sets `errno` on failure.
|
||||
*/
|
||||
int tcsetwinsize(int __fd, const struct winsize* _Nonnull __size);
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#include <android/legacy_termios_inlines.h>
|
||||
|
|
|
@ -1591,6 +1591,8 @@ LIBC_V { # introduced=VanillaIceCream
|
|||
mktime_z;
|
||||
__riscv_flush_icache; # riscv64
|
||||
__riscv_hwprobe; # riscv64
|
||||
tcgetwinsize;
|
||||
tcsetwinsize;
|
||||
timespec_getres;
|
||||
tzalloc;
|
||||
tzfree;
|
||||
|
|
|
@ -42,6 +42,12 @@ static void termios_h() {
|
|||
STRUCT_MEMBER(struct termios, tcflag_t, c_lflag);
|
||||
STRUCT_MEMBER_ARRAY(struct termios, cc_t/*[]*/, c_cc);
|
||||
|
||||
#if !defined(__GLIBC__) // Our glibc is too old.
|
||||
TYPE(struct winsize);
|
||||
STRUCT_MEMBER(struct winsize, unsigned short, ws_row);
|
||||
STRUCT_MEMBER(struct winsize, unsigned short, ws_col);
|
||||
#endif
|
||||
|
||||
MACRO(NCCS);
|
||||
|
||||
MACRO(VEOF);
|
||||
|
@ -162,6 +168,12 @@ static void termios_h() {
|
|||
FUNCTION(tcflush, int (*f)(int, int));
|
||||
FUNCTION(tcgetattr, int (*f)(int, struct termios*));
|
||||
FUNCTION(tcgetsid, pid_t (*f)(int));
|
||||
#if !defined(__GLIBC__) // Our glibc is too old.
|
||||
FUNCTION(tcgetwinsize, int (*f)(int, struct winsize*));
|
||||
#endif
|
||||
FUNCTION(tcsendbreak, int (*f)(int, int));
|
||||
FUNCTION(tcsetattr, int (*f)(int, int, const struct termios*));
|
||||
#if !defined(__GLIBC__) // Our glibc is too old.
|
||||
FUNCTION(tcsetwinsize, int (*f)(int, const struct winsize*));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include <termios.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pty.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
@ -96,3 +98,49 @@ TEST(termios, cfmakeraw) {
|
|||
EXPECT_EQ(1, t.c_cc[VMIN]);
|
||||
EXPECT_EQ(0, t.c_cc[VTIME]);
|
||||
}
|
||||
|
||||
TEST(termios, tcgetwinsize_tcsetwinsize_invalid) {
|
||||
#if !defined(__GLIBC__)
|
||||
winsize ws = {};
|
||||
|
||||
errno = 0;
|
||||
ASSERT_EQ(-1, tcgetwinsize(-1, &ws));
|
||||
ASSERT_EQ(EBADF, errno);
|
||||
|
||||
errno = 0;
|
||||
ASSERT_EQ(-1, tcsetwinsize(-1, &ws));
|
||||
ASSERT_EQ(EBADF, errno);
|
||||
#else
|
||||
GTEST_SKIP() << "glibc too old";
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(termios, tcgetwinsize_tcsetwinsize) {
|
||||
#if !defined(__GLIBC__)
|
||||
int pty, tty;
|
||||
winsize ws = {123, 456, 9999, 9999};
|
||||
ASSERT_EQ(0, openpty(&pty, &tty, nullptr, nullptr, &ws));
|
||||
|
||||
winsize actual = {};
|
||||
ASSERT_EQ(0, tcgetwinsize(tty, &actual));
|
||||
EXPECT_EQ(ws.ws_xpixel, actual.ws_xpixel);
|
||||
EXPECT_EQ(ws.ws_ypixel, actual.ws_ypixel);
|
||||
EXPECT_EQ(ws.ws_row, actual.ws_row);
|
||||
EXPECT_EQ(ws.ws_col, actual.ws_col);
|
||||
|
||||
ws = {1, 2, 3, 4};
|
||||
ASSERT_EQ(0, tcsetwinsize(tty, &ws));
|
||||
|
||||
actual = {};
|
||||
ASSERT_EQ(0, tcgetwinsize(tty, &actual));
|
||||
EXPECT_EQ(ws.ws_xpixel, actual.ws_xpixel);
|
||||
EXPECT_EQ(ws.ws_ypixel, actual.ws_ypixel);
|
||||
EXPECT_EQ(ws.ws_row, actual.ws_row);
|
||||
EXPECT_EQ(ws.ws_col, actual.ws_col);
|
||||
|
||||
close(pty);
|
||||
close(tty);
|
||||
#else
|
||||
GTEST_SKIP() << "glibc too old";
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue