streams von der Standardausgabe abfangen mit popen()

x0r

x0r

Bitschubser
Mahlzeit,

ich will eine API für das CGI entwickeln um z.Bsp.: start/stop-Scripte anstoßen zu können, Dateien zu erzeugen usw....

Hilfreich, wenn man die Ausgaben der Anwendung zur Verfügung hat um das Ergebnis irgendwie zu visualisieren. Hab daher versucht zunächst die Ausgaben in txt-Dateien zu streamen und anschließend diese mittels filepointern ausgelesen.

Jetzt möchte ich aber auch Pipes zwischen den Anwendungen aufbauen, und da wäre ja proc_open() eine gute Wahl, da ich ja auch schreibend auf die Standardeingabe zugreifen kann. Der Einfachheit halber habe ich zunächst versucht mit popen()
ein Shellcommando abzusetzen ($/bin/ls -l), und dessen Ausgabe mittels fgets() in einen Puffer zu überführen der mir dann eben die Rückgabe als Klartext präsentiert.

Hier mal ein Schnippslet:

Code:
FILE* CLI_httpd(const char* cstrParam)
{	

	void* cstrFullCMD = (char*)malloc(strlen(cstrParam)+strlen(" 2>/dev/null")+12);
	
        strcpy(cstrFullCMD, "/bin/ls -l ");
	strcat(cstrFullCMD, cstrParam);
	strcat(cstrFullCMD, 	" 1>/dev/null\0");

	return popen(cstrFullCMD, "r\0");		
}

soweit sogut, hier die Initialisierung des Puffer und die Überführung...
Code:
typedef int (*funcHandleType)(const char*);	// benutzerdefinierter Typ für ein Handle auf                               
                                                                   // Symbole in einer dynamischen Bibliothek

  
int main() {

     funcHandleType funcHandle = dlsym(pvDLLHandle, HTTPD);  // symbolhandle gewinnen
               ...          

     	        char* ThrdPuffer = NULL;
               	fgets(ThrdPuffer, (sizeof((funcHandle)(SecPuffer))+1), stdout);
               	printf("<br />Der R&uuml;ckgabestring: %s", ThrdPuffer);

So die Ausgabe ist aber jedesmal 'NULL', dabei sollte doch zumindes sowas wie "/bin/ls -l" eigentlich kein Problem darstellen ...

Hab ich mich mit dem fgets() vielleicht vertan ?!
Danke im Vorraus, MfG
 
Wenn ich das richtig verstanden habe, willst du jeglichen stdout in einer Log-Datei haben? Waere da nicht
Code:
#define LOG_FILE "/var/log/meinlog.log"
...
fclose(stdout);
freopen(LOG_FILE, "a", stdout);
setbuf(stdout, NULL);
wesentlich sinnvoller? Dann musst du nur immer den letzten Output aus der Datei holen, was sich z.B. dadurch vereinfachen laesst, dass du nach jedem abgesetzten Befehl einfach eine Markierung ins Log setzt, so dass du immer alles zwischen den letzten beiden Markierungen als Output rausholen kannst. Oder du ueberschreibst die Datei einfach mit jedem Befehl.
 
theton schrieb:
Wenn ich das richtig verstanden habe, willst du jeglichen stdout in einer Log-Datei haben?

Negativ: genau dass habe ich ja zuvor gemacht.
Es kostet aber mehr Taktzyklen erst einmal einen Stream in eine (meinthalben temporäre) Datei zu lenken, und diese erneut auszulesen. Bei multithread-Szenarien auf embedded Systemen (ist leider bei mir der Fall 8)) ist das extrem uncool...

Der Trick ist ja, den ganzen Quatsch mit den Wrappern für Low/Level-Filepointer zu umgehen, und ein paar Zyklen Geschwindigkeit mehr rauszuholen.
Prinzipell wäre es aber schon einfacher.

EDIT: @theton danke für den Tipp, habs aber dann doch noch gelöst.

Problem ist diese Zeile:

Code:
fgets(ThrdPuffer, (sizeof((funcHandle)(SecPuffer))+1), stdout);
und
Code:
strcat(cstrFullCMD, 	" 1>/dev/null\0");

Ich Dussel hab doch echt von der Standardausgabe gelesen, wo ich aus dem FILE*-Stream hätte lesen sollen :(
Und viel schlimmer ist, dass ich versucht habe eine Stream zu lesen, den ich ja explicit nach /dev/null umgelenkt habe (peinlich8))
naja, wieder was gelernt.
 
Zuletzt bearbeitet:

Ähnliche Themen

popen

Aus Datei lesen

Probleme mit syslog-ng & Speichern in MySQL

Zurück
Oben