Why the function tgetnum("co") does not update every time I resize the terminal?

147 Views Asked by At

I have a global variable called g_data that holds a pointer to a structure which contains, among many, two variables to hold the height and width of the terminal. The function signalhandler below checks whether the terminal has been resized. In that case, the function update_data changes the values of those two variables to the current height and width of the terminal.

My problem is that the function tgetnum, whenever it's being called, it doesn't seem to get the current terminal size (after the resizing).

I'm using Ubuntu 18.04LTS

typedef struct  s_data
{
    t_lst   *lst;
    t_ldim  ldim;
    t_pos   pos;
    int     height;
    int     width;
    int     max;
    int     lstsize;
}               t_data;

int i = 0;

void    signalhandler(int sig)
{

    if (sig == SIGWINCH)
    {
        update_data(g_data);
        if (g_data == NULL)
            exit(EXIT_FAILURE);
        enable_cap("ti");
        print_args(g_data);
        printf("%d - %d\n", i++, tgetnum("co"));
        signal(SIGWINCH, signalhandler);
    }
    else if (sig == SIGTSTP)
    {
        signal(SIGTSTP, SIG_DFL);
        modify_main_caps(SET);
        enable_cap("te");
        ioctl(0, TIOCSTI, "\032");
    }
    else if (sig == SIGCONT)
    {
        signal(SIGTSTP, signalhandler);
        modify_main_caps(UNSET);
        update_data(g_data);
        enable_cap("ti");
        print_args(g_data);
    }
}
1

There are 1 best solutions below

3
Paul Ogilvie On

Looking up tgetnum in Linux man pages, it says:

These routines are included as a conversion aid for programs that use the termcap library. Their parameters are the same and the routines are emulated using the terminfo database. Thus, they can only be used to query the capabilities of entries for which a terminfo entry has been compiled.

Looking up terminfo in man, it says:

Terminfo is a data base describing terminals, used by screen-oriented programs...

Because it is a database, there is no dynamic updating. It only gets the statically defined information from the database for your current terminal.


Update:

Googling around I found http://man7.org/tlpi/code/online/dist/tty/demo_SIGWINCH.c.html which sets a SIGWINCH handler and then uses ioctl to get the updated size, roughly:

struct winsize ws;
ioctl(STDIN_FILENO, TIOCGWINSZ, &ws);
printf("Caught SIGWINCH, new window size: "
            "%d rows * %d columns\n", ws.ws_row, ws.ws_col);