[PHP] Problem listen-socket & exec()

S

sparky

Mitglied
Servus, also folgendes Problem:

Die Klasse macht einen ListenServer auf einem bestimmten Port (55555) und horcht auf Verbindungen. Die Commands die ankommen haben dann folgendes Format: array('command' => 'cm_xxx', 'arg1' => 'blubb' ...)

Das ganze rennt dann natürlich in der Console:


PHP:
class    ListenServer extends BaseServer
{
    var    $readEndCharacter    =    "\r\n\r\n";


    function    onReceiveData( $clientId, $data )
    {
        $request    =    unserialize( $data );
        if( preg_match("/^cm_/i", $request['command']) )
        {
            
            switch($request['command']) {
                case 'cm_system': $response = $this->Run($response, $request['arg1']);
                break;
                case 'cm_writefile': $response = $this->writeFile($response, $request['arg1'], $request['arg2']);
                break;
                case 'cm_getfile': $response = $this->getFile($response, $request['arg1']);
                break;
                default: 
                    $response .= "no action found";
                    $this->sendDebugMessage("Server::Receive(): no matching action");
            }
        }

        else
        {
            $response    =    "error\r\n"
        }

        $this->sendDebugMessage("Server::Send(): $response");
        $this->sendData( $clientId, $response, false);
        $this->closeConnection( $clientId );
    }

    function Run($res, $cmd) {
        $this->sendDebugMessage("Server::Run(): $cmd");
        if(!escapeshellcmd($cmd)) return false;
        exec(escapeshellcmd($cmd), $o, $r);
        $this->sendDebugMessage("Server::Run(): output: $o | res: $r | ret: ".serialize(array($o, $r)));
        return $res . serialize(array($o, $r, 'return' => 'command executed')) . "\r\n\r\n";
    }
    
    function GetFile($res, $file) {
          $str = file($file);
        $this->sendDebugMessage("Server::getFile(): $file | str: " . serialize($str));
        return $res . serialize($str) . "\r\n\r\n";
    }
    
    function WriteFile($res, $file, $str) {
        $this->sendDebugMessage("Server::writeFile(): file: $file |str: $str");
        if(is_link($file)) {
            $this->sendDebugMessage("Server::writeFile(): deleting symlink: $file");
            $this->Run('rm -f ' . $file);
            $this->Run('touch ' . $file);
        }
          $fp = fopen($file, 'w');
        foreach($str as $value) {
            fwrite($fp, trim($value) . "\n");
        }
        fclose($fp);
        return $res . "\r\n\r\n";
    }
}


in meinem PHP Script (nicht in der Console, sondern normal Webserver) kommunisizere ich dann mit diesem Code: ($data = serialisiertes Array)

PHP:
function DaemonSend($data) {
        $socket = socket_create (AF_INET, SOCK_STREAM, 0);
        $result = socket_connect ($socket, $ip, 55555);
        $in = $data . "\r\n\r\n";
        $out = '';
        socket_write ($socket, $in, strlen ($in));

        while ($res = socket_read($socket, 2048)) {
            $out .= $res;
        }
        socket_close ($socket);
        return unserialize($out);
    }


so jetzt das Problem:
es geht alles reibungslos, nur wenn ich auf dem ListenServer die Methode Run() verwende und ein System Commando ausführen will, dann läuft mein PHP-Script auf dem Webserver in ner Endlosschleife. Bei allen anderen Methoden geht alles. Das System Commando wird sogar im Hintergrund gestartet & die Ausgaben umgelenkt (über ein Shellscript) so dass das Shellscript nur die PID von dem Ausgeführten Befehl zurückgibt. Wenn ich das gestartete Commando kille, dann lädt das Webserver-PHP File fertig.

An was kann das liegen ? Wenn ich dieselbe Run() Funktion local auf dem seelben Rechner ausführe wie mein Webserver-Script, dann geht alles optimal.

EDIT: ich habs auch mit anderen Fkt anstatt exec() versucht, aber mit allen dasselbe Problem
 
hmpf keine Chance, ich hab ALLE versucht nochmal, das tolle ist ja, der Listen-Socket beendet die Verbindung:

Debug:
Code:
2004-01-26 15:44:49 Server::Run(): output: Array | res: Array | ret: a:2:{i:0;a:1:{i:0;a:1:{i:0;s:5:"15987";}}i:1;a:1:{i:0;i:0;}}
2004-01-26 15:44:49 Server::Send(): a:3:{i:0;a:1:{i:0;a:1:{i:0;s:5:"15987";}}i:1;a:1:{i:0;i:0;}s:6:"return";s:16:"command executed";}
2004-01-26 15:44:49 Closed connection ( 0 ) from 192.168.0.161 on port 32812

aber das empfangende Script scheint sich bei socket_read() aufzuhängen :(
 
hi,

du hast eigentlich ein Problem dabei warum sich dein Script so verhält und sich der Client beendet: Bei einem exec wird normalerweise (ich glaub bei PHP nicht) der Prozess durch das gestartete Programm ersetzt. Bei PHP gibt IMHO exec nur den Output zurück. Aber er blockiert, da er so lange wartet bis der Prozess fertig ist, deshalb denkt der Client IMHO auch, dass die Connection beendet wurde und er schließt sie deshalb auch.

So nun ein Lösungsvorschlag: häng ein & an deinen Befehl an.

Steve

PS keine Ahnung ob stimmt. :)
 
EDIT:

also es liegt wohl an meinem Shellscript, denn ein "ls -l" oder ein shellscript mit einem einfachen "echo test" geht wunderbar.
das script:

Code:
#!/bin/bash
#export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
cd $(dirname "$1")
SVBIN=$(basename "$1")

for param ; do
        if [ "$param" != "$1" ] ; then
                SVARGS="$SVARGS $param"
        fi
done

./${SVBIN}${SVARGS} 2>/dev/null 1>/dev/null &
curr_pid=$!
echo "$curr_pid"
exit 0

negativ.
und wie gesagt, wenn ich denselben Code lokal aufrufe geht ja alles ...
 
Zuletzt bearbeitet:

Ähnliche Themen

nginx owncloud, php? Problem

NagiosGrapher 1.7.1 funktioniert nicht

Problem mit HSPA+ Modem Huawei E353 - Installation unmöglich?

dovecot und postfix Konfiguration Problem

CentOS 6.3 RADIUS - Keine Verbindung möglich

Zurück
Oben