mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
xz: Create separate is_tty() function.
The new is_tty() will report if a file descriptor is a terminal or not. On POSIX systems, it is a wrapper around isatty(). However, the native Windows implementation of isatty() will return true for all character devices, not just terminals. So is_tty() has a special case for Windows so it can use alternative Windows API functions to determine if a file descriptor is a terminal. This fixes a bug with MSVC and MinGW-w64 builds that refused to read from or write to non-terminal character devices because xz thought it was a terminal. For instance: xz foo -c > /dev/null would fail because /dev/null was assumed to be a terminal.
This commit is contained in:
parent
6b05f827f5
commit
584e3a258f
2 changed files with 37 additions and 7 deletions
|
@ -13,11 +13,6 @@
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# include <io.h>
|
|
||||||
# define isatty _isatty
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/// Buffers for uint64_to_str() and uint64_to_nicestr()
|
/// Buffers for uint64_to_str() and uint64_to_nicestr()
|
||||||
static char bufs[4][128];
|
static char bufs[4][128];
|
||||||
|
@ -266,10 +261,31 @@ my_snprintf(char **pos, size_t *left, const char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
is_tty(int fd)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
// There is no need to check if handle == INVALID_HANDLE_VALUE
|
||||||
|
// because it will return false anyway when used in GetConsoleMode().
|
||||||
|
// The resulting HANDLE does not need to be closed based on Windows
|
||||||
|
// API documentation.
|
||||||
|
intptr_t handle = _get_osfhandle(fd);
|
||||||
|
DWORD mode;
|
||||||
|
|
||||||
|
// GetConsoleMode() is an easy way to tell if the HANDLE is a
|
||||||
|
// console or not. We do not care about the value of mode since we
|
||||||
|
// do not plan to use any further Windows console functions.
|
||||||
|
return GetConsoleMode((HANDLE)handle, &mode);
|
||||||
|
#else
|
||||||
|
return isatty(fd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern bool
|
extern bool
|
||||||
is_tty_stdin(void)
|
is_tty_stdin(void)
|
||||||
{
|
{
|
||||||
const bool ret = isatty(STDIN_FILENO);
|
const bool ret = is_tty(STDIN_FILENO);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
message_error(_("Compressed data cannot be read from "
|
message_error(_("Compressed data cannot be read from "
|
||||||
|
@ -282,7 +298,7 @@ is_tty_stdin(void)
|
||||||
extern bool
|
extern bool
|
||||||
is_tty_stdout(void)
|
is_tty_stdout(void)
|
||||||
{
|
{
|
||||||
const bool ret = isatty(STDOUT_FILENO);
|
const bool ret = is_tty(STDOUT_FILENO);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
message_error(_("Compressed data cannot be written to "
|
message_error(_("Compressed data cannot be written to "
|
||||||
|
|
|
@ -105,6 +105,20 @@ lzma_attribute((__format__(__printf__, 3, 4)))
|
||||||
extern void my_snprintf(char **pos, size_t *left, const char *fmt, ...);
|
extern void my_snprintf(char **pos, size_t *left, const char *fmt, ...);
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Test if file descriptor is a terminal
|
||||||
|
///
|
||||||
|
/// For POSIX systems, this is a simple wrapper around isatty(). However on
|
||||||
|
/// Windows, isatty() returns true for all character devices, not just
|
||||||
|
/// terminals.
|
||||||
|
///
|
||||||
|
/// \param fd File descriptor to test
|
||||||
|
///
|
||||||
|
/// \return bool:
|
||||||
|
/// - true if file descriptor is a terminal
|
||||||
|
/// - false otherwise
|
||||||
|
extern bool is_tty(int fd);
|
||||||
|
|
||||||
|
|
||||||
/// \brief Test if stdin is a terminal
|
/// \brief Test if stdin is a terminal
|
||||||
///
|
///
|
||||||
/// If stdin is a terminal, an error message is printed and exit status set
|
/// If stdin is a terminal, an error message is printed and exit status set
|
||||||
|
|
Loading…
Reference in a new issue