aboutsummaryrefslogtreecommitdiff
path: root/util-linux/script.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux/script.c')
-rw-r--r--util-linux/script.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/util-linux/script.c b/util-linux/script.c
index 9eebb51a4..aac77c3ba 100644
--- a/util-linux/script.c
+++ b/util-linux/script.c
@@ -21,15 +21,25 @@
21//kbuild:lib-$(CONFIG_SCRIPT) += script.o 21//kbuild:lib-$(CONFIG_SCRIPT) += script.o
22 22
23//usage:#define script_trivial_usage 23//usage:#define script_trivial_usage
24//usage: "[-afq" IF_SCRIPTREPLAY("t") "] [-c PROG] [OUTFILE]" 24//usage: "[-afq] [-t[FILE]] [-c PROG] [OUTFILE]"
25//usage:#define script_full_usage "\n\n" 25//usage:#define script_full_usage "\n\n"
26//usage: " -a Append output" 26//usage: "Default OUTFILE is 'typescript'"
27//usage: "\n"
28//usage: "\n -a Append output"
27//usage: "\n -c PROG Run PROG, not shell" 29//usage: "\n -c PROG Run PROG, not shell"
28//usage: "\n -f Flush output after each write" 30/* Accepted but has no effect (we never buffer output) */
31/*//usage: "\n -f Flush output after each write"*/
29//usage: "\n -q Quiet" 32//usage: "\n -q Quiet"
30//usage: IF_SCRIPTREPLAY( 33//usage: "\n -t[FILE] Send timing to stderr or FILE"
31//usage: "\n -t Send timing to stderr" 34
32//usage: ) 35//util-linux-2.28:
36//-e: return exit code of the child
37
38//FYI (reported as bbox bug #2749):
39// > script -q -c 'echo -e -n "1\n2\n3\n"' /dev/null </dev/null >123.txt
40// > The output file on full-blown ubuntu system contains 6 bytes.
41// > Output on Busybox system (arm-linux) contains extra '\r' byte in each line.
42//however, in my test, "script" from util-linux-2.28 seems to also add '\r' bytes.
33 43
34#include "libbb.h" 44#include "libbb.h"
35#include "common_bufsiz.h" 45#include "common_bufsiz.h"
@@ -46,6 +56,8 @@ int script_main(int argc UNUSED_PARAM, char **argv)
46 char pty_line[GETPTY_BUFSIZE]; 56 char pty_line[GETPTY_BUFSIZE];
47 struct termios tt, rtt; 57 struct termios tt, rtt;
48 struct winsize win; 58 struct winsize win;
59 FILE *timing_fp;
60 const char *str_t = NULL;
49 const char *fname = "typescript"; 61 const char *fname = "typescript";
50 const char *shell; 62 const char *shell;
51 char shell_opt[] = "-i"; 63 char shell_opt[] = "-i";
@@ -59,19 +71,19 @@ int script_main(int argc UNUSED_PARAM, char **argv)
59 }; 71 };
60 72
61#if ENABLE_LONG_OPTS 73#if ENABLE_LONG_OPTS
62 static const char getopt_longopts[] ALIGN1 = 74 static const char script_longopts[] ALIGN1 =
63 "append\0" No_argument "a" 75 "append\0" No_argument "a"
64 "command\0" Required_argument "c" 76 "command\0" Required_argument "c"
65 "flush\0" No_argument "f" 77 "flush\0" No_argument "f"
66 "quiet\0" No_argument "q" 78 "quiet\0" No_argument "q"
67 IF_SCRIPTREPLAY("timing\0" No_argument "t") 79 "timing\0" Optional_argument "t"
68 ; 80 ;
69
70 applet_long_options = getopt_longopts;
71#endif 81#endif
72 82
73 opt_complementary = "?1"; /* max one arg */ 83 opt = getopt32long(argv, "^" "ac:fqt::" "\0" "?1"/* max one arg */,
74 opt = getopt32(argv, "ac:fq" IF_SCRIPTREPLAY("t") , &shell_arg); 84 script_longopts,
85 &shell_arg, &str_t
86 );
75 //argc -= optind; 87 //argc -= optind;
76 argv += optind; 88 argv += optind;
77 if (argv[0]) { 89 if (argv[0]) {
@@ -87,6 +99,10 @@ int script_main(int argc UNUSED_PARAM, char **argv)
87 if (!(opt & OPT_q)) { 99 if (!(opt & OPT_q)) {
88 printf("Script started, file is %s\n", fname); 100 printf("Script started, file is %s\n", fname);
89 } 101 }
102 timing_fp = stderr;
103 if (str_t) {
104 timing_fp = xfopen_for_write(str_t);
105 }
90 106
91 shell = get_shell_name(); 107 shell = get_shell_name();
92 108
@@ -120,8 +136,9 @@ int script_main(int argc UNUSED_PARAM, char **argv)
120 /* parent */ 136 /* parent */
121 struct pollfd pfd[2]; 137 struct pollfd pfd[2];
122 int outfd, count, loop; 138 int outfd, count, loop;
123 double oldtime = ENABLE_SCRIPTREPLAY ? time(NULL) : 0; 139 double oldtime = time(NULL);
124 smallint fd_count = 2; 140 smallint fd_count = 2;
141
125#define buf bb_common_bufsiz1 142#define buf bb_common_bufsiz1
126 setup_common_bufsiz(); 143 setup_common_bufsiz();
127 144
@@ -151,20 +168,21 @@ int script_main(int argc UNUSED_PARAM, char **argv)
151 goto restore; 168 goto restore;
152 } 169 }
153 if (count > 0) { 170 if (count > 0) {
154 if (ENABLE_SCRIPTREPLAY && (opt & OPT_t)) { 171 if (opt & OPT_t) {
155 struct timeval tv; 172 struct timeval tv;
156 double newtime; 173 double newtime;
157 174
158 gettimeofday(&tv, NULL); 175 gettimeofday(&tv, NULL);
159 newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; 176 newtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
160 fprintf(stderr, "%f %u\n", newtime - oldtime, count); 177 fprintf(timing_fp, "%f %u\n", newtime - oldtime, count);
161 oldtime = newtime; 178 oldtime = newtime;
162 } 179 }
163 full_write(STDOUT_FILENO, buf, count); 180 full_write(STDOUT_FILENO, buf, count);
164 full_write(outfd, buf, count); 181 full_write(outfd, buf, count);
165 if (opt & OPT_f) { 182 // If we'd be using (buffered) FILE i/o, we'd need this:
166 fsync(outfd); 183 //if (opt & OPT_f) {
167 } 184 // fflush(outfd);
185 //}
168 } 186 }
169 } 187 }
170 if (pfd[1].revents) { 188 if (pfd[1].revents) {