control interactivo de un progtwig usando php

Me gustaría ejecutar un progtwig C en una computadora remota usando php. El objective final es controlar el progtwig utilizando un navegador web en un teléfono o cualquier otra computadora.

Mi progtwig C está adquiriendo datos de diferentes sensores durante algunas decenas de minutos. Se ejecuta desde la línea de comandos en Linux y puedo apagarlo presionando la tecla ‘q’ en el teclado de la computadora. El hilo principal es algo como esto:

int main(){ printf("Program is running... Press 'q'  to quit\n"); fflush(stdout); //create one thread per sensor while (getchar() != 'q'){ } //ask the threads to terminate return(0); } 

Cada hilo realiza un printf para dar el estado de cada sensor. Me gustaría controlar estos valores en mi teléfono y tener un botón para finalizar el progtwig remoto.

Puedo monitorear con éxito los valores usando system (), open () o proc_open (). Su problema es el getchar en el progtwig principal. Cuelga el script php …

  array("pipe", "r"), // // stdin est un pipe où le processus va lire 1 => array("pipe", "w"), // stdout est un pipe où le processus va écrire 2 => array("file", "/tmp/error-output.txt", "a") // stderr est un fichier ); $cwd = '/tmp'; $env = array(); $process = proc_open('/home/tristan/www/a.out', $descriptorspec, $pipes, $cwd, $env); if (is_resource($process)) { fwrite($pipes[0], 'q'); fclose($pipes[0]); echo stream_get_contents($pipes[1]); fclose($pipes[1]); $return_value = proc_close($process); echo "La commande a retourné $return_value\n"; } } ?> 

Usando fwrite($pipes[0], 'q'); funciona bien, pero el script php se cuelga si uso fwrite($pipes[0], ''); para mantener el progtwig en ejecución …

EDITAR: He invertido el problema de almacenamiento en búfer $process = proc_open('stdbuf -i0 /home/tristan/www/a.out', $descriptorspec, $pipes, $cwd, $env); sin éxito…

¿Alguien tiene una pista sobre cómo monitorear valores y enviar comandos al progtwig de una manera interactiva?

Gracias por tu ayuda !

Hubo dos problemas con el código PHP anterior que permite que su progtwig se cuelgue:

  • stream_get_contents() se bloqueará para siempre, esperando una EOL que nunca aparece cuando el código C se ejecuta en un bucle infinito. Deberá usar stream_set_blocking() para evitar que stream_get_contents() bloquee

  • proc_close() también espera por siempre a menos que el proceso haya finalizado. Lo cual nunca ocurre debido al ciclo sin fin. Tendrás que terminarlo explícitamente usando proc_terminate() (lo cual no tiene mucho sentido en absoluto)

He preparado un ejemplo de cómo el código no se bloquea, pero debo decir que su código no tiene mucho sentido. Codificaría el progtwig C como un daemon UNIX que escucha un socket de dominio UNIX. Luego puede diseñar un protocolo de comunicación simple basado en texto para sus comandos. Luego, conéctese al socket en PHP. Pero tal vez estoy equivocado ya que no conozco su escenario de aplicación en detalle.

Sin embargo, aquí viene su código fijo:

 $descriptorspec = array( 0 => array("pipe", "r"), // // stdin est un pipe où le processus va lire 1 => array("pipe", "w"), // stdout est un pipe où le processus va écrire 2 => array("file", "/tmp/error-output.txt", "a") // stderr est un fichier ); $cwd = '/tmp'; $env = array(); $process = proc_open(__DIR__ . '/a.out', $descriptorspec, $pipes, $cwd, $env); if (is_resource($process)) { fwrite($pipes[0], ' '); fclose($pipes[0]); // set stream to unblocking mode stream_set_blocking($pipes[1], 0); // now the following line will not wait forever // for an EOF echo stream_get_contents($pipes[1]); fclose($pipes[1]); // proc_close will wait until the process has finished - forever in this case // if you want to terminate the process. You'll have to terminate it explicitely proc_terminate($process); $return_value = proc_close($process); // if you want to have a meaningful return value // you'll have to implement a handler for SIGTERM // in your C program echo "La commande a retourné $return_value\n"; } 

Finalmente obtuve lo que quería usando tuberías dentro de la función del sistema ():

 < ?php if(isset($_POST['start'])){ system('> /tmp/progOut'); system('mkfifo /tmp/progIn'); $proc = popen('./a.out < /tmp/progIn > /tmp/progOut &', 'r'); } ?>