aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-31 01:52:18 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-31 01:52:18 +0100
commit7c3c92c533b65d4c29f2990915c9c424c3f6629d (patch)
treed9eb784d9c458c3d91fcf9a9e31e636f39d8a360
parenta92a74961d838209f3468d10426bc945ba26070c (diff)
downloadbusybox-w32-7c3c92c533b65d4c29f2990915c9c424c3f6629d.tar.gz
busybox-w32-7c3c92c533b65d4c29f2990915c9c424c3f6629d.tar.bz2
busybox-w32-7c3c92c533b65d4c29f2990915c9c424c3f6629d.zip
man: make width selection more thorough; explain how to override it
Fedora's "man CMD >file" still uses terminal width, not 80 (but disables formatting), this change mimics that. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/xfuncs.c47
-rw-r--r--miscutils/man.c13
2 files changed, 44 insertions, 16 deletions
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 3f9a84ad4..45650edba 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -237,16 +237,27 @@ ssize_t FAST_FUNC full_write2_str(const char *str)
237 237
238static int wh_helper(int value, int def_val, const char *env_name, int *err) 238static int wh_helper(int value, int def_val, const char *env_name, int *err)
239{ 239{
240 if (value == 0) { 240 /* Envvars override even if "value" from ioctl is valid (>0).
241 char *s = getenv(env_name); 241 * Rationale: it's impossible to guess what user wants.
242 if (s) { 242 * For example: "man CMD | ...": should "man" format output
243 value = atoi(s); 243 * to stdout's width? stdin's width? /dev/tty's width? 80 chars?
244 /* If LINES/COLUMNS are set, pretend that there is 244 * We _cant_ know it. If "..." saves text for e.g. email,
245 * no error getting w/h, this prevents some ugly 245 * then it's probably 80 chars.
246 * cursor tricks by our callers */ 246 * If "..." is, say, "grep -v DISCARD | $PAGER", then user
247 *err = 0; 247 * would prefer his tty's width to be used!
248 } 248 *
249 * Since we don't know, at least allow user to do this:
250 * "COLUMNS=80 man CMD | ..."
251 */
252 char *s = getenv(env_name);
253 if (s) {
254 value = atoi(s);
255 /* If LINES/COLUMNS are set, pretend that there is
256 * no error getting w/h, this prevents some ugly
257 * cursor tricks by our callers */
258 *err = 0;
249 } 259 }
260
250 if (value <= 1 || value >= 30000) 261 if (value <= 1 || value >= 30000)
251 value = def_val; 262 value = def_val;
252 return value; 263 return value;
@@ -258,6 +269,20 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh
258{ 269{
259 struct winsize win; 270 struct winsize win;
260 int err; 271 int err;
272 int close_me = -1;
273
274 if (fd == -1) {
275 if (isatty(STDOUT_FILENO))
276 fd = STDOUT_FILENO;
277 else
278 if (isatty(STDERR_FILENO))
279 fd = STDERR_FILENO;
280 else
281 if (isatty(STDIN_FILENO))
282 fd = STDIN_FILENO;
283 else
284 close_me = fd = open("/dev/tty", O_RDONLY);
285 }
261 286
262 win.ws_row = 0; 287 win.ws_row = 0;
263 win.ws_col = 0; 288 win.ws_col = 0;
@@ -268,6 +293,10 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh
268 *height = wh_helper(win.ws_row, 24, "LINES", &err); 293 *height = wh_helper(win.ws_row, 24, "LINES", &err);
269 if (width) 294 if (width)
270 *width = wh_helper(win.ws_col, 80, "COLUMNS", &err); 295 *width = wh_helper(win.ws_col, 80, "COLUMNS", &err);
296
297 if (close_me >= 0)
298 close(close_me);
299
271 return err; 300 return err;
272} 301}
273int FAST_FUNC get_terminal_width(int fd) 302int FAST_FUNC get_terminal_width(int fd)
diff --git a/miscutils/man.c b/miscutils/man.c
index 01382c4d7..adb7770b4 100644
--- a/miscutils/man.c
+++ b/miscutils/man.c
@@ -9,6 +9,8 @@
9//usage: "Format and display manual page\n" 9//usage: "Format and display manual page\n"
10//usage: "\n -a Display all pages" 10//usage: "\n -a Display all pages"
11//usage: "\n -w Show page locations" 11//usage: "\n -w Show page locations"
12//usage: "\n"
13//usage: "\n$COLUMNS overrides output width"
12 14
13#include "libbb.h" 15#include "libbb.h"
14#include "common_bufsiz.h" 16#include "common_bufsiz.h"
@@ -53,7 +55,7 @@ struct globals {
53 setup_common_bufsiz(); \ 55 setup_common_bufsiz(); \
54 G.col = "col"; \ 56 G.col = "col"; \
55 G.tbl = "tbl"; \ 57 G.tbl = "tbl"; \
56 /* replaced -Tlatin1 with -Tascii for non-UTF8 displays */; \ 58 /* replaced -Tlatin1 with -Tascii for non-UTF8 displays */ \
57 G.nroff = "nroff -mandoc -Tascii"; \ 59 G.nroff = "nroff -mandoc -Tascii"; \
58 G.pager = ENABLE_LESS ? "less" : "more"; \ 60 G.pager = ENABLE_LESS ? "less" : "more"; \
59} while (0) 61} while (0)
@@ -132,15 +134,12 @@ static int run_pipe(char *man_filename, int man, int level)
132 close(STDIN_FILENO); 134 close(STDIN_FILENO);
133 open_zipped(man_filename, /*fail_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */ 135 open_zipped(man_filename, /*fail_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */
134 if (man) { 136 if (man) {
135 /* "man man" formats to screen width. 137 int w = get_terminal_width(-1);
136 * "man man >file" formats to default 80 columns.
137 * "man man | cat" formats to default 80 columns.
138 */
139 int w = get_terminal_width(STDOUT_FILENO);
140 if (w > 10) 138 if (w > 10)
141 w -= 2; 139 w -= 2;
142 /* "2>&1" is added so that nroff errors are shown in pager too. 140 /* "2>&1" is added so that nroff errors are shown in pager too.
143 * Otherwise it may show just empty screen */ 141 * Otherwise it may show just empty screen.
142 */
144 cmd = xasprintf("%s | %s -rLL=%un -rLT=%un 2>&1 | %s", 143 cmd = xasprintf("%s | %s -rLL=%un -rLT=%un 2>&1 | %s",
145 G.tbl, G.nroff, w, w, 144 G.tbl, G.nroff, w, w,
146 G.pager); 145 G.pager);