diff --git a/src/Makefile.inc b/src/Makefile.inc index c1d202a061..92efa2756a 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -59,6 +59,7 @@ CURLX_HFILES = \ CURL_CFILES = \ slist_wc.c \ + terminal.c \ tool_binmode.c \ tool_bname.c \ tool_cb_dbg.c \ @@ -103,6 +104,7 @@ CURL_CFILES = \ CURL_HFILES = \ slist_wc.h \ + terminal.h \ tool_binmode.h \ tool_bname.h \ tool_cb_dbg.h \ diff --git a/src/terminal.c b/src/terminal.c new file mode 100644 index 0000000000..08b1bdd2d6 --- /dev/null +++ b/src/terminal.c @@ -0,0 +1,91 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "tool_setup.h" + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#include "terminal.h" + +#include "memdebug.h" /* keep this as LAST include */ + +#ifdef HAVE_TERMIOS_H +# include +#elif defined(HAVE_TERMIO_H) +# include +#endif + +/* + * get_terminal_columns() returns the number of columns in the current + * terminal. It will return 79 on failure. Also, the number can be very big. + */ + +unsigned int get_terminal_columns(void) +{ + unsigned int width = 0; + char *colp = curl_getenv("COLUMNS"); + if(colp) { + char *endptr; + long num = strtol(colp, &endptr, 10); + if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 20) && + (num < 10000)) + width = (unsigned int)num; + curl_free(colp); + } + + if(!width) { + int cols = 0; + +#ifdef TIOCGSIZE + struct ttysize ts; + if(!ioctl(STDIN_FILENO, TIOCGSIZE, &ts)) + cols = ts.ts_cols; +#elif defined(TIOCGWINSZ) + struct winsize ts; + if(!ioctl(STDIN_FILENO, TIOCGWINSZ, &ts)) + cols = (int)ts.ws_col; +#elif defined(_WIN32) + { + HANDLE stderr_hnd = GetStdHandle(STD_ERROR_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO console_info; + + if((stderr_hnd != INVALID_HANDLE_VALUE) && + GetConsoleScreenBufferInfo(stderr_hnd, &console_info)) { + /* + * Do not use +1 to get the true screen-width since writing a + * character at the right edge will cause a line wrap. + */ + cols = (int) + (console_info.srWindow.Right - console_info.srWindow.Left); + } + } +#endif /* TIOCGSIZE */ + if(cols >= 0 && cols < 10000) + width = (unsigned int)cols; + } + if(!width) + width = 79; + return width; /* 79 for unknown, might also be very small or very big */ +} diff --git a/src/terminal.h b/src/terminal.h new file mode 100644 index 0000000000..dbd4abe281 --- /dev/null +++ b/src/terminal.h @@ -0,0 +1,30 @@ +#ifndef HEADER_CURL_TERMINAL_H +#define HEADER_CURL_TERMINAL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "tool_setup.h" + +unsigned int get_terminal_columns(void); + +#endif /* HEADER_CURL_TERMINAL_H */ diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c index 8e50908ddd..1c06b14d99 100644 --- a/src/tool_cb_prg.c +++ b/src/tool_cb_prg.c @@ -23,10 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - #define ENABLE_CURLX_PRINTF /* use our own printf() functions */ #include "curlx.h" @@ -35,17 +31,12 @@ #include "tool_cb_prg.h" #include "tool_util.h" #include "tool_operate.h" +#include "terminal.h" #include "memdebug.h" /* keep this as LAST include */ #define MAX_BARLENGTH 256 -#ifdef HAVE_TERMIOS_H -# include -#elif defined(HAVE_TERMIO_H) -# include -#endif - /* 200 values generated by this perl code: my $pi = 3.1415; @@ -229,59 +220,6 @@ int tool_progress_cb(void *clientp, return 0; } -/* - * get_terminal_columns() returns the number of columns in the current - * terminal. It will return 79 on failure. Also, the number can be very big. - */ - -unsigned int get_terminal_columns(void) -{ - unsigned int width = 0; - char *colp = curl_getenv("COLUMNS"); - if(colp) { - char *endptr; - long num = strtol(colp, &endptr, 10); - if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 20) && - (num < 10000)) - width = (unsigned int)num; - curl_free(colp); - } - - if(!width) { - int cols = 0; - -#ifdef TIOCGSIZE - struct ttysize ts; - if(!ioctl(STDIN_FILENO, TIOCGSIZE, &ts)) - cols = ts.ts_cols; -#elif defined(TIOCGWINSZ) - struct winsize ts; - if(!ioctl(STDIN_FILENO, TIOCGWINSZ, &ts)) - cols = (int)ts.ws_col; -#elif defined(_WIN32) - { - HANDLE stderr_hnd = GetStdHandle(STD_ERROR_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO console_info; - - if((stderr_hnd != INVALID_HANDLE_VALUE) && - GetConsoleScreenBufferInfo(stderr_hnd, &console_info)) { - /* - * Do not use +1 to get the true screen-width since writing a - * character at the right edge will cause a line wrap. - */ - cols = (int) - (console_info.srWindow.Right - console_info.srWindow.Left); - } - } -#endif /* TIOCGSIZE */ - if(cols >= 0 && cols < 10000) - width = (unsigned int)cols; - } - if(!width) - width = 79; - return width; /* 79 for unknown, might also be very small or very big */ -} - void progressbarinit(struct ProgressData *bar, struct OperationConfig *config) { diff --git a/src/tool_cb_prg.h b/src/tool_cb_prg.h index b012457dfa..dc10f2a5cc 100644 --- a/src/tool_cb_prg.h +++ b/src/tool_cb_prg.h @@ -45,8 +45,6 @@ struct OperationConfig; void progressbarinit(struct ProgressData *bar, struct OperationConfig *config); -unsigned int get_terminal_columns(void); - /* ** callback for CURLOPT_PROGRESSFUNCTION */ diff --git a/src/tool_help.c b/src/tool_help.c index f74033d0ad..6d29fd8f66 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -31,6 +31,7 @@ #include "tool_util.h" #include "tool_version.h" #include "tool_cb_prg.h" +#include "terminal.h" #include "memdebug.h" /* keep this as LAST include */ diff --git a/src/tool_msgs.c b/src/tool_msgs.c index 09c9310a52..47e625c1e3 100644 --- a/src/tool_msgs.c +++ b/src/tool_msgs.c @@ -29,6 +29,8 @@ #include "tool_cfgable.h" #include "tool_msgs.h" +#include "tool_cb_prg.h" +#include "terminal.h" #include "memdebug.h" /* keep this as LAST include */ @@ -46,7 +48,7 @@ static void voutf(struct GlobalConfig *config, const char *fmt, va_list ap) { - size_t width = (79 - strlen(prefix)); + size_t width = (get_terminal_columns() - strlen(prefix)); DEBUGASSERT(!strchr(fmt, '\n')); if(!config->silent) { size_t len;