resize.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * resize - set terminal width and height.
  4. *
  5. * Copyright 2006 Bernhard Reutner-Fischer
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  8. */
  9. /* no options, no getopt */
  10. #include "libbb.h"
  11. #define ESC "\033"
  12. #define old_termios (*(struct termios*)&bb_common_bufsiz1)
  13. static void
  14. onintr(int sig UNUSED_PARAM)
  15. {
  16. tcsetattr(STDERR_FILENO, TCSANOW, &old_termios);
  17. exit(EXIT_FAILURE);
  18. }
  19. int resize_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  20. int resize_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  21. {
  22. struct termios new;
  23. struct winsize w = { 0, 0, 0, 0 };
  24. int ret;
  25. /* We use _stderr_ in order to make resize usable
  26. * in shell backticks (those redirect stdout away from tty).
  27. * NB: other versions of resize open "/dev/tty"
  28. * and operate on it - should we do the same?
  29. */
  30. tcgetattr(STDERR_FILENO, &old_termios); /* fiddle echo */
  31. new = old_termios;
  32. new.c_cflag |= (CLOCAL | CREAD);
  33. new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  34. bb_signals(0
  35. + (1 << SIGINT)
  36. + (1 << SIGQUIT)
  37. + (1 << SIGTERM)
  38. + (1 << SIGALRM)
  39. , onintr);
  40. tcsetattr(STDERR_FILENO, TCSANOW, &new);
  41. /* save_cursor_pos 7
  42. * scroll_whole_screen [r
  43. * put_cursor_waaaay_off [$x;$yH
  44. * get_cursor_pos [6n
  45. * restore_cursor_pos 8
  46. */
  47. fprintf(stderr, ESC"7" ESC"[r" ESC"[999;999H" ESC"[6n");
  48. alarm(3); /* Just in case terminal won't answer */
  49. scanf(ESC"[%hu;%huR", &w.ws_row, &w.ws_col);
  50. fprintf(stderr, ESC"8");
  51. /* BTW, other versions of resize recalculate w.ws_xpixel, ws.ws_ypixel
  52. * by calculating character cell HxW from old values
  53. * (gotten via TIOCGWINSZ) and recomputing *pixel values */
  54. ret = ioctl(STDERR_FILENO, TIOCSWINSZ, &w);
  55. tcsetattr(STDERR_FILENO, TCSANOW, &old_termios);
  56. if (ENABLE_FEATURE_RESIZE_PRINT)
  57. printf("COLUMNS=%d;LINES=%d;export COLUMNS LINES;\n",
  58. w.ws_col, w.ws_row);
  59. return ret;
  60. }