c24chan has asked for the wisdom of the Perl Monks concerning the following question:

Hi:

I have the following script

==========================================
#!D:/Perl/bin/Perl.exe -w use strict; use CGI ":standard"; $| = 1; my $MYFILE = "D:\\Apache\\logs\\mgmtwrkstn\\lucky.txt"; if (param("monitor")) { &monitor(); } else { if (fork) { # only need to fork for IE print redirect(-uri => url() . "?monitor=yes", -nph=>1); } else { &do_stuff(); } sub monitor { my $html = &draw_page(); if (defined $html) { print header(-refresh=>1, -nph=>1), $html; } else { print header(-nph=>1), &goodbye(); } } sub goodbye { return start_html(-title=>"Goodbye!") . h1("Goodbye!") . end_html(); } sub get_number { open NUMBER, "<$MYFILE" or return undef; my $number = @glo; close NUMBER; return $number; } sub draw_page { my $number = &get_number(); return (defined $number) ? start_html(-title=>"Your Lucky Number") . p("Your lucky number is $number.") . end_html() : undef; } sub do_stuff { for my $i (1 .. 10) { open NUMBER2, ">$MYFILE"; print NUMBER2 $i; close NUMBER2; sleep 1; } unlink $MYFILE; }
=========================================================

What this script essentially do is that it forks a child process to write 1 to 10 on some file, while writing it, the parent process will refresh the page every second to read the content of that file. This script is orginally from http://hypernews.ngdc.noaa.gov/HyperNews/get/webscience/2/6/1.html?nogifs It works under Unix environment with apache. However, when I run this script in W2K and apache 1.3.x. It doesn't work. It seems like that the child process is locking the files its writing to and the parent process can't go into it. Therefore, the parent process doesn't refresh the page until the child process unlink ("delete") the file. Can anyone help me on this one? I am a newbie on Perl and CGI and I want to continuosly monitor some background job on a web page.

Thanks Herman

Replies are listed 'Best First'.
Re: CGI real time update on Window/Apache problem
by tcf22 (Priest) on Oct 09, 2003 at 19:48 UTC
    On Win32 fork() doesn't do a true fork. Check the PID it returns, its negative. It creates a pseudo-process in the same address space as the original process. The process can't be detached from the original process. This may be causing your problem, if the same script works on Unix.

    Try using Win32::Process instead of fork to create a new process.
    Win32::Process::Create($ProcessObj, "D:\\winnt35\\system32\\notepad.exe", "notepad temp.txt", 0, DETACHED_PROCESS, ".")|| die Win32::GetLastError();

    - Tom

      hm... I don't think its a fork problem, since window really create a child for the writing thread to the file, its just that the parent thread cannot read it until its child is finish. I think its more or less a flushing problem? Do you agree?

      Anyways, I now have the following code, and IE give me a page not found error, do you know why?

      #!D:/Perl/bin/Perl.exe -w use strict; use CGI ":standard"; use IO::Handle; use Win32::Process; use Win32; $| = 1; my $MYFILE = "D:\\tmp"; my $share = "begin"; if (param("monitor")) { &monitor(); } else { Win32::Process::Create($Process, "D:\\ping.exe yahoo.com > + ${MYFILE}", "ping",0,DETACHED_PROCESS, ".") || +die "Create: $!"; } # print redirect(-uri => url() . "?monitor=yes", -nph=>1); } sub monitor { my $html = &draw_page(); if (defined $html) { print header(-refresh=>1, -nph=>1), $html; } else { print header(-nph=>1), &goodbye(); } } sub goodbye { return start_html(-title=>"Goodbye!") . h1("Goodbye!") . end_h +tml(); } sub get_number { open NUMBER, "<$MYFILE" or return undef; NUMBER->autoflush(1); my $number = <NUMBER>; close NUMBER; return $number; } sub draw_page { my $number = &get_number(); return (defined $number) ? start_html(-title=>"Your Lucky Numb +er") . p("Your lucky number is $number.") . end_html() : undef; } sub do_stuff { for my $i (1 .. 10) { open NUMBER, ">$MYFILE"; NUMBER->autoflush(1); print NUMBER "$i\n"; close NUMBER; sleep 1; } unlink $MYFILE; }