Skip to content

Instantly share code, notes, and snippets.

@craig65535
Last active January 16, 2016 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craig65535/bf1071592c0f24379c72 to your computer and use it in GitHub Desktop.
Save craig65535/bf1071592c0f24379c72 to your computer and use it in GitHub Desktop.
all: writer
clean:
rm -f writer
writer: writer.c
gcc -Wall -Wextra -W -o writer writer.c
# craig65535@gmail.com
require 'rubygems'
gem 'eventmachine-tail', '=0.6.5'
require 'eventmachine-tail'
if ARGV.length != 2
abort("args")
end
file = File.open(ARGV[1], "w")
EM.run do
EventMachine::file_tail(ARGV[0], nil, 0) do |filetail, line|
file.write(line + "\n")
end
end
#!/usr/bin/perl -w
# craig65535@gmail.com
use warnings;
use strict;
my $DELAY = 0.2;
my $TIMES = 50;
my $INFILE = "/tmp/x";
my $INFILE_BAK = "$INFILE.bak";
my $INFILE_FULL = "$INFILE.full";
my $OUTFILE = "/tmp/y";
my $TEXT = "We're no strangers to love. You know the rules and so do I. A full commitment's what I'm thinking of. You wouldn't get this from any other guy.";
sub log_msg($)
{
my ($msg) = @_;
#print "[tester] $msg";
}
sub spawn
{
my $pid = fork;
die unless defined $pid;
return $pid unless $pid == 0;
exec @_;
die;
}
sub roll()
{
return unless -e $INFILE_BAK;
log_msg("concat $INFILE_BAK >> $INFILE_FULL\n");
system("cat $INFILE_BAK >> $INFILE_FULL");
log_msg("unlink $INFILE_BAK\n");
unlink $INFILE_BAK;
}
unlink $INFILE_FULL;
unlink $INFILE_BAK;
my @cmd = ("./writer", $INFILE, $TEXT);
log_msg("Run ".join(" ", map("'$_'", @cmd))."\n");
my $writer_pid = spawn(@cmd);
log_msg("writer_pid = $writer_pid\n");
@cmd = ("ruby", "reader.rb", $INFILE, $OUTFILE);
log_msg("Run ".join(" ", map("'$_'", @cmd))."\n");
my $reader_pid = spawn(@cmd);
log_msg("reader_pid = $reader_pid\n");
my $ok = 0;
if ($writer_pid =~ /^\d+$/ && $reader_pid =~ /^\d+$/) {
$ok = 1;
}
if ($ok) {
eval {
for (my $i = 0; $i < $TIMES; $i++) {
log_msg("sleep $DELAY\n");
select(undef, undef, undef, $DELAY);
roll();
log_msg("rename $INFILE,$INFILE_BAK\n");
rename $INFILE,$INFILE_BAK or die "rename ($INFILE,$INFILE_BAK): $!";
log_msg("USR1 -> $writer_pid\n");
kill(10, $writer_pid);
}
log_msg("sleep $DELAY\n");
select(undef, undef, undef, $DELAY);
};
if ($@) {
$ok = 0;
print STDERR $@;
}
}
if ($writer_pid =~ /^\d+$/) {
log_msg("TERM writer (pid $writer_pid)\n");
kill(15, $writer_pid);
}
log_msg("sleep 1 so writer finishes\n");
sleep 1;
roll();
log_msg("rename $INFILE,$INFILE_BAK\n");
rename $INFILE,$INFILE_BAK or die "rename ($INFILE,$INFILE_BAK): $!";
roll();
if ($reader_pid =~ /^\d+$/) {
log_msg("TERM reader (pid $reader_pid)\n");
kill(15, $reader_pid);
}
if ($ok) {
print "open $OUTFILE\n";
open FILE, '<', $OUTFILE or die "open $OUTFILE: $!";
print "scanning\n";
my $last_line = 0;
my $num = 0;
while (my $line = <FILE>) {
$num++;
if ($line =~ /^\[(\d+)\] [^\[]+$/) {
my $read_num = $1;
if ($read_num - $last_line > 1) {
print "Lines ".($last_line+1)." through ".($read_num-1)." missing\n";
}
$last_line = $read_num;
} else {
print "Line $num: [$line]\n";
}
}
print "close\n";
close FILE;
}
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
/* craig65535@gmail.com */
volatile sig_atomic_t reopen = 0;
volatile sig_atomic_t term = 0;
void usr1_handler()
{
reopen = 1;
}
void term_handler()
{
term = 1;
}
int main(int argc, char **argv)
{
FILE *f;
char *s;
int len;
int line = 0;
if (argc < 3)
return 1;
s = argv[2];
if (signal(SIGUSR1, usr1_handler)) {
perror("signal");
return 1;
}
if (signal(SIGTERM, term_handler)) {
perror("signal");
return 1;
}
while (!term) {
printf("[writer] fopen\n");
f = fopen(argv[1], "w");
if (!f) {
perror("fopen");
return 1;
}
len = (int)strlen(s) + 1;
while (!term && !reopen) {
line++;
int n = fprintf(f, "[%06d] %s\n", line, s);
if (n < 0) {
printf ("fprintf returned %d (errno=%s)\n", n, strerror(errno));
} else if (n != len + 9) {
printf ("fprintf returned %d\n", n);
}
usleep(1000);
}
if (reopen) {
printf("[writer] got signal. last line was %d\n", line);
reopen = 0;
}
printf("[writer] fclose\n");
if (fclose(f) != 0) {
perror("fclose");
return 1;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment