#!/usr/bin/perl -w
#
# A script for making backups of InnoDB and MyISAM tables, indexes and .frm
# files.
#
# Copyright 2003, 2009 Innobase Oy. All Rights Reserved.
#

use strict;
use Getopt::Long;
use POSIX "strftime";
use POSIX ":sys_wait_h";
use POSIX "tmpnam";
use FileHandle;
use File::Basename;

    $ENV{PATH}= dirname($ENV{EXE_MYSQL}).(":").$ENV{PATH};
    my $mysql_stdout='mysql-stdout';
    my $mysql_stderr='mysql-stderr';
    my $mysql_port= $ARGV[0];
    my $hello_id = 0;
    my $options = "--unbuffered --host=127.0.0.1 --user=tom --port=$mysql_port";
    my $mysql_pid= 0;

    $SIG{PIPE} = \&catch_sigpipe;

sub Die {
    my $message = shift;
    my $extra_info = '';

    # kill all child processes of this process
    kill_child_processes();

    die "innobackup Error: $message$extra_info";
}

sub catch_sigpipe {
    my $rcode;

    if ($mysql_pid && (-1 == ($rcode = waitpid($mysql_pid, &WNOHANG))
                       || $rcode == $mysql_pid)) {
        my $reason = `cat $mysql_stderr`;
        print "Pipe to mysql child process broken: $reason at";
        system("date +'%H:%M:%S'");
        exit(1);
    } else {
        Die "Broken pipe";
    }
}


$SIG{PIPE} = \&catch_sigpipe;

sub kill_child_processes {
    if ($mysql_pid) {
        kill(15, $mysql_pid);
        $mysql_pid = '';
 }
}

sub current_time {
    return strftime("%y%m%d %H:%M:%S", localtime());
}


    # run mysql as a child process with a pipe connection
    my $now = current_time();
    print "$now  innobackup Starting mysql with options: $options\n";
    $mysql_pid = open(*MYSQL_WRITER, "| mysql $options >$mysql_stdout 2>$mysql_stderr ") or Die "Failed to spawn mysql child process: $!";
    MYSQL_WRITER->autoflush(1);
    $now = current_time();
    print "$now innobackup Connected to database with mysql child process (pid=$mysql_pid)\n";

    my $hello_message = "innobackup hello $hello_id";
    print MYSQL_WRITER "select '$hello_message';\n"
        or Die "Connection to mysql child process failed: $!";

# mysql check code comes now

    # wait for reply
    eval {
        local $SIG{ALRM} = sub {
            kill_child_processes();
            die "alarm clock restart"
        };
        my $stdout = '';
        my $stderr = '';
        alarm 900;
        while (index($stdout, $hello_message) < 0) {
            sleep 2;
            if ($mysql_pid && $mysql_pid == waitpid($mysql_pid, &WNOHANG)) {
                my $reason = `cat $mysql_stderr`;
                $mysql_pid = '';
                kill_child_processes();
                die "satya: mysql child process has died: $reason";
            }
            $stdout = `cat $mysql_stdout`;
            $stderr = `cat $mysql_stderr`;
            if ($stderr) {
                # mysql has reported an error, do exit
                kill_child_processes();
                die "mysql error: $stderr";
            }
        }
        alarm 0;
    };
    if ($@ =~ /alarm clock restart/) {
        Die "Connection to mysql child process (pid=$mysql_pid) timedout."
            . " (Time limit of 900 seconds exceeded."
            . " You may adjust time limit by editing the value of parameter"
            . " \"\$mysql_response_timeout\" in this script.)";
    } elsif ($@) { Die $@; }


