How to get windows size from Linux

2019-06-06 02:31发布

问题:

everyone. I am still new to programming. I really need some help about the issues that I'm facing. So, the situation here is I'm trying to display a warning when the terminal size is below 80x24. For the record, my Os is Window, but I'm using a virtual machine to run Linux because all the files are in Linux. When i run the file using terminal, the warning display correctly. But the problem is when i try to run the file from Windows using PuTTY. The warning did not appear. I'm sure its because the function that I'm using can only read the Linux environment and not the Windows. Can anyone help me or point me to a direction on how to make it capable of getting the dimension of windows. The files should all remain in Linux. I am using C.

Here are just some part of the code to show about displaying warning and getting dimension.

//This is to display warning


int display_warning()
{
 CDKSCREEN *cdkscreen = 0;
 WINDOW *cursesWin    = 0;
 char *mesg[5];
 char *buttons[] = {"[ OK ]"};
 CDKDIALOG *confirm;

 cursesWin = initscr();
 cdkscreen = initCDKScreen (cursesWin);

 initCDKColor();

 mesg[0] = "</2>"The size of Window must be at least 80x24.";
 confirm = newCDKDialog(cdkscreen, CENTER, CENTER, mesg, 1, buttons, A_REVERSE, TRUE,TRUE, FALSE);
 setCDKDialogBackgroundColor(confirm, "</2>");
 injectCDKDialog(confirm,TAB);
 activateCDKDialog(confirm,0);

 if (confirm -> exitType == vNORMAL){
 destroyCDKDialog (confirm);
 destroyCDKScreen (cdkscreen);
 endCDK();
 }
 return 0;
}



//This is to get the dimension

int get_terminal_size()
{
 int cols;
 int lines;

 #ifdef TIOCGSIZE
 struct ttysize ts;
 ioctl(0,TIOCGSIZE, &ts);
 lines = ts.ts_linesl;
 cols = ts.ts_cols;

 #elif defined(TIOCGWINSZ)
 struct winsize ts;
 ioctl(0, TIOCGWINSZ, &ts);
 lines = ts.ws_row;
 cols = ts.ws_col;

 #endif

 if((lines <= 23)||(cols <= 79)){
 display_warning();
 }

 return 0;
}

//then there will be the main function that i think is not necessary to put the code here.

All comment and help are very appreciated. I am a beginner in programming, so please excuse me if there are some basic things that i dont know.

Fikrie

回答1:

The issue has nothing to do with PuTTY per se, and everything to do with SSH clients and pseudoterminals in general.

To avoid this issue, configure your PuTTY to use a pseudoterminal. (In the TTY panel, there is a "Don't allocate a pseudoterminal" checkbox. Make sure it is not checked.)

With ssh, you need to use the -t option to tell ssh to use a pseudoterminal.

Here is a simple example program you can use in Linux to obtain the terminal size. It does not require curses:

#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>

static int get_size(const int fd, int *const rows, int *const cols)
{
    struct winsize sz;
    int            result;

    do {
        result = ioctl(fd, TIOCGWINSZ, &sz);
    } while (result == -1 && errno == EINTR);
    if (result == -1)
        return errno;

    if (rows)
        *rows = sz.ws_row;

    if (cols)
        *cols = sz.ws_col;

    return 0;
}

int main(void)
{
    int rows, cols;

    if (!get_size(STDIN_FILENO,  &rows, &cols) ||
        !get_size(STDOUT_FILENO, &rows, &cols) ||
        !get_size(STDERR_FILENO, &rows, &cols))
        printf("%d rows, %d columns\n", rows, cols);
    else
        fprintf(stderr, "Terminal size is unknown.\n");
    return 0;
}

The actual information is obtained using the TIOCGWINSZ TTY ioctl.

The pseudoterminal size is actually maintained by the kernel. If there is no pseudoterminal, just standard streams, there are no rows and columns; it's just a stream in that case. In particular, even tput lines and tput cols will fail then.

Many interactive command-line programs will refuse to work if there is no pseudoterminal. For example, top will report something like "TERM environment variable not set" or "top: failed tty get". Others will work, just not interactively; they'll output once only, but as if the terminal was infinitely tall and infinitely wide.

In summary, your application should recognize whether it is running in a pseudoterminal (with terminal size known, curses support possible, and so on), or in stream mode (via SSH or PuTTY, deliberately without a pseudoterminal -- or perhaps just because inputs and outputs are all directed to/from files or some such).



标签: c linux ioctl