getchar spinnt?



  • Hi everyone

    Ich habe gerade versucht, mit getchar eine kleine Pause in mein Programm einzubauen. Das sieht dann wie folgt aus:

    printf("Warning! Serial communication is not secure!\nPress Ctrl-C to abort or [ENTER] to continue...\n");
    char cTmp = getchar();
    for(int j = 0; j < iWaitLimit && (iTmp = m_Ewb.rd_Data(blForceSem)) != 0; j++) {  // Read out requested meter's time...
       if(iTmp == -2) {  // No semaphore present
          printf("Warning! Serial communication is not secure!\nPress Ctrl-C to abort or [ENTER] to continue...\n");
          char cTmp = getchar();
          blForceSem = false;
       }
    }
    

    Ich habe für SIGINT und SIGTERM einen Signalhandler installiert, der mein Programm sauber beendet (unter anderem verwendete Semaphore löscht, etc.) - das nur, damit man aus dem printf-Text schlau wird 🙂 .

    Was mich jetzt so verwirrt: Beim ersten Aufruf, welchen ich zu Testzwecken eingebaut habe, klappt alles reibungslos (Ctrl-C ruft Signalhandler --> Programm beendet, Enter lässt es weiterlaufen).

    Ein paar Zeilen weiter, in der Schleife, ist das scheinbar plötzlich nicht mehr möglich. Erstens kann ich mit Ctrl-C nicht mehr beenden, zweitens wird von nun an alles, was ich auf der Konsole eintippe, nicht mehr angezeigt (auch wenn der Prozess bereits regulär terminiert hat). Um das wieder zu beheben, muss ich die Konsole (putty) neu starten. Die rd_Data()-Funktion im for-Konstrukt greift lediglich auf die serielle Schnittstelle zu und hat mit der Konsole eigentlich gar nichts zu schaffen.

    Wo kann da also der Fehler liegen?

    Vielen Dank für eure Hilfe und beste Grüsse
    Kessi



  • KessiMC schrieb:

    Wo kann da also der Fehler liegen?

    ...im Puffer der Standardeingabe.

    greetz, Swordfish



  • Ähmmm, das musst du mir jetzt genauer erklären 😕

    Muss ich 'was überprüfen oder in meinem Code ändern (Buffer flushen) oder wie jetzt 🙂 ?



  • Du darfst nich vergessen, daß bei Eingabe über eine Konsole

    a<return>
    

    auch das newline-Zeichen deinem Programm mit übergeben
    wird. In Unix ist das \n(ASCII 13) in WinDoof \r\n (ASCII 13,10)



  • Uuuppss. Ich meinte natürlich \n(ASCII 10)



  • Ähm, ok, aber das sollte getchar() doch checken? Ich meine, beim ersten Mal (vor der Schleife) kann ich auch ein dutzend Zeichen eingeben, getchar() nimmt dann einfach das erste (Habe mit getchar() auch schon in einem separeten Programm ein wenig gespielt).

    Da dürfte das mit dem Zeilenumbruch getchar() nicht wirklich aus der Fassung bringen, oder?



  • Bedeutet, dass mein Thread immer weiter nach unten rutscht, etwa, dass es für dieses Verhalten von getchar() keine logische Erklärung gibt 😞 ?

    Das wäre beunruhigend...



  • KessiMC schrieb:

    Ähm, ok, aber das sollte getchar() doch checken? Ich meine, beim ersten Mal (vor der Schleife) kann ich auch ein dutzend Zeichen eingeben, getchar() nimmt dann einfach das erste

    Richtig! Aber jeder Folgeaufruf von getchar() liefert
    dir dann eben die verbleibenden (+ newline-Sequenz).

    Was ist an diesem Verhalten seltsam?



  • Java-Progger schrieb:

    Richtig! Aber jeder Folgeaufruf von getchar() liefert
    dir dann eben die verbleibenden (+ newline-Sequenz).

    Was ist an diesem Verhalten seltsam?

    Ja, ok, ich nehme an, diesbezüglich macht getchar() seine Arbeit schon ordentlich. Meine grosse Schwierigkeit zeigt sich ja in obigem Code. Beim ersten Aufruf von getchar() klappt alles reibungslos, man kann entweder ENTER drücken, um fortzufahren (ob der User da noch welche Zeichen eingetippt hat, stört mich nicht weiter) oder mit Ctrl-C den Signalhandler laden und das Programm beenden.

    In der Schleife funktioniert das mit genau demselben Code aber nicht mehr :(, auch nicht, wenn ich etwa den getchar()-Aufruf vor der Schleife weglasse. Zum einen kann der Signalhandler mit Ctrl-C nicht mehr gestartet werden, zum andern werden die eingetippten Zeichen nicht mehr angezeigt (nicht 'mal mehr, wenn das Programm beendet und man zurück in der Shell ist).

    Erst, wenn ich mein Terminal-Programm (putty) neu starte und mich neu einlogge, verschwinden diese Effekte wieder.

    Ich kann mir nicht erklären, was das soll, aber ich weiss, dass es mir mittlerweile tierisch auf den Senkel geht 😡 .

    Thx für jede Hilfe und greeetz
    Kessi



  • Mit Strg+C zerschießt du dir ja auch die Eingabe-Konsole stdin. Da solltest du dir vielleicht einen etwas sanfteren Weg suchen, um dem Programm mitzuteilen, daß du fertig bist 😉



  • CStoll schrieb:

    Mit Strg+C zerschießt du dir ja auch die Eingabe-Konsole stdin. Da solltest du dir vielleicht einen etwas sanfteren Weg suchen, um dem Programm mitzuteilen, daß du fertig bist

    Okeee, aber das Problem (Zeichen werden nicht mehr angezeigt) tritt auf, egal ob ich Ctrl-C drücke oder Enter, um fortzufahren. Des Weiteren zeigt Ctrl-C ja gar keinen Effekt, das Programm wird ausgeführt als ob ich ENTER gedrückt hätte - das ist ja gerade das Problem...

    Langsam bin ich mit meinem Latein am Ende 😞 .



  • Oookay, nun ist der Fehler endlich 'raus. Meine rd_Data()-Funktion greift auf die serielle Schnittstelle zu und hat das zum Teil nicht ganz sauber gemacht. Unter anderem hat sie mit tcsetattr() Einstellungen an nicht definierten Portdeskriptoren (z.B. 0, -1) vorgenommen. Das hat die Konsole so aus dem Gleichgewicht geworfen.

    Ich hatte erwartet, dass diese Fälle abgefangen würden, da nie Probleme aufgetreten sind. Stattdessen fange ich sie nun selber ab und alles läuft wieder prima 🙂 .

    Vielen Dank auf jeden Fall für eure Unterstützung und beste Grüsse
    Kessi



  • Die "undefinierten Portdescriptoren" (genauer gesagt die Descriptoren 0, 1 und 2) sind die Konsole. Wenn Du da z.B. Echo o.ä. abschaltest, ist klar dass Du Deine Eingaben nicht mehr siehst 😉


Anmelden zum Antworten