resize.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * resize - set terminal width and height.
  4. *
  5. * Copyright 2006 Bernhard 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 ATTRIBUTE_UNUSED)
  15. {
  16. tcsetattr(STDERR_FILENO, TCSANOW, &old_termios);
  17. exit(1);
  18. }
  19. int resize_main(int argc, char **argv);
  20. int resize_main(int argc, char **argv)
  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. signal(SIGINT, onintr);
  35. signal(SIGQUIT, onintr);
  36. signal(SIGTERM, onintr);
  37. signal(SIGALRM, onintr);
  38. tcsetattr(STDERR_FILENO, TCSANOW, &new);
  39. /* save_cursor_pos 7
  40. * scroll_whole_screen [r
  41. * put_cursor_waaaay_off [$x;$yH
  42. * get_cursor_pos [6n
  43. * restore_cursor_pos 8
  44. */
  45. fprintf(stderr, ESC"7" ESC"[r" ESC"[999;999H" ESC"[6n");
  46. alarm(3); /* Just in case terminal won't answer */
  47. scanf(ESC"[%hu;%huR", &w.ws_row, &w.ws_col);
  48. fprintf(stderr, ESC"8");
  49. /* BTW, other versions of resize recalculate w.ws_xpixel, ws.ws_ypixel
  50. * by calculating character cell HxW from old values
  51. * (gotten via TIOCGWINSZ) and recomputing *pixel values */
  52. ret = ioctl(STDERR_FILENO, TIOCSWINSZ, &w);
  53. tcsetattr(STDERR_FILENO, TCSANOW, &old_termios);
  54. if (ENABLE_FEATURE_RESIZE_PRINT)
  55. printf("COLUMNS=%d;LINES=%d;export COLUMNS LINES;\n",
  56. w.ws_col, w.ws_row);
  57. return ret;
  58. }