1303 files changed, 32187 insertions, 57138 deletions
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 23f2751..45650ed 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -25,20 +25,22 @@ #include "libbb.h" /* Turn on nonblocking I/O on a fd */ -void FAST_FUNC ndelay_on(int fd) +int FAST_FUNC ndelay_on(int fd) { int flags = fcntl(fd, F_GETFL); if (flags & O_NONBLOCK) - return; + return flags; fcntl(fd, F_SETFL, flags | O_NONBLOCK); + return flags; } -void FAST_FUNC ndelay_off(int fd) +int FAST_FUNC ndelay_off(int fd) { int flags = fcntl(fd, F_GETFL); if (!(flags & O_NONBLOCK)) - return; + return flags; fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); + return flags; } void FAST_FUNC close_on_exec_on(int fd) @@ -205,7 +207,6 @@ off_t FAST_FUNC fdlength(int fd) else bottom = pos; // If we can't, it's smaller. - } else { if (bottom == top) { if (!top) return 0; @@ -236,16 +237,27 @@ ssize_t FAST_FUNC full_write2_str(const char *str) static int wh_helper(int value, int def_val, const char *env_name, int *err) { - if (value == 0) { - char *s = getenv(env_name); - if (s) { - value = atoi(s); - /* If LINES/COLUMNS are set, pretend that there is - * no error getting w/h, this prevents some ugly - * cursor tricks by our callers */ - *err = 0; - } + /* Envvars override even if "value" from ioctl is valid (>0). + * Rationale: it's impossible to guess what user wants. + * For example: "man CMD | ...": should "man" format output + * to stdout's width? stdin's width? /dev/tty's width? 80 chars? + * We _cant_ know it. If "..." saves text for e.g. email, + * then it's probably 80 chars. + * If "..." is, say, "grep -v DISCARD | $PAGER", then user + * would prefer his tty's width to be used! + * + * Since we don't know, at least allow user to do this: + * "COLUMNS=80 man CMD | ..." + */ + char *s = getenv(env_name); + if (s) { + value = atoi(s); + /* If LINES/COLUMNS are set, pretend that there is + * no error getting w/h, this prevents some ugly + * cursor tricks by our callers */ + *err = 0; } + if (value <= 1 || value >= 30000) value = def_val; return value; @@ -257,6 +269,20 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh { struct winsize win; int err; + int close_me = -1; + + if (fd == -1) { + if (isatty(STDOUT_FILENO)) + fd = STDOUT_FILENO; + else + if (isatty(STDERR_FILENO)) + fd = STDERR_FILENO; + else + if (isatty(STDIN_FILENO)) + fd = STDIN_FILENO; + else + close_me = fd = open("/dev/tty", O_RDONLY); + } win.ws_row = 0; win.ws_col = 0; @@ -267,8 +293,18 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh *height = wh_helper(win.ws_row, 24, "LINES", &err); if (width) *width = wh_helper(win.ws_col, 80, "COLUMNS", &err); + + if (close_me >= 0) + close(close_me); + return err; } +int FAST_FUNC get_terminal_width(int fd) +{ + unsigned width; + get_terminal_width_height(fd, &width, NULL); + return width; +} int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) { @@ -308,3 +344,15 @@ int FAST_FUNC wait4pid(pid_t pid) return WTERMSIG(status) + 0x180; return 0; } + +// Useful when we do know that pid is valid, and we just want to wait +// for it to exit. Not existing pid is fatal. waitpid() status is not returned. +int FAST_FUNC wait_for_exitstatus(pid_t pid) +{ + int exit_status, n; + + n = safe_waitpid(pid, &exit_status, 0); + if (n < 0) + bb_perror_msg_and_die("waitpid"); + return exit_status; +} |