come aggirare un bug del php

Ho un problema che non riesco a risolvere (ma va?).

Ho un eseguibile windows che funziona da linea di comando (ovviamente non ho i sorgenti). Questo eseguibile mostra tutto a schermo, ogni tanto mostra qualche nuova riga e l'unico comando che accetta da tastiera e' CTRL+C per terminarlo (se non lo si preme lui non muore mai). Fin qui tutto ok. Quindi il primo punto e' che questo non e' un eseguibile come gli altri (il comando dir ad esempio), ma e' un programma che non termina mai.

La prima anomalia e' che se io lancio da shell:

prog.exe>log.txt

a video non compare piu' nulla ma il file log.txt resta inspiegabilmente vuoto. Ovviamente questo anche se aggiungo 2>&1 alla fine del comando.

Invece, anche se cosi' per me e' inutilizzabile, prog.exe|more funziona. Questo e' gia' un bel mistero.

Ma veniamo al mio php 5.25 x64. In questo caso shell_exec, exec e company non mi servono a nulla. Piuttosto devo usare popen o proc_open per aprire una risorsa verso l'eseguibile e "mettermi in ascolto", facendo un fread ogni tanto all'interno di un ciclo. Peccato che pero' questa cosa non funziona e la colpa sembra essere di questo bug: http://bugs.php.net/bug.php?id=47918 (o forse di questo: http://bugs.php.net/bug.php?id=34972).

In pratica io dovrei aprire una proc_open in modalita' non-blocking ma questa cosa e' bugata sotto windows e quindi amen. Escluderei workaround tramite php, c'ho sbattuto la testa fino ad oggi.

Il workaround che si puo' fare e' proprio prog.exe>log.txt. Scrivo sul file di log, quindi col php vado a leggere li' (almeno questo il php lo sa fare ...). Il punto e' che, come ho scritto all'inizio, il file di log mi resta vuoto. Mistero. Come me ne esco? Suggerimenti?

 

inviato 7 anni fa
aik
aik
1
modificato 6 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

Scusa...a me sembra stai usando una sintassi tipo bash... nome_eseguibile > log.txt

Questa operazione la può fare una shell (correggetemi se sbaglio). Tu come la vuoi fare?

Su che server stai?

A che ti serve questo eseguibile? Per curiosità, cosa fa che non ho capito?

Ciao

risposto 7 anni fa
Mario Santagiuliana
X 0 X

Questo eseguibile mi controlla un lettore rfid. Ogni volta che ci avvicino un tag rfid l'eseguibile mi mostra in output il suo identificativo. A me serve leggere questo identificativo tramite i miei script php.

L'eseguibile, una volta lanciato, non muore mai, a meno che non si digiti CTRL+C. Ovviamente a me va bene cosi'.

Siccome questo eseguibile non muore mai non posso interrogarlo tramite shell_exec, exec o altri, perche' questi programmi attendono il termine dell'esecuzione per girarmi l'output. Quindi ci sono 4 possibili modi:

* redirigo l'output dell'eseguibile su un file e col php accedo a quel file

* provo ad aprirlo tramite popen o proc_open

* faccio un new COM() di WShell e uso stdout->Read()

* uso una libreria php in grado di interfacciarsi con il reader PCSC

Nessuna di queste soluzioni funziona a dovere. Scartiamo l'ultima, perche' l'unica libreria esistente e' ferma a molti anni fa e non riconosce i miei tag rfid. Torniamo all'eseguibile.

Quando avvio l'eseguibile questo e' istantaneo e veloce a schermo, tutto fila liscio e non ho alcun ritardo. Ma quando provo a leggere il suo stdout (ovvero cio' che lui mostra a schermo) questo non viene "intrappolato" subito ma solo quando la dimensione dello stdout arriva a 4K. E non riesco a spiegarmi perche'.

Provo a fare un esempio affinche' sia chiaro.

Se io faccio da prompt windows:

c:\>ping /t www.phpnews.it >output.txt

e osservo il file output.txt noto che ogni tot ms il file cresce di qualche byte. Ovvero il comando ping genera dell'output che, come chiunque si aspetta, viene immediatamente aggiunto al file output.txt

Stessa identica cosa se io uso popen("ping /t www.phpnews.it"); o proc_open("ping /t www.phpnews.it") e poi tramite un while faccio continuamente fread su quell'handler. Praticamente ogni volta che il mio eseguibile, ping, genera una riga di output questa viene subito letta dal php e dal suo fread.

Invece la cosa NON funziona cosi' col mio eseguibile. Nonostante quando lo lancio normalmente questo e' fluido, quando provo a leggere il suo output in uno dei modi elencati riesco a farlo solo a blocchi di 4k, ovvero finche' la dimensione dell'output non raggiunge i 4 Kb io non vedo nulla (ne' nel file di log del primo esempio, ne' usando l'fread del secondo esempio, ne' usano la StdOut->Read(1)). Non appena raggiungo i 4K ricevo il blocco di 4K (esattamente 4096 bytes)

Cio' che e' frustrante e' che non trovo niente del genere su Google, ovvero facendo una ricerca con 4k, shell, windows e altro non mi spunta alcun risultato utile.

Non posto qui l'eseguibile perche' e' "cattiva educazione", ma chi si vuole cimentare puo' farlo senza particolare sforzo. Qui c'e' l'sdk: http://www.springcard.com/download/sdks.html (il file e' pcsc-sdk_1-05.zip), scompattate lo zip (non occorre installare nulla) e provate il file in questione (pcscmon.exe). Non importa se non avete il lettore rfid, in questo caso vedrete semplicemente questa scritta:

SpringCard PC/SC Monitor
------------------------
This program is free software (GPL)
v.081114 (c) 2008 Pro Active
Press <Ctrl+C> to exit

No PC/SC reader

Ora provate a catturare in qualche modo quella scritta col php. Scommetto che non ci riuscite ...

risposto 7 anni fa
aik
aik
1
X 0 X

Lavoro su linux e non ho tanto tempo da dedicare alla visione degli script in windows (posso usare wine ma non è la stessa cosa).

Il problema come hai detto si risolverebbe se il tuo programma (è opensource, è licenza GPL, per quale ragione non puoi modificarlo?) correttamente indirizzasse tutto l'output in un file.

O modifichi il programma o usi una shell più potente rispetto alla riga di comando di windows...

risposto 7 anni fa
Mario Santagiuliana
X 0 X

Purtroppo per avere i sorgenti devo attendere l'esito della registrazione e approvazione manuale sul sito del distributore (non mi pare molto user-friendly per chi adotta la GPL, ma tant'e'). Poi dovro' vedere quale tool usare per compilare i suoi sorgenti, modificare i sorgenti e vedere se cosi' va (altre possibili soluzioni sono trovare la controparte che funzioni sotto linux o altri programmi simili sotto windows).

Fatto sta che e' una bella seccatura non riuscire tramite popen o proc_open ad interagire con un banalissimo programma da linea di comando windows ...

risposto 7 anni fa
aik
aik
1
X 0 X
Purtroppo per avere i sorgenti devo attendere l'esito della registrazione e approvazione manuale sul sito del distributore (non mi pare molto user-friendly per chi adotta la GPL, ma tant'e')

Mi sembra una violazione della licenza GPL la quale specifica che i sorgenti del programma devono essere liberamente distribuibili, visionabili e modificabili!!!

Un buon spunto da cui partire per esserne certi: http://www.gnu.org/licenses/gpl-violation.it.html

Vedo se trovo qualcosa sotto linux che faccia la stessa cosa ma non sarà immediato...

Ciao

risposto 7 anni fa
Mario Santagiuliana
X 0 X

L'equivalente sotto linux e' questo: http://ludovic.rousseau.free.fr/softwares/pcsc-tools/

Domani cerchero' di farlo funzionare, speriamo bene ... anche se per una lunga serie di ragioni preferirei avere la versione per windows funzionante (infatti spero di riuscire ad accedere ai sorgenti quanto prima)

risposto 7 anni fa
aik
aik
1
modificato 7 anni fa
X 0 X

Niente da fare: sono fermo da una settimana. Non va niente, che nervi!

Lo script sotto linux non va perche' i driver dell'omnikey sotto linux non vanno! Ma va a capire perche'!

L'account per accedere ai sorgenti della versione GPL di Windows ancora non me l'attivano!

Trovo in rete possibili script equivalenti, uno in perl, l'altro in python. Il primo ignoro perche' non va, il tanto decantato python, appena installato, mi dice "ImportError: No module named readline", un errore che se cerchi su Google compare SOLO per chi compila sotto linux, peccato che invece io ho usato l'installer di windows!

L'unico programma del cavolo che funziona e bene, quello sotto Windows, non si riesce a catturarne l'output, ne' col php ne' da shell. E ovunque chiedo, nonostante la buona volonta' o l'impegno, nessuno sa aiutarmi. Scusate lo sfogo, questa decisamente non e' la mia settimana!  :buck:

risposto 7 anni fa
aik
aik
1
X 0 X

Domanda disinteressata visto che non ho avuto modo di seguire a fondo il Thread:

hai provato a lavorare con l'output buffering per cercare di catturare l'output?

:bye:

risposto 7 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

Si', come ho scritto nel primo post si', ma senza successo.

Alla fine ho risolto grazie a Python 2.5 32 bit (l'unico che poteva aiutarmi, le versioni successive e quelle a 64bit non andavano). In pratica ho trovato un driver equivalente che funziona sotto python, che fa praticamente la stessa cosa e che lanciandolo finalmente redirige l'output.

Poco importa che pero' non possa lanciare questo script da shell_exec. Se lo lancio da li' shell_exec mi restituisce una stringa vuota, probabilmente il tentativo di avviare quello script python nella shell del php fallisce, ma che mi frega: lancio il processo separatamente da shell windows, l'output viene rediretto correttamente su file e il php accede al file e va bene cosi' ...

Certo che e' incredibile non poter redirigere l'output come logica vorrebbe, anche perche' in determinati casi proprio non se ne puo' fare a meno ...

risposto 6 anni fa
aik
aik
1
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda