Hi Leute!

Sorry, daß ich schon wieder 'nen neuen Thread aufmache. Ist nur, um euch den aktuellen Stand mitzuteilen und meine Probleme neuerlicherweise auf den Punkt zu bringen. Ich versuche hier nochmal alles, was ich weiß und nicht weiß zusammen zu fassen, auf daß wir in Zukunft in diesem Thread alles finden, was dieses Thema betrifft. Damit ich nicht noch mehr Threads aufmachem muss...

Für alle, die meine anderen Threads nicht verfolgt haben, zusammenfassend:

Ich baue in eines meiner Programme einen Telnet-Server ein, der die Fähigkeiten der Readline/History-Bibliotheken in sich vereinen soll. Quasi ein vollwertiges Terminal innerhalb meines Programms, zur Steuerung desselbigen per Telnet Client (Putty o.ä.).

Ich habe bereits den Socket erstellt, verbinden darauf ist möglich, Eingabe von Kommandos auch. Desweiteren habe ich das Pseudo-Terminal zwischen dem Socket und der GNU Readline Funktion erstellt.

Das ganze funktioniert in der Theorie folgendermaßen:
Jemand verbindet sich mit einem Telnet Client auf den Socket (bei mir TCP Port 6700). Im Eingangsbereich des Sockets (Überwachung des Sockets auf eingehende Daten) wird erstmal überprüft, ob es sich bei dem eingehenden Character um ein 0xFF handelt. Ist das der Fall, werden die nächsten zwei Bytes eingelesen und als Telnet Command interpretiert (siehe entsprechendes RFC). In allen anderen Fällen werden die Character ohne Änderung an die Slave-Seite des Pseudoterminals weitergegeben.

Auf die Eingabe auf Slave-Seite reagierend kommt das eingegebene Zeichen laut definition auf der anderen, der Master-Seite wieder heraus. Signalisiert die Master-Seite des Pseudo Terminals ein eingehendes Zeichen, wird es 1:1 an die Readline Funktion weitergegeben. Readline ist hier als Callback implementiert, da auch andere Schnittstellen ständig gepollt werden müssen und keine blockierende Funktion aufgerufen werden darf, solange keine Daten zur Verfügung stehen. Daher wird bei eingehenden Zeichen auf der Master-Seite des Pseudo Terminals auch per rl_callback_read_char das Zeichen eingelesen.

So viel zum funktionierenden Teil meines Programms.

Meine Probleme sind die folgenden, bei denen ich euch dringend darum bitte, mir zu helfen, weil Google sich wie in den meisten Fällen meiner Probleme massiv ausschweigt:

Ich habe dem Telnet Client per Telnet Kommandos DO SUPPRESS-GO-AHEAD und WILL ECHO mitgeteilt, daß er jedes eingegebene Zeichen einzeln sofort nach Eingabe an den Server schicken soll. Das funktioniert noch nicht. Der Client schickt immer noch erst nach drücken der RETURN/ENTER-Taste.

Auf einen Druck der RETURN/ENTER-Taste hin überträgt der Client den gesamten eingegebenen String inklusive der Steuerzeichen CR (0x0D) und eines NL (0x0A). Diese werden auch 1:1 an das Pseudo Terminal weitergegeben, da es sich dabei ja nicht um Telnet Steuerzeichen (0xFF) handelt. Das PTY (Pseudo Terminal) schickt diese dann 1:1 weiter an Readline. Readline scheint aber mit 0x0A nichts anfangen zu können, blockiert an der Stelle. Ich kann mir nur vorstellen, daß das PTY irgendwas mit dem 0x0A anstellt, daß es zwar rausgeht auf die Slave Seite, auf der Master Seite auch signalisiert, aber dennoch per read() nicht lesbar ist (ReadLine verwendet read()). Das gleiche gilt für Steuerzeichen, die ReadLine für die History benötigt (Cursor rauf/runter). Diese Steuerzeichen, durch das PTY an ReadLine geschickt bewirken ebenfalls, daß das read() in rl_callback_read_char() blockiert.

Meine Fragen, die aus obigen Problemen resultieren, lauten nun wie folgt:

Welche Kommandos muss ich zusätzlich zu DO SUPPRESS-GO-AHEAD und WILL ECHO noch an den Telnet Client schicken, bevor irgendwelche Eingaben/AUsgaben gemacht werden, bzw. auf welche Kommandos muss ich definitiv reagieren?

Welche Einstellungen (Canonical, Echo, Terminaltype etc.) per termios/tcsetattr muss ich auf welcher Seite des PTY vornehmen, damit das beschriebene Konstrukt Socket->SlavePTY->MasterPTY->ReadLine funktioniert?

Ist das beschriebene Konstrukt Socket->SlavePTY->MasterPTY->ReadLine überhaupt die richtige Vorgehensweise? Wie wird es sonst gemacht, wenn nicht so?



Vielen Dank für eure Mühen!

Grüße,
Hendrik