Konsolen Infos holen ( Linux )



  • Wie kann ich zu Laufzeit in einem C.Programm abfragen, wie die Auflösung in der Konsole eingestellt ist ?
    Anzahl Zeichen pro Spalte/Zeile.
    Oder noch besser, wie kann ich es abfangen, wen die Konsolengrösse zur Laufzeit geändert wird ?
    ZB. so wie es "htop" macht, sobald ich die Grösse des Fensters ändere, wir der Inhalt des Fenster angepasst.



  • Das einfachste wäre es wohl eine library zu nutzen wie ncurses.
    htop z.b. verwendet ncurses



  • Am besten liest Du Dir das NCURSES-Programming-HOWTO durch.



  • Die Frage, die sich hier stellt, ist natürlich... woher bezieht ncurses seine Infos? 🤔


  • Mod

    Auf unterster Ebene passieren das ioctl calls gegen das Terminal. Zum Beispiel TIOCGWINSZ um die Terminalgröße abzufragen.

    Könnte ungefähr so aussehen:

    #include <sys/ioctl.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main() 
    {
    	struct winsize ws;
            ioctl(STDIN_FILENO, TIOCGWINSZ, &ws);
    
    	printf("Zeilen: %d\n", ws.ws_row);
    	printf("Spalten: %d\n", ws.ws_col);
    }
    


  • Du kannst das SIGWINCH Signal abfangen um zu erfahren, wann sich die Größe ändert. Um an die Größe zu kommen, kannst du den TIOCGWINSZ ioctl command auf einen file descriptor des Terminals verwenden:

    struct winsize size;
    ioctl(STDIN_FILENO, TIOCGWINSZ, &size); // beispielhaft stdin
    // size.ws_row Anzahl der Reihen
    // size.ws_col Anzahl der Spalten
    


  • Dank eurer Hilfe und Google bin ich auf folgendes gekommen.
    Wen man weis wie, recht simpel.

    #include <stdio.h>
    #include <sys/ioctl.h>
    #include <unistd.h>
    #include <signal.h>
    
    void sig_winch(int in)
    {
        struct winsize w;
    
        ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
        printf("w = %d, h = %d\n", w.ws_col, w.ws_row);
    }
    
    int main()
    {
        signal(SIGWINCH, sig_winch);
        getchar();
    }
    
    

  • Mod

    Sei aber vorsichtig, was du da in dem Handler machst. Das kann jederzeit aufgerufen werden. Beispielsweise während dein Programm eine andere Ausgabe macht, und du diese in deinem Beispiel mit deinem printf munter unterbrichst. Meistens beschränkt man sich darauf, dass man im Handler ein globales Flag setzt, und dann an einer sicheren Stelle prüft, ob man reagieren muss.

    PS: Wenn du da größere Konsolenpläne hast, als nur genau diese eine Sache abzufragen, guck dir unbedingt eines der High-Level Frameworks (wie das genannte curses) an. Sonst programmierst du dir einen Wolf mit den ganzen kryptischen Terminalbefehlen und Steuerzeichen. Und musst alles 100x für verschiedene Terminals programmieren, die alle ein kleines bisschen anders funktionieren, wenn du möchtest, dass dein Programm auch anderswo läuft (und viel Spaß dabei, herauszufinden, welches Terminal genau was und wie unterstützt).



  • @SeppJ sagte in Konsolen Infos holen ( Linux ):

    Sei aber vorsichtig, was du da in dem Handler machst. Das kann jederzeit aufgerufen werden. Beispielsweise während dein Programm eine andere Ausgabe macht, und du diese in deinem Beispiel mit deinem printf munter unterbrichst.

    Dann werde ich wohl mit dem gleichen Problem konfrontiert werden, wie bei Multithreading-Programmen. Da gibt es auch Probleme, wen mehrere Threads auf die Konsole schreiben. Dann muss ich wohl auch mit Semaphores arbeiten, wen es mehr werden soll als nur ein HelloWorld.


Anmelden zum Antworten