ncurses funktionen nicht reentrant?



  • ich habe hier zwei threads von denen einer ein ncurses window verwaltet. damit der ncurses-thread texte sofort ausgibt, wird ein signal geschickt. der signal-handler holt sich den text ab und gibt ihn aus. (alle texte werden über pipes verschickt, weshalb alle objekte thread-lokal sind)

    funktion für alle ausgaben:
    void Curses::print(const std::string& str)
    {
    waddstr(output_, str.c_str());
    wrefresh(output_);
    }

    das funktioniert allerdings nicht. es funktioniert allerdings sobald man folgende änderung einfügt:

    void Curses::print(const std::string& str)
    {
    waddstr(output_, "xxxxx\n");
    wrefresh(output_);
    }

    wtf? 😡
    ich bin mit meinem latein komplett am ende, vor allem weil sich die ncurses-dokumentation aussschweigt, was das thema reentrancy angeht. 😡

    ich habe versucht das verhalten in einem kleinen testprogramm festzuhalten, allerdings passieren hier auch nur wieder sonderbare dinge: die eingabe wird abgebrochen, sobald man bis zum signal nichts eingegeben hat.

    WINDOW* a;
    WINDOW* b;
    
    void sigfun(int)
    {
    	const char str[] = "<sighandler>\n";
    	waddstr(a, str);
    	wrefresh(a);
    }
    
    int main()
    {
    	sys::signal(SIGALRM, &sigfun);
    	initscr();
    
    	a = newwin(LINES -1, COLS, 0, 0);
    	b = newwin(1, COLS, LINES -1, 0);
    
    	const char str1[] = "string1\n";
    	const char str2[] = "string2\n";
    
    	char c;
    
            waddstr(a, str1);
    	alarm(1);
    	wgetnstr(b, &c, 1);
    	waddstr(a, str2);
    	wrefresh(a);
    	wrefresh(b);
    
    	pause();
    	endwin();
    }
    

    ich hoffe ihr könnt mir helfen!



  • sys::signal emuliert übrigens nur ::signal mit einem sigprocmask-aufruf, damit der signal-handler garantiert installiert bleibt.



  • Hallo!

    Hast du schon versucht den string in einem Buffer zu speichern bevor du ihn mit *addstr() ausgibst!

    void Curses::print(const std::string& str)
    {
    
    char buf[MAX_LENGTH+1];
    
    strncpy(buf, str.c_str(), MAX_LENGTH);
    
    waddstr(output_, buf);
    wrefresh(output_);
    }
    

    Vielleicht kannst du so die Fehlerquelle einengen und herausfinden, ob es am string oder an der (n)curses Funktion liegt.

    Gruß
    Michael



  • es liegt an ncurses. mit einem char buffer funktioniert es nicht. außerdem enthält der string definitiv das, was ich in die pipe geschrieben habe. (wenn ich den inhalt testweise vor *addstr in eine datei schreiben lasse, sehe ich, dass der string die richtigen daten enthält).


Anmelden zum Antworten