Hi folks, review the patch below, please. Karel >From ef40b89a3123ed1f89b9d39cb89986ef801a2e78 Mon Sep 17 00:00:00 2001 From: Karel Zak <kzak@xxxxxxxxxx> Date: Wed, 2 Apr 2008 11:34:12 +0200 Subject: [PATCH] scriptreplay: rewrite in C The dependence on Perl sucks in basic system package. Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> --- configure.ac | 1 - misc-utils/Makefile.am | 6 +- misc-utils/scriptreplay.c | 110 ++++++++++++++++++++++++++++++++++++++++++++ misc-utils/scriptreplay.pl | 83 --------------------------------- 4 files changed, 113 insertions(+), 87 deletions(-) create mode 100644 misc-utils/scriptreplay.c delete mode 100755 misc-utils/scriptreplay.pl diff --git a/configure.ac b/configure.ac index 435f768..75a112c 100644 --- a/configure.ac +++ b/configure.ac @@ -693,7 +693,6 @@ tests/Makefile tests/helpers/Makefile tests/commands.sh misc-utils/chkdupexe:misc-utils/chkdupexe.pl -misc-utils/scriptreplay:misc-utils/scriptreplay.pl ]) AC_OUTPUT diff --git a/misc-utils/Makefile.am b/misc-utils/Makefile.am index 5441b01..40610c1 100644 --- a/misc-utils/Makefile.am +++ b/misc-utils/Makefile.am @@ -5,14 +5,14 @@ EXTRA_DIST = README.flushb bin_PROGRAMS = usrbinexec_PROGRAMS = cal ddate logger look mcookie \ - namei script whereis + namei script whereis scriptreplay EXTRA_DIST += README.cal README.ddate README.namei README.namei2 mcookie_SOURCES = mcookie.c ../lib/md5.c -usrbinexec_SCRIPTS = chkdupexe scriptreplay +usrbinexec_SCRIPTS = chkdupexe -CLEANFILES = chkdupexe scriptreplay +CLEANFILES = chkdupexe dist_man_MANS = cal.1 chkdupexe.1 ddate.1 logger.1 look.1 mcookie.1 \ namei.1 script.1 whereis.1 scriptreplay.1 diff --git a/misc-utils/scriptreplay.c b/misc-utils/scriptreplay.c new file mode 100644 index 0000000..9e049e6 --- /dev/null +++ b/misc-utils/scriptreplay.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2008, Karel Zak <kzak@xxxxxxxxxx> + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <err.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +const char *progname; +#define SCRIPT_MIN_DELAY 0.0001 + +void __attribute__((__noreturn__)) +usage(int rc) +{ + printf("%s <timingfile> [<typescript> [<divisor>]]\n", progname); + exit(rc); +} + +int +main(int argc, char *argv[]) +{ + FILE *tfd, *sfd; + const char *sname = "typescript", *tname; + char buf[BUFSIZ]; + double divi = 0; + size_t rblk; + + progname = program_invocation_short_name; + + if (argc < 2) + usage(EXIT_FAILURE); + tname = argv[1]; + tfd = fopen(tname, "r"); + if (!tfd) + err(EXIT_FAILURE, "cannot open file %s", tname); + + if (argc >= 3) + sname = argv[2]; + sfd = fopen(sname, "r"); + if (!sfd) + err(EXIT_FAILURE, "cannot open file %s", sname); + if (argc == 4) { + char *end; + divi = strtod(argv[3], &end); + if (end == NULL || *end != '\0') + usage(EXIT_FAILURE); + } + else if (argc > 4) + usage(EXIT_FAILURE); + + /* ignore the first line */ + if (!fgets(buf, sizeof(buf), sfd)) + goto done; + + do { + double delay; + size_t blk; + + if (fscanf(tfd, "%lf %zd\n", &delay, &blk) != 2) + break; + if (divi) + delay /= divi; + + if (delay > SCRIPT_MIN_DELAY) { + struct timeval tv; + tv.tv_sec = (long) delay; + tv.tv_usec = (delay - tv.tv_sec) * 1000000; + + select(0, NULL, NULL, NULL, &tv); + } + + rblk = blk; + while(rblk) { + size_t len, cc; + + cc = rblk > sizeof(buf) ? sizeof(buf) : rblk; + len = fread(buf, 1, cc, sfd); + + if (len <= 0) + break; + rblk -= len; + cc = write(1, buf, len); + if (cc != len) + err(EXIT_FAILURE, "write output failed"); + } + } while(rblk == 0); + +done: + if (ferror(sfd)) + err(EXIT_FAILURE, "cannot read typescript file %s", sname); + if (ferror(tfd)) + err(EXIT_FAILURE, "cannot read timing file %s", tname); + + exit(EXIT_SUCCESS); +} diff --git a/misc-utils/scriptreplay.pl b/misc-utils/scriptreplay.pl deleted file mode 100755 index b445f6d..0000000 --- a/misc-utils/scriptreplay.pl +++ /dev/null @@ -1,83 +0,0 @@ -#!@PERL@ -w - -# "script -t" will output a typescript with timings -# this script "scriptreplay" replays it -# run pod2man on it to get a man page - -=head1 NAME - -scriptreplay - play back typescripts, using timing information - -=head1 SYNOPSIS - -scriptreplay timingfile [typescript [divisor]] - -=head1 DESCRIPTION - -This program replays a typescript, using timing information to ensure that -output happens at the same speed as it originally appeared when the script -was recorded. It is only guaranteed to work properly if run on the same -terminal the script was recorded on. - -The timings information is what script outputs to standard error if it is -run with the -t parameter. - -By default, the typescript to display is assumed to be named "typescript", -but other filenames may be specified, as the second parameter. - -If the third parameter exits, it is used as a time divisor. For example, -specifying a divisor of 2 makes the script be replayed twice as fast. - -=head1 EXAMPLE - - % script -t 2> timingfile - Script started, file is typescript - % ls - <etc, etc> - % exit - Script done, file is typescript - % scriptreplay timingfile - -=cut - -use strict; -$|=1; -open (TIMING, shift) - or die "cannot read timing info: $!"; -open (TYPESCRIPT, shift || 'typescript') - or die "cannot read typescript: $!"; -my $divisor=shift || 1; - -# Read starting timestamp line and ignore. -<TYPESCRIPT>; - -my $block; -my $oldblock=''; -while (<TIMING>) { - my ($delay, $blocksize)=split ' ', $_, 2; - # Sleep, unless the delay is really tiny. Really tiny delays cannot - # be accurately done, because the system calls in this loop will - # have more overhead. The 0.0001 is arbitrary, but works fairly well. - if ($delay / $divisor > 0.0001) { - select(undef, undef, undef, $delay / $divisor - 0.0001); - } - - read(TYPESCRIPT, $block, $blocksize) - or die "read failure on typescript: $!"; - print $oldblock; - $oldblock=$block; -} -print $oldblock; - -=head1 SEE ALSO - -script(1) - -=head1 COPYRIGHT - -This program is in the public domain. - -=head1 AUTHOR - -Joey Hess <joey@xxxxxxxxxxx> - -- 1.5.3.8 -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html