Hello! Having serios troubles with my project DCunlimited (http://www.sf.net/prjects/dcunlimited)
Pasting two methods of my sockethandling class below:
function socketRead (&$socket, $callback)
{
// Set custom errorhandler
set_error_handler("errorHandler");
// Declare signalhandler
pcntl_signal(SIGUSR1, array($this, "signalHandler"));
// Check if callbacks is valid
if (!(function_exists($callback))) {
trigger_error("socketRead(): The specified callback isn't valid", E_USER_WARNING); restore_error_handler(); return(FALSE); }
// Check if FIFO is valid
if (!(is_writable(FIFONAME))) {
trigger_error("socketRead(): FIFO isn't writeable. Maybe it wasn't created properly", E_USER_WARNING); restore_error_handler(); return(FALSE); }
// Fork
if (($fork = pcntl_fork()) < 0) {
restore_error_handler(); return(FALSE); }
if ($fork == 0)
{
// I'm the child
// Open FIFO
$file = fopen(FIFONAME, "w");
// Start watching for data
$tmp = array($socket);
while(socket_select($tmp, $write = NULL, $excp = NULL, $time = NULL))
{
// Some data has arrived
// Write pid to FIFO
fwrite($file, posix_getpid());
// Send signal to parent
posix_kill(posix_getppid(), SIGUSR1);
// Sleep a little
// sleep(1);
}
// Came out of loop, something is wrong. Die.
die();
}
// I'm the parent
/** DEBUG */ echo("DEBUG: ".$fork);
// Open FIFO if needed
if (!$this->rNamedPipe) {
echo("DEBUG: ".($this->rNamedPipe = fopen(FIFONAME, "r"))."\n");
echo("DEBUG: ".($this->rNamedPipe)."\n"); }
// Set member var to pid for later use
$tmp = (int)(substr($socket, -1));
$this->aChildPid[$tmp] = $fork;
$this->aChildPid[$fork]['socket'] = &$socket;
$this->aChildPid[$fork]['callback'] = $callback;
// Everything worked, return TRUE
restore_error_handler(); return(TRUE);
}
function signalHandler ($signal)
{
// Set custom errorhandler
set_error_handler("errorHandler");
switch ($signal)
{
case SIGUSR1:
// New data have arrived
// Read FIFO and socket
print_r(fstat($this->rNamedPipe));
$pid = (int)(fread($this->rNamedPipe, 5));
echo("DEBUG: ".$pid."\n");
if (FALSE === ($data = socket_read($this->aChildPid[$pid]['socket'], 2048)))
{
// Something went wrong
trigger_error("Couldn't read from socket"); restore_error_handler(); return(NULL);
} elseif (!$data) {
// Connection closed
// restore_error_handler();
// $this->socketClose($socket);
// call_user_func($this->aChildPid[$pid]['callback'], FALSE);
// set_error_handler("errorHandler");
} else {
// Step through data and call callback for each line:
$data = explode("\n", $data);
for ($n = 0; $n < sizeof($data); $n++)
{
restore_error_handler();
call_user_func($this->aChildPid[$pid]['callback'], $data[$n]);
set_error_handler("errorHandler");
}
}
restore_error_handler();
break;
}
It should work like these: When you call socketRead(), it should fork, and the child should then loop a select()-statement. Each time the select()-statement returns, when there is new data, the child should write it's pID to a FIFO, and then send a SIGUSR1 to the parent.
The parent have then opened the FIFO in a mebervar (rNamedPipe), and the signal handler uses this member var (who is now a resource) to read the pID from the FIFO.
But something is wrong. Both sides opens the FIFO, and the child writes to it as it should. But when the parent tries to read from it, it casts an errormess, who is identical to the one you get when you try to read from a file who is already closed....
fread(): supplied argument is not a valid stream resource
Anyone have any ideas? Getting desperate :-S