aboutsummaryrefslogtreecommitdiff
path: root/more.c
diff options
context:
space:
mode:
Diffstat (limited to 'more.c')
-rw-r--r--more.c100
1 files changed, 49 insertions, 51 deletions
diff --git a/more.c b/more.c
index 9f07633c3..6cdec729b 100644
--- a/more.c
+++ b/more.c
@@ -9,6 +9,8 @@
9 * based on the original more implementation by Bruce, and code from the 9 * based on the original more implementation by Bruce, and code from the
10 * Debian boot-floppies team. 10 * Debian boot-floppies team.
11 * 11 *
12 * Termios corrects by Vladimir Oleynik <vodz@usa.net>
13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or 16 * the Free Software Foundation; either version 2 of the License, or
@@ -29,29 +31,26 @@
29#include <fcntl.h> 31#include <fcntl.h>
30#include <signal.h> 32#include <signal.h>
31#include <stdlib.h> 33#include <stdlib.h>
34#include <unistd.h>
32#include <sys/ioctl.h> 35#include <sys/ioctl.h>
33#include "busybox.h" 36#include "busybox.h"
34 37
35/* ED: sparc termios is broken: revert back to old termio handling. */
36#ifdef BB_FEATURE_USE_TERMIOS
37# if #cpu(sparc)
38# include <termio.h>
39# define termios termio
40# define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp)
41# define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp)
42# else
43# include <termios.h>
44# define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp)
45# define getTermSettings(fd,argp) tcgetattr(fd, argp);
46# endif
47
48static FILE *cin; 38static FILE *cin;
49 39
40#ifdef BB_FEATURE_USE_TERMIOS
41#include <termios.h>
42#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp)
43#define getTermSettings(fd,argp) tcgetattr(fd, argp);
44
50static struct termios initial_settings, new_settings; 45static struct termios initial_settings, new_settings;
51 46
52static void gotsig(int sig) 47static void set_tty_to_initial_mode(void)
53{ 48{
54 setTermSettings(fileno(cin), &initial_settings); 49 setTermSettings(fileno(cin), &initial_settings);
50}
51
52static void gotsig(int sig)
53{
55 putchar('\n'); 54 putchar('\n');
56 exit(EXIT_FAILURE); 55 exit(EXIT_FAILURE);
57} 56}
@@ -65,7 +64,7 @@ static int terminal_height = 24;
65extern int more_main(int argc, char **argv) 64extern int more_main(int argc, char **argv)
66{ 65{
67 int c, lines, input = 0; 66 int c, lines, input = 0;
68 int please_display_more_prompt; 67 int please_display_more_prompt = -1;
69 struct stat st; 68 struct stat st;
70 FILE *file; 69 FILE *file;
71 int len, page_height; 70 int len, page_height;
@@ -77,46 +76,57 @@ extern int more_main(int argc, char **argv)
77 argc--; 76 argc--;
78 argv++; 77 argv++;
79 78
80 do {
81 if (argc == 0) {
82 file = stdin;
83 } else
84 file = xfopen(*argv, "r");
85 79
86 fstat(fileno(file), &st); 80 /* not use inputing from terminal if usage: more > outfile */
87 81 if(isatty(fileno(stdout))) {
88#ifdef BB_FEATURE_USE_TERMIOS
89 cin = fopen("/dev/tty", "r"); 82 cin = fopen("/dev/tty", "r");
90 if (!cin) 83 if (!cin)
91 cin = xfopen("/dev/console", "r"); 84 cin = xfopen("/dev/console", "r");
85 please_display_more_prompt = 0;
86#ifdef BB_FEATURE_USE_TERMIOS
92 getTermSettings(fileno(cin), &initial_settings); 87 getTermSettings(fileno(cin), &initial_settings);
93 new_settings = initial_settings; 88 new_settings = initial_settings;
94 new_settings.c_cc[VMIN] = 1;
95 new_settings.c_cc[VTIME] = 0;
96 new_settings.c_lflag &= ~ICANON; 89 new_settings.c_lflag &= ~ICANON;
97 new_settings.c_lflag &= ~ECHO; 90 new_settings.c_lflag &= ~ECHO;
91#ifndef linux
92 /* Hmm, in linux c_cc[] not parsed if set ~ICANON */
93 new_settings.c_cc[VMIN] = 1;
94 new_settings.c_cc[VTIME] = 0;
95#endif
98 setTermSettings(fileno(cin), &new_settings); 96 setTermSettings(fileno(cin), &new_settings);
97 atexit(set_tty_to_initial_mode);
98 (void) signal(SIGINT, gotsig);
99 (void) signal(SIGQUIT, gotsig);
100 (void) signal(SIGTERM, gotsig);
101#endif
102 }
103
104 do {
105 if (argc == 0) {
106 file = stdin;
107 } else
108 file = wfopen(*argv, "r");
109 if(file==0)
110 goto loop;
111
112 fstat(fileno(file), &st);
99 113
100# ifdef BB_FEATURE_AUTOWIDTH 114 if(please_display_more_prompt>0)
115 please_display_more_prompt = 0;
116
117#if defined BB_FEATURE_AUTOWIDTH && defined BB_FEATURE_USE_TERMIOS
101 ioctl(fileno(stdout), TIOCGWINSZ, &win); 118 ioctl(fileno(stdout), TIOCGWINSZ, &win);
102 if (win.ws_row > 4) 119 if (win.ws_row > 4)
103 terminal_height = win.ws_row - 2; 120 terminal_height = win.ws_row - 2;
104 if (win.ws_col > 0) 121 if (win.ws_col > 0)
105 terminal_width = win.ws_col - 1; 122 terminal_width = win.ws_col - 1;
106# endif
107
108 (void) signal(SIGINT, gotsig);
109 (void) signal(SIGQUIT, gotsig);
110 (void) signal(SIGTERM, gotsig);
111
112#endif 123#endif
113 len=0; 124 len=0;
114 lines = 0; 125 lines = 0;
115 page_height = terminal_height; 126 page_height = terminal_height;
116 please_display_more_prompt = 0;
117 while ((c = getc(file)) != EOF) { 127 while ((c = getc(file)) != EOF) {
118 128
119 if (please_display_more_prompt) { 129 if (please_display_more_prompt>0) {
120 len = printf("--More-- "); 130 len = printf("--More-- ");
121 if (file != stdin) { 131 if (file != stdin) {
122#if _FILE_OFFSET_BITS == 64 132#if _FILE_OFFSET_BITS == 64
@@ -129,13 +139,6 @@ extern int more_main(int argc, char **argv)
129 (double) st.st_size)), (long)st.st_size); 139 (double) st.st_size)), (long)st.st_size);
130#endif 140#endif
131 } 141 }
132 len += printf("%s",
133#ifdef BB_FEATURE_USE_TERMIOS
134 ""
135#else
136 "\n"
137#endif
138 );
139 142
140 fflush(stdout); 143 fflush(stdout);
141 144
@@ -143,20 +146,16 @@ extern int more_main(int argc, char **argv)
143 * We've just displayed the "--More--" prompt, so now we need 146 * We've just displayed the "--More--" prompt, so now we need
144 * to get input from the user. 147 * to get input from the user.
145 */ 148 */
146#ifdef BB_FEATURE_USE_TERMIOS
147 input = getc(cin); 149 input = getc(cin);
148#else 150#ifndef BB_FEATURE_USE_TERMIOS
149 input = getc(stdin); 151 printf("\033[A"); /* up cursor */
150#endif 152#endif
151
152#ifdef BB_FEATURE_USE_TERMIOS
153 /* Erase the "More" message */ 153 /* Erase the "More" message */
154 putc('\r', stdout); 154 putc('\r', stdout);
155 while (--len >= 0) 155 while (--len >= 0)
156 putc(' ', stdout); 156 putc(' ', stdout);
157 putc('\r', stdout); 157 putc('\r', stdout);
158 fflush(stdout); 158 fflush(stdout);
159#endif
160 len=0; 159 len=0;
161 lines = 0; 160 lines = 0;
162 page_height = terminal_height; 161 page_height = terminal_height;
@@ -180,6 +179,7 @@ extern int more_main(int argc, char **argv)
180 /* increment by just one line if we are at 179 /* increment by just one line if we are at
181 * the end of this line */ 180 * the end of this line */
182 if (input == '\n') 181 if (input == '\n')
182 if(please_display_more_prompt==0)
183 please_display_more_prompt = 1; 183 please_display_more_prompt = 1;
184 /* Adjust the terminal height for any overlap, so that 184 /* Adjust the terminal height for any overlap, so that
185 * no lines get lost off the top. */ 185 * no lines get lost off the top. */
@@ -195,6 +195,7 @@ extern int more_main(int argc, char **argv)
195 } 195 }
196 } 196 }
197 if (++lines >= page_height) { 197 if (++lines >= page_height) {
198 if(please_display_more_prompt==0)
198 please_display_more_prompt = 1; 199 please_display_more_prompt = 1;
199 } 200 }
200 len=0; 201 len=0;
@@ -208,12 +209,9 @@ extern int more_main(int argc, char **argv)
208 } 209 }
209 fclose(file); 210 fclose(file);
210 fflush(stdout); 211 fflush(stdout);
211 212loop:
212 argv++; 213 argv++;
213 } while (--argc > 0); 214 } while (--argc > 0);
214 end: 215 end:
215#ifdef BB_FEATURE_USE_TERMIOS
216 setTermSettings(fileno(cin), &initial_settings);
217#endif
218 return 0; 216 return 0;
219} 217}