tls: in AES-GCM decoding, avoid memmove
[oweals/busybox.git] / util-linux / script.c
index c5063e8a17af03b81e00d7b4b1da99861566b459..aac77c3ba78dcba9740bcc31fb0de9402cd5e20a 100644 (file)
  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
 //config:config SCRIPT
-//config:      bool "script"
+//config:      bool "script (8 kb)"
 //config:      default y
 //config:      help
-//config:        The script makes typescript of terminal session.
+//config:      The script makes typescript of terminal session.
 
 //applet:IF_SCRIPT(APPLET(script, BB_DIR_USR_BIN, BB_SUID_DROP))
 
 //kbuild:lib-$(CONFIG_SCRIPT) += script.o
 
 //usage:#define script_trivial_usage
-//usage:       "[-afq" IF_SCRIPTREPLAY("t") "] [-c PROG] [OUTFILE]"
+//usage:       "[-afq] [-t[FILE]] [-c PROG] [OUTFILE]"
 //usage:#define script_full_usage "\n\n"
-//usage:       "       -a      Append output"
+//usage:       "Default OUTFILE is 'typescript'"
+//usage:     "\n"
+//usage:     "\n       -a      Append output"
 //usage:     "\n       -c PROG Run PROG, not shell"
-//usage:     "\n       -f      Flush output after each write"
+/* Accepted but has no effect (we never buffer output) */
+/*//usage:     "\n     -f      Flush output after each write"*/
 //usage:     "\n       -q      Quiet"
-//usage:       IF_SCRIPTREPLAY(
-//usage:     "\n       -t      Send timing to stderr"
-//usage:       )
+//usage:     "\n       -t[FILE] Send timing to stderr or FILE"
+
+//util-linux-2.28:
+//-e: return exit code of the child
+
+//FYI (reported as bbox bug #2749):
+// > script -q -c 'echo -e -n "1\n2\n3\n"' /dev/null </dev/null >123.txt
+// > The output file on full-blown ubuntu system contains 6 bytes.
+// > Output on Busybox system (arm-linux) contains extra '\r' byte in each line.
+//however, in my test, "script" from util-linux-2.28 seems to also add '\r' bytes.
 
 #include "libbb.h"
 #include "common_bufsiz.h"
@@ -46,6 +56,8 @@ int script_main(int argc UNUSED_PARAM, char **argv)
        char pty_line[GETPTY_BUFSIZE];
        struct termios tt, rtt;
        struct winsize win;
+       FILE *timing_fp;
+       const char *str_t = NULL;
        const char *fname = "typescript";
        const char *shell;
        char shell_opt[] = "-i";
@@ -59,19 +71,19 @@ int script_main(int argc UNUSED_PARAM, char **argv)
        };
 
 #if ENABLE_LONG_OPTS
-       static const char getopt_longopts[] ALIGN1 =
+       static const char script_longopts[] ALIGN1 =
                "append\0"  No_argument       "a"
                "command\0" Required_argument "c"
                "flush\0"   No_argument       "f"
                "quiet\0"   No_argument       "q"
-               IF_SCRIPTREPLAY("timing\0" No_argument "t")
+               "timing\0"  Optional_argument "t"
                ;
-
-       applet_long_options = getopt_longopts;
 #endif
 
-       opt_complementary = "?1"; /* max one arg */
-       opt = getopt32(argv, "ac:fq" IF_SCRIPTREPLAY("t") , &shell_arg);
+       opt = getopt32long(argv, "^" "ac:fqt::" "\0" "?1"/* max one arg */,
+                               script_longopts,
+                               &shell_arg, &str_t
+       );
        //argc -= optind;
        argv += optind;
        if (argv[0]) {
@@ -87,6 +99,10 @@ int script_main(int argc UNUSED_PARAM, char **argv)
        if (!(opt & OPT_q)) {
                printf("Script started, file is %s\n", fname);
        }
+       timing_fp = stderr;
+       if (str_t) {
+               timing_fp = xfopen_for_write(str_t);
+       }
 
        shell = get_shell_name();
 
@@ -120,8 +136,9 @@ int script_main(int argc UNUSED_PARAM, char **argv)
                /* parent */
                struct pollfd pfd[2];
                int outfd, count, loop;
-               double oldtime = ENABLE_SCRIPTREPLAY ? time(NULL) : 0;
+               double oldtime = time(NULL);
                smallint fd_count = 2;
+
 #define buf bb_common_bufsiz1
                setup_common_bufsiz();
 
@@ -151,20 +168,21 @@ int script_main(int argc UNUSED_PARAM, char **argv)
                                        goto restore;
                                }
                                if (count > 0) {
-                                       if (ENABLE_SCRIPTREPLAY && (opt & OPT_t)) {
+                                       if (opt & OPT_t) {
                                                struct timeval tv;
                                                double newtime;
 
                                                gettimeofday(&tv, NULL);
                                                newtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
-                                               fprintf(stderr, "%f %u\n", newtime - oldtime, count);
+                                               fprintf(timing_fp, "%f %u\n", newtime - oldtime, count);
                                                oldtime = newtime;
                                        }
                                        full_write(STDOUT_FILENO, buf, count);
                                        full_write(outfd, buf, count);
-                                       if (opt & OPT_f) {
-                                               fsync(outfd);
-                                       }
+                                       // If we'd be using (buffered) FILE i/o, we'd need this:
+                                       //if (opt & OPT_f) {
+                                       //      fflush(outfd);
+                                       //}
                                }
                        }
                        if (pfd[1].revents) {