Skip to content

Commit 89167c1

Browse files
rathannbitprophet
authored andcommitted
handle TIOCGWINSZ struct correctly
`TIOCGWINSZ` contains 4, not 2 unsigned shorts: ```C struct winsize { unsigned short ws_row; unsigned short ws_col; unsigned short ws_xpixel; /* unused */ unsigned short ws_ypixel; /* unused */ }; ``` Fixes the following test failures when building with Python3.14: ``` =========================== short test summary info ============================ FAILED tests/runners.py::Local_::pty::when_pty_True_we_use_pty_fork_and_os_exec - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::pty_uses_WEXITSTATUS_if_WIFEXITED - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::pty_uses_WTERMSIG_if_WIFSIGNALED - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::WTERMSIG_result_turned_negative_to_match_subprocess - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::pty_is_set_to_controlling_terminal_size - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::spurious_OSErrors_handled_gracefully - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::other_spurious_OSErrors_handled_gracefully - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::non_spurious_OSErrors_bubble_up - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::stop_mutes_errors_on_pty_close - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::fallback::can_be_overridden_by_kwarg - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::fallback::can_be_overridden_by_config - SystemError: buffer overflow FAILED tests/runners.py::Local_::pty::fallback::overridden_fallback_affects_result_pty_value - SystemError: buffer overflow FAILED tests/runners.py::Local_::shell::defaults_to_bash_or_cmdexe_when_pty_True - SystemError: buffer overflow FAILED tests/runners.py::Local_::shell::may_be_overridden_when_pty_True - SystemError: buffer overflow FAILED tests/runners.py::Local_::env::uses_execve_for_pty_True - SystemError: buffer overflow FAILED tests/terminals.py::terminals::pty_size::calls_fcntl_with_TIOCGWINSZ - SystemError: buffer overflow ================== 16 failed, 952 passed, 11 skipped in 6.67s ================== ``` Resolves #1038 .
1 parent 0a020da commit 89167c1

1 file changed

Lines changed: 4 additions & 3 deletions

File tree

invoke/terminals.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,18 @@ def _pty_size() -> Tuple[Optional[int], Optional[int]]:
8787
# Sentinel values to be replaced w/ defaults by caller
8888
size = (None, None)
8989
# We want two short unsigned integers (rows, cols)
90-
fmt = "HH"
90+
# Note: TIOCGWINSZ struct contains 4 unsigned shorts, 2 unused
91+
fmt = "HHHH"
9192
# Create an empty (zeroed) buffer for ioctl to map onto. Yay for C!
92-
buf = struct.pack(fmt, 0, 0)
93+
buf = struct.pack(fmt, 0, 0, 0, 0)
9394
# Call TIOCGWINSZ to get window size of stdout, returns our filled
9495
# buffer
9596
try:
9697
result = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf)
9798
# Unpack buffer back into Python data types
9899
# NOTE: this unpack gives us rows x cols, but we return the
99100
# inverse.
100-
rows, cols = struct.unpack(fmt, result)
101+
rows, cols, *_ = struct.unpack(fmt, result)
101102
return (cols, rows)
102103
# Fallback to emptyish return value in various failure cases:
103104
# * sys.stdout being monkeypatched, such as in testing, and lacking

0 commit comments

Comments
 (0)