The Nightstar Zoo

Nightstar IRC Network - irc.nightstar.net
It is currently Mon Oct 23, 2017 6:47 am

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sun Oct 16, 2005 10:03 am 
Offline
Safari Exhibit
Safari Exhibit
User avatar

Joined: Mon Feb 07, 2005 3:48 am
Posts: 151
Location: Durban, South Africa
I have a rather nasty problem. I have set up a home network which my parents use. Since I refuse to put a Windows XP box directly on the internet (it was bad enough when it was a standalone win98 box) the server, which does dialup and IMAP amongst other things, runs Debain Linux.

Since my parents don't want to ssh to the server to dialup, fetch mail, etc. I've written a php "control panel" to provide an easy interface to dialing up, fetching mail, etc. but at the moment the webserver doesn't give back the page until the calls to system() that do the work return.

I've been trying to do some kind of non-blocking I/O with the output from fetchmail and friends redirected into temp files which are then read on a page refresh to determine progress. The whole thing is a big, nasty state machine.

Now, the state machine bit I can handle. That's ugly, but not too horrible. The bit that gets me is trying to get php to spawn a process and return immediately. The following is the obvious method:

Code:
system("do_fetchmail 2>&1> $fetchmailfile &");


But it still waits until fetchmail returns before it gives the page back to the browser. Variations on the same theme don't seem to want to work either.

Has anybody ever done anything like this?


Top
 Profile  
 
PostPosted: Sun Oct 16, 2005 1:39 pm 
jerith wrote:
Code:
system("do_fetchmail 2>&1> $fetchmailfile &");


But it still waits until fetchmail returns before it gives the page back to the browser. Variations on the same theme don't seem to want to work either.

Has anybody ever done anything like this?


So you're trying to background it? I don't know if system() in PHP interprets the amp in that way, if it's wait()ing on the child process there's not a whole lot you can do. I don't know if it handles the redirection either... It's probably like the C system() (which is not a system call) and uses sh to interpret the command line.

Chances are there's another library call that does something closer to what you want. Check the docs, it might even have a direct wrapper for fork() and exec(). If not, write a shell script wrapper:

Code:
#!/usr/bin/env bash

do_fetchmail > $fetchmailfile 2>&1 & disown


I'm assuming you want it to start up and then go away.

That said... why are you doing it this way? Why can't they just check their mail directly? Why can't this be run automatically every few minutes from cron?


Last edited by anthonyr on Mon Oct 17, 2005 6:30 pm, edited 3 times in total.

Top
  
 
PostPosted: Sun Oct 16, 2005 2:25 pm 
Offline
Safari Exhibit
Safari Exhibit
User avatar

Joined: Mon Feb 07, 2005 3:48 am
Posts: 151
Location: Durban, South Africa
anthonyr wrote:
So you're trying to background it? I don't know if system() in PHP interprets the amp in that way, if it's wait()ing on the child process there's not a whole lot you can do. I don't know if it handles the redirection either...


As far as I can tell (the documentation isn't very clear on this point) it spawns a shell to run the command. Output redirection definitely works at least.

Further googling shows that a hack with piped execution does the trick:

Code:
proc_close (proc_open ($ExecCommand,array(),$somefun));


I haven't tried this yet, though.

anthonyr wrote:
That said... why are you doing it this way? Why can't they just check their mail directly? Why can't this be run automatically every few minutes from cron?


Unfortunately I live in the land of expensive bandwidth and dialup connections, so cron is out of the question.

Also, I have the server running IMAP so that all the client machines have access to the mail. Thus, the client machines talk IMAP to the server where all the messages are stored and the server has to talk POP3/SMTP to the ISP over the dialup connection, which can't be done from the mail client. (At least, not unless I write a Thunderbird extension which I don't have the time to learn to do.)


Top
 Profile  
 
PostPosted: Sun Oct 16, 2005 4:06 pm 
jerith wrote:
As far as I can tell (the documentation isn't very clear on this point) it spawns a shell to run the command.


Yes, but the only way to run a program without the process that initiates it being replaced is to fork() first, so we already know it's spawing a process. The problem is that it's wait()ing for the child to terminate. As far as I can tell, you're trying to initiate it and then leave it to take its own sweet time to finish.

There should be another library call that doesn't wait().


Top
  
 
 Post subject:
PostPosted: Sun Oct 16, 2005 4:51 pm 
Write a small program in C that spawns a process whose path is given as an argument and immediately returns. Call THAT from PHP.

Something like:
Code:
#include <unistd.h>

int main (int arg_num, char** argv)
{
    int pid;

    // Bad arguments.
    if (arg_num < 2)
        return 0;

    switch (pid = fork())
    {
    // Fork failed.
    case -1:
        return 0;

    // This is the child process.
    case 0:
        execv(argv[1], &argv[1]);  // the second arg should probably have the path stripped, but meh.

    // This is the parent process.
    default:
        return pid;
    }

    return 0;
}


This will spawn the process you want to run and return its pid.

I'm certain there are ways to do this with perl or bash scripts and so forth, but I don't know perl and I haven't written a bash script in a long time, so there you are. :)


Top
  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 4:00 pm 
For goodness' sake Raif, you've got a working, fast, pretty-much-bug-free implemenation in C. Scripting languages? Bleck!


Top
  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 6:28 pm 
MineFelinePossesseth wrote:
For goodness' sake Raif, you've got a working, fast, pretty-much-bug-free implemenation in C. Scripting languages? Bleck!

The scripting language way is one line...


Top
  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group