[PHP] Re: A Separate Process?

2001-08-30 Thread Richard Lynch

You could just log the IP into a database, and then look it up later in
another script in a cron job.  You'll need PHP installed as a stand-alone
binary (aka CGI) and you'll want to read:

man 5 crontab

You could use select distinct and then would only need to look up each IP
once for a user that viewed many pages.

If you wait too long, though, the IPs will change on you for DHCP clients.
Still the same country probably though.

To answer your original question :-) what you are talking about is called
fork (like a fork in the road) and you do it something not unlike this:

exec(/path/to/some/other/script , $results, $errorcode);
echo implode(BR\n, $results);
if ($errorcode){
echo OS Error: $errorcode.  Usually path/permissions.  man
errnoBR\n;
}

It's the  symbol that tells the shell to fork.

The other script in question has to, e, I forget exactly, but I think it
has to *NOT* bind up stdin, stdout, or stderr, because then Apache and PHP
are waiting for that output...

Search the archives for fork and  and exec and you should find more
posts.

--
WARNING [EMAIL PROTECTED] address is an endangered species -- Use
[EMAIL PROTECTED]
Wanna help me out?  Like Music?  Buy a CD: http://l-i-e.com/artists.htm
Volunteer a little time: http://chatmusic.com/volunteer.htm
- Original Message -
From: Jordan Pickup [EMAIL PROTECTED]
Newsgroups: php.general
To: [EMAIL PROTECTED]
Sent: Monday, August 27, 2001 4:03 PM
Subject: A Separate Process?


 Is there any way to make a separate process in PHP?

 I do real-time stats collection on my site and one of the things I collect
 is the domain of the user (to get their country).

 Sometimes getting the domain name takes a few seconds to come back and the
 user has to wait for that time before their page displays.

 Is there any way to split of a separate process - that doesn't end when
the
 current process ends - to do the stats collecting so that the user doesn't
 have to wait?

 Or, if not, is there some way to tell the browser that it has all the data
 (so that it will finish rendering the page and run my javascript) and the
 script can continue running and do the ns lookup?

 I'm sorry if this question has been asked and answered before but I
couldn't
 find an answer anywhere else... and the archive for this list seems to be
 down.

 Jordan


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]




[PHP] Re: A Separate Process?

2001-08-30 Thread James Potts

Jordan,

Following (at the end of this post) is the code for a Unix daemon
(daemon.c).  It is setup to run on both System V and BSD.  I am not familar
with Linux.  In any case, you link in the object built from this code with
your main C program.  After you've setup your environment in your main
module, call daemon_start( 1 ).  You do not need to start it as a background
process, since it will fork itself and kill the child, anyway.  The main
thing the daemon does is disassociate itself from any terminals and ensures
zombie processes are left in the environment.

Apart from starting the daemon, you'll need to setup an infinite loop in
your main module.  Here's a snippet from a main module we use to query a
table, scg_system, that our applications in windows write to if they need to
execute a report on our Unix database server:  The only thing scg_system has
is a varchar field for the reports command line, a status to tell if the
command line has been run yet, and a time stamp.  We use the status of 1 to
tell if scg_sysd has read the row to execute the command line (so it won't
execute it again); 2 to indicate that scg_sysd successfully executed the
command; and 3 if scg_sysd tried, but could not execute the command, in
which case the error is logged by the LogError() function.

A good way to test your daemon, is to just setup main(), call
daemon_start(), and then in your infinite loop open a tty and write to it ,
then close the tty.  After the wait() in your main() program, another child
will be forked and it will write to the tty again.   Once you're satisfied
it works, just kill the process.  Warning: Do not test a daemon on a
production system.  It is not difficult to code in an error that might cause
the program to start forking until it fills-up the process table.


 /*
  * check for an open database before continuing.  This first loop is used
because the daemon is started when the system
  * inits and the database will not yet be running.
  */
 while( 1 ) {

  if( !fork( ) ) {
i = nCreateTable( );   /* nCreateTable() returns 0 when it has
successfully checked for/created the table */
fprintf( fp, %d, i ); /* write 1-char stat to tmp for parent
*/
fclose( fp );
exit( i );
  } else {

   wait( (int*)0 );   /* wait for child to exit */

   if( ( fp = fopen( szTmpNam, r ) ) == NULL ) {
LogError( Can't open tmp file(2), 0 );
exit( 1 );
   }

   fread( szBuf, sizeof( szBuf ), 256, fp ); /* get status */
   fclose( fp );/* close and unlink tmpfile */
   unlink( szTmpNam );

   status = atoi( szBuf );
   if( !status ) break;/* the database is started;
scg_system exists */

   signal( SIGALRM, alarm_catch );
   alarm( nSLEEPTIME );/* nSLEEPTIME is the number of
seconds to sleep */
   pause( );

   tmpnam( szTmpNam );
   if( ( fp = fopen( szTmpNam, w+ ) ) == NULL ) {
LogError( Can't open tmp file(3), 0 );
exit( 1 );
   }
}
} /* end while */

 fclose( fp );
 unlink( szTmpNam );

 /* this is the processing loop */
while( 1 ) {

if( !fork() ) {
   nRunDBCommands( );   /* look up the command line and system() the
command */
   exit( 0 );
} else {

   wait( (int*) 0 );

   signal( SIGALRM, alarm_catch );
   alarm( nSLEEPTIME );
   pause( );
  }
 }  /* end while */


/* alarm catcher doesn't need to do anything.  It could call alarm(), but we
did it in the while loop */
int alarm_catch()
{
return(0);
}/* end alarm_catch */


/** here's daemon.c /
/*
 * daemon.c - start process as a UNIX daemon
 *
 * syntax:  void  daemon_start( int ignsigcld )
 *
 * description:   daemon is called by the main process to disconnect
 *the process from any terminals and/or group
 *leader roles.  The nonzero ignsigcld flag is
 *to handle SIGCLDs so zombies don't clog.
 *
 * databases/files accessed:
 * name  type  description
 *      ===
 * scg_systemtable   hold command lines to be executed by scg_sysd
 *
 * function calls:
 * name description
 *  ===
 *
 * global variables:
 * name type  description
 *    ===
 *
 * edit history:
 * Date Programmer Description
 *  == ===
 * Thu Oct 24 02:34:24 EDT 1996 jlp   baselined for fm_sysd.ec
 *
 * Programmer's Note:
 */

static char ident[] =SCG Id: @(#) daemon.c 1.1.0.0. 10/14/97 17:00:50;

/*
 * defines
 */

/*
 * externals
 */

extern int errno ;

/*
 * includes
 */

#include stdio.h
#include signal.h
#include errno.h
#include sys/types.h
#include sys/param.h
#include SCGdefs.h

/*
 * globals
 */

/*
 * function declarations
 */

/*
 *
 *** Function definitions ***
 *
 */
#ifdef SIGSTP