Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » stdin und stdout umleiten (für cgi schnittstelle)

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
18.08.2005, 17:39 Uhr
Skippy



so ich möchte für meinen server eine cgi schnittstelle schreiben
aber irgendwie kapier ich das ganze net

daher hat jemand ein paar gute links zu dem thema ? oder kann mir erklären wie das gemacht wird habe leider nichts dazu gefunden

und den einzigen code beispiel aus nem anderen server versteh ich überhaupt nicht was gemacht wird

ich hatte jetzt mal aus jux ne anwendung geschrieben die mir schonmal wenigstens die paramter die übergeben werden anzeigt


die würde dann in php-cgi.exe umbenannt und meinen richtigen server (janaserver2)
als exe zum ausführen von .php dateien

dann bekomme ich vom server den output der normalerweise in der konsole stehen würde

hier der code


C++:
#include <stdio.h>
#include <cstdlib>
#include <iostream>

int main(int argc, char *argv[])
{

  FILE * pFile;
  pFile = fopen ("paramfile.txt","w"); //datei zum schreiben öffnen

  for(int x = 0; x < argc; x++)
  {
    printf("Parameter %d: %s\n", x, argv[x]); //eintrag in konsole ausgeben
    fprintf (pFile, "Parameter %d: %s\n", x, argv[x]); //eintrag in datei speichern
  }
  fclose (pFile);

  system("PAUSE");
  return 0;
}


was mich interessieren würde kann in stdin nochmer stehen und wie könnte ich das anzeigen lassen


PS: so sieht die ausgabe dann aus die ich im internetexplorer habe

(einfacher text )

Code:
Drcken Sie eine beliebige Taste . . .
Parameter 0: C:\Php\PHP-cgi.EXE
Parameter 1: C:\Programme\Jana2\html\Forum\viewforum.php

Dieser Post wurde am 18.08.2005 um 17:42 Uhr von Skippy editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
19.08.2005, 08:15 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hi, die commandozeilenparameter sind NICHT!!!! der stdin! Vom stdin kannste mit z.b mit scanf/gets/getc lesen!
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
19.08.2005, 14:41 Uhr
Skippy



@FloSoft das weiß ich natürlich habe ja an dem Programm noch gearbeitet nur da ich nicht weiß wie daten in stdin übergeben werden bin ich noch am probieren bis jetzt hats aber noch nicht geklappt habe cin und cin.getline probiert aber anscheinend kommt bei php auch nichts rüber jedenfalls zeigt er mir nichts an is aber momentan auch net ganz so wichtig ich muss ja erstmal wissen wie das geht mit stdin und stdout umleiten

habe etwas gefunden mit pipes soll das gut mölich sein aber das ganze spielchen versteh ich auch nicht, das was ich bis jetzt zum thema gefunden habe sieht schrecklich aus


aber sowei ich das bisher verstanden habe muss ich um cgi/php auszuführen
-stdin stdout initialisieren
-setzen der EnvironmentVariable ?keine ahnung wie das nun wieder geht
-daten in stdin packen
-programm starten mit parameter ?oder muss ich das programm starten bevor stdin beschrieben wird
-wenn programm fertig(beendet) dann stdout auslesen? oder muss das vorher geschehen

also wenn jemand dazu informationen hat immer her damit übrigens man soll wohl execute process verwenden also auch darüber wäre ich für informationen dankbar
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
22.08.2005, 22:53 Uhr
imhotep
followed the white rabbit


Hallo

Zu Beginn sollte ich dich vielleicht Aufklären was stdin/stdout eigentlich ist.
Es handelt sich um die Standardkanäle für Ein- bzw. Ausgaben von Konsolenprogrammen.
Sprich, ich hab ein Programm, das will, das ich ihm was ein geben ich tippe auf meiner Tastatur was ein drücke Enter und das ganze wird durch stdin an das Programm übergeben. Dann macht das Programm eine Ausgabe, die wird an stdout gesendet, das sie mir auf dem Bildschirm anzeigt. Zusätzlich gibt es noch stderr, für Fehlernachrichten.
Das ganze hat eigentlich den Sinn, dass der Programmierer sich nicht darum kümmern muss wo seine Daten herkommen und hingehen, und der Anwender zum Beispiel Ausgaben in Logdatein umleiten kann.

Mal ne kleine Frage, wo sollen die daten den herkommen? aus ner datei? dann kannst du die datei umleiten und als stdin verwenden bzw. gleich die datei auslesen (wass sicherlich besser ist).

Zu 1.
Wie schon erwähnt braucht man stdin und stdout nicht initalisieren, weil die es standardmässig sind, man kann sie aber umleiten.
Datei auf stdin umleiten:


BASH:

prog < inputdatei



als code sähe das dann so aus:


C++:
char * input;
while (gets(input) != NULL) {
    printf("Parameter %s", input); //eintrag in konsole ausgeben
    fprintf(stdout, "Parameter %s", input); //das selbe wie die Zeile zuvor, nur expliziter
    fprintf (pFile, "Parameter %s", input); //eintrag in datei speichern
}



stdout wird zum Beispiel von "printf" verwendet um Text auszugeben, was im Allgemeinen auf der Konsole passiert.
stdout in eine Datei umzulenken:

BASH:

programm > outputdatei



Fehlermeldungen solltest du seperat auf stderr ausgeben, um diese besser zu erkennen.

C++:
    fprintf(stderr, "Hab Mist gebaut :-(\n"); //eine Fehlermeldung auf stderr


Das hat den Vorteil, dass du die Fehlermeldungen getrennt von den normalen Ausgaben umleiten kannst.


BASH:

programm 2> errordatei



kannst auch alles frei kombieren

BASH:

programm <inputdatei > outputdatei 2> errordatei



Zu 2.

Umgebungvariablen setzen hängt vom Betriebsystem ab.
Da du WinXp zu verwenden scheinst nehm ich mal an, dein Server auch.

Unter WinXP setzt man Umgebungsvariablen in der Systemsteuerung->System da müßte unter irgendeinem Reiter ein Knopf mit der Aufschrift Umgebungsvariablen sein.

Die Variable sieht dann etwa so aus

Code:
HOME="C:\laala"



(weiß jetzt nicht, ob die Großschreibung bei Windows zwingend ist, aber schaden kanns nicht)

Zu 3.
wie schon gezeigt kannst du Dateien in stdin umleiten
an sonsten wär stdin ne ganz normale eingabeaufforderung.

Zu 4.
das Programm mit Parametern und Umleitung sähe etwa so aus


Code:
programm -a -f < dateiname



Zu 5.
stdout würde während das Programm läuft Nachrichten ausgeben (siehe printf-Ausgaben)



Also ich denke du solltest an das Problem anderst ran gehen:

Schreib deinen Eingaben in eine Datei und speichere die Ausgaben in eine andere.
stdin und stdout (und nicht zu vergessen stderr) sind eigentlich nur gedacht für Konsolenanwendung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
23.08.2005, 09:14 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


cgi ist "konsole", d.h das programm wird vom webserver aufgerufen, der scriptname ist glaub ich im parameter drin, alle post-daten jedoch per stdin, get-daten landen in den parametern, weitere webserver-variablen in den environment-dateien.

Falls du IIS benutzt, warum nimmst du nicht das php-isapi-modul? da kannst du dann auf das cgi verzichten. (oh seh grad du nimmst jana, aber da kannste doch auch direkt einstellen das php geht)
--
class God : public ChuckNorris { };

Dieser Post wurde am 23.08.2005 um 09:15 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.08.2005, 13:49 Uhr
Skippy



wir haben uns da ein klein wenig missverstanden ich schreibe nicht die client seite vom cgi sondern die server seite daher ich muss alles anbieten damit ich die clients benutzen kann
daher ich muss dafür sorgen das php_cgi.exe richtig aufgerufen wird und die von php-cgi.exe kommenden daten über nem socket verschickt werden



der code selbst ist für nen webserver den ich schreibe ich hab das mit jana nur getestet wie die daten aussehen die ankommen mein problem ist ja bisher nur das die parameter übergabe bei create process nicht klappt bei create prozess kann man ja die angabe welche exe gestartet wird und den übergebenen parameter jeweils extra als parameter der funktion creat prozess übergeben geht aber komischerweise nicht es klappt nur wenn ich als 2parameter beides als einen string übergebe problem dabei ist nur das ich beides (die auszuführende exe und den parameter(übergebene datei ) extra habe und die nun vorher erst noch zusammenfügn muss

also hier mal die funktion wie ich sie bisher hab bitte wer zeit kann ja mal schauen ob dort fehler sind oder was man verbessern könnte
Danke schonmal für eure bisherige gedult und mühe




C++:

std::string ExecuteCGI()
{
            
printf ("\n\nCGI exECUTE,");
  std::string answerbuf;
  char buf[1024];           //i/o buffer



  STARTUPINFO si;
  SECURITY_ATTRIBUTES sa;
  SECURITY_DESCRIPTOR sd;               //security information for pipes
  PROCESS_INFORMATION pi;
  HANDLE newstdin,newstdout,read_stdout,write_stdin;  //pipe handles

  if (IsWinNT())        //initialize security descriptor (Windows NT)
  {
    InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, true, NULL, false);
    sa.lpSecurityDescriptor = &sd;
  }
  else sa.lpSecurityDescriptor = NULL;
  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle = true;         //allow inheritable handles

  if (!CreatePipe(&newstdin,&write_stdin,&sa,0))   //create stdin pipe
  {
    ErrorMessage("CreatePipe");
    getch();
    return 0;
  }
  if (!CreatePipe(&read_stdout,&newstdout,&sa,0))  //create stdout pipe
  {
    ErrorMessage("CreatePipe");
    getch();
    CloseHandle(newstdin);
    CloseHandle(write_stdin);
    return 0;
  }
  
    GetStartupInfo(&si);      //set startupinfo for the spawned process
  /*
  The dwFlags member tells CreateProcess how to make the process.
  STARTF_USESTDHANDLES validates the hStd* members. STARTF_USESHOWWINDOW
  validates the wShowWindow member.
  */

  si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.wShowWindow = SW_HIDE;
  si.hStdOutput = newstdout;
  si.hStdError = newstdout;     //set the new handles for the child process
  si.hStdInput = newstdin;
  char app_spawn[] = "c:\\php\\php-cgi2.exe"; //sample, modify for your
                                                     //system
  char app_cmdline[] = "c:\\php\\php-cgi.exe C:\\Programme\\Jana2\\html\\index.php"; //sample, modify for your
                                                     //system


  //spawn the child process
  if (!CreateProcess(NULL,
  app_cmdline,// command line
  NULL,// process security attributes
  NULL,// primary thread security attributes
  TRUE,// handles are inherited
  CREATE_NEW_CONSOLE,// creation flags
  NULL, // use parent's environment
  NULL,// use parent's current directory
  &si, // STARTUPINFO pointer
  &pi))// receives PROCESS_INFORMATION
  {
    std::cout << "Fehler: " << GetLastError();

    ErrorMessage("CreateProcess");
    getch();
    CloseHandle(newstdin);
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(write_stdin);
    return 0;
  }

  unsigned long exit=0;  //process exit code
  unsigned long bread;   //bytes read
  unsigned long avail;   //bytes available

   printf ("\n\nCGI exECUTE,");

  bzero(buf);
  for(;;)      //main program loop
  {
    GetExitCodeProcess(pi.hProcess,&exit);      //while the process is running
    if (exit != STILL_ACTIVE)
      break;
      
   //WaitForSingleObject(pi.hProcess,INFINITE);   dann brauchen wir die schleife nicht mehr
   //Durch ändern des WaitForSingleObject kann auch erreicht werden,
   //dass das Programm nicht endlos wartet, sondern eine vorgegebene Zeit (in Milisekunden)
   //WaitForSingleObject(pi.hProcess,6000);



    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    //check to see if there is any data to read from stdout
   WaitForInputIdle(pi.hProcess, INFINITE);
    if (bread == 0)
    {
      bzero(buf);
      if (avail > 1023)
      {
        while (bread >= 1023)
        {
          ReadFile(read_stdout,buf,1023,&bread,NULL);  //read the stdout pipe
          printf("%s",buf);
          bzero(buf);
        }
      }
      else {
        ReadFile(read_stdout,buf,1023,&bread,NULL);
        printf("%s",buf);
        answerbuf += buf;
      }
    }
  }
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdin);            //clean stuff up
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
  CloseHandle(write_stdin);



  std::string fin_answerbuf;
  std::string::size_type qm = answerbuf.find("\r\n\r\n");
  if (qm != std::string::npos)
  {
    std::string url_params = answerbuf.substr(0, qm);

    fin_answerbuf = answerbuf.substr(qm+1);
  }


return fin_answerbuf;
}


Dieser Post wurde am 23.08.2005 um 13:54 Uhr von Skippy editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
24.08.2005, 00:48 Uhr
imhotep
followed the white rabbit


bin jetzt nicht ganz sicher, aber ich glaub, man muss, wenn man ein String-array verwendet, um ein programm zu starten und Parameter zu übergeben den letzten String als NULL angeben, damit die argc und argv der main-Funktion richtig erkannt werden. Zumindest ist das bei der glib-Funktion "g_spawn_async_with_pipes" so.


C++:
argv[0] = "c:\\php\\php-cgi.exe";
argv[1] = " C:\\Programme\\Jana2\\html\\index.php";
argv[2] = NULL;

flags = G_SPAWN_SEARCH_PATH;

Fehlermeldung = g_spawn_async_with_pipes (NULL, argv, NULL, flags, NULL, NULL, &child_pid,
                                                       &std_in, //Pipe für stdin
                                                       &std_output, //Pipe für stdout
                                                       &std_error, //Pipe für stderr
                                                       &g_error);



So sähe das in etwa bei glib aus und sicherlich ist dein Problem zumindest mit dem Programmaufruf auch hier angesiedelt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
24.08.2005, 08:52 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


was mir grad so auffällt:


C++:
BOOL CreateProcess(
  LPCTSTR lpApplicationName,
  LPTSTR lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL bInheritHandles,
  DWORD dwCreationFlags,
  LPVOID lpEnvironment,
  LPCTSTR lpCurrentDirectory,
  LPSTARTUPINFO lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);



lpApplicationName (bei dir NULL) sollte den Pfad zur Datei enthalten, eben z.b "c\php\\php-cgi2.exe"
lpCommandLine sind dann die Parameter in String-Form (also z.b "Param1 Param2 Param3")
ein letzter NULL-Parameter ist da nicht notwendig, das zerlegt windows für einen.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
24.08.2005, 14:44 Uhr
Skippy



aber genau das funktioniert ja halt nicht wenn ich bei createprozess
als ersten parameter die aufzurufende datei angebe
und als zweiten parameter den zu übergebenden parameter
in der form
char erster parameter[] = "c\php\\php-cgi2.exe";
char zweiter parameter[] = "C\Programme\\Jana2\\html\\index.php";
dann klappt das nicht die aufzurufende datei funktioniert nur wird der parameter nicht übertragen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
24.08.2005, 18:32 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja bei mir geht das:


C++:
argv[0] = "c: \\php\\php-cgi2.exe";
argv[1] = "c: \\Programme\\Jana2\\html\\index.php";


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: