Fork() on Windows.

I was assigned a very simple task – write a script that opens SSH connection to a remote server, waits 30 seconds and closes the connection. About 5 minutes of work on Linux.

On windows it took an entire day.

First attempt: Using MKS32’s KSH.

d:/sitescope/tools/plink sitescope@testdb -pw pass -m d:/sshTest_cmd2;
SSH_PID=$!
echo $SSH_PID
(sleep 30 ; kill $SSH_PID);

Problem: The ssh process executed within a subshell, and I only got the PID for the subshell. Killing the subshell did not kill the SSH process.

Second attempt: Using Perl’s fork, exec and wait.

$pid = fork;
if($pid == 0) {
    exec("d:/sitescope/tools/plink sitescope@testdb -pw pass -m d:/sshTest_cmd2");
}elsif ($pid > 0) {
    sleep 30;
    kill(9,$pid);
} else {
    print "fork failed";
};

Problem: Under windows, fork is not a real fork. It creates a “pseudo process” (AKA thread), and $PID is a negative number. Not a real process ID. After the “exec”, the child thread will become a real process with PID, but again, I’ll not have the PID.

Third attempt: Perl has a WIN32 package, which includes a process object, allowing me to create a process, wait for it, and kill it.

use Win32;
use Win32::Process;
use Win32::Process (STILL_ACTIVE);

sub ErrorReport{
    print Win32::FormatMessage( Win32::GetLastError() );
}

$params = "plink sitescope\@$ARGV[0] -pw $ARGV[1] -m D:\\sshTest_cmd";
print "$params \n";

Win32::Process::Create($ProcessObj,"D:\\SiteScope\\tools\\plink.exe",$params,0,
NORMAL_PRIORITY_CLASS,".")|| die ErrorReport();

$PID = $ProcessObj->GetProcessID();
print "$PID \n";

$ProcessObj->Wait(30000);
$ProcessObj->GetExitCode($exitcode);

print "exit code is: $exitcode \n";

if ($exitcode == 0)
{
    print "exiting normally \n";
exit 0;
} elsif ($exitcode == STILL_ACTIVE)
{
    print "killing ssh \n";
    $ProcessObj->Kill(59);
    exit 59;
} else
{
    print "ssh exited abnormally \n";
    exit $exitcode;
}

Finally something works 🙂

Advertisements

8 Comments on “Fork() on Windows.”

  1. does not have perl some SSH module? are you sticked to putty?

    not sure what you want to do however

    what about this :

    C:\> ssh.exe -o BatchMode=yes server1 sleep 30
    C:\> echo %errorlevel%
    0
    C:\> ssh.exe -o BatchMode=yes server2 sleep 30
    Permission denied (publickey,password,keyboard-interactive).
    C:\> echo %errorlevel%
    255

    HTH
    Laurent

    • prodlife says:

      In my scenario, the connection sometimes freezes and never returns any reply (until I reboot the server). So I need a way to kill ssh if it does not return by itself.

      You are right, I should check Perl’s SSH modules.

  2. Dan C says:

    Would it not be sufficient to `sleep 30s; kill` from within the shell itself?

  3. Dan C says:

    Would it not be sufficient to `sleep 30s; exit` from within the shell itself?

    (sorry, ignore the previous comment)

  4. did you try things like ServerAliveInterval=30 ? What does freeze? Your click-click-tool? Or your ssh session on the server? On the server you could set ClientAliveInterval=30.

    Whale, using windows kill and putty do not sound like a sexy solution… try something else >:D<

    • prodlife says:

      If you want the sexy details – its the TCP stack on the server that breaks, hanging all connections. The client doesn’t detect this, because the beacon packets do get through. Very strange scenario.

  5. Freek says:

    What about cygwin?
    If you have permission to install it on the windows server, you could just use linux shell scripting

    • prodlife says:

      Cygwin was definitely another option. However, I’m not sure it forks processes in exactly the same way that native Linux will do. After what I’ve seen, assuming that the same scripting language or shell will behave in the same way under a different OS seems naive.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s