linux动态获取终端窗口的大小方法(代码测试 )

通过函数signal();接受SIGWINCH信号 每次接收到信号,打印屏幕的大小

/*
*   通过函数 ioctl(); 获得终端界面的参数
*   @author 李政 <[email protected]>
*/
#include <termios.h>
#include <stdio.h>
#include <errno.h>

#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#endif

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include "my_err.h"

//打印函数
static void pr_winsize(int fd)
{
    //定义一个结构体变量 size
    struct winsize size;

    //返回值判断
    if(ioctl(fd, TIOCGWINSZ, (char *)&size) < 0)
    {
        err_sys("TIOCGWINSZ error");
    }

    //每次接收到信号打印 行、列数
    printf("%d rows, %d columns\n", size.ws_row, size.ws_col);

}

//signal 的函数
static void sig_winch(int signo)
{
    printf("SIGWINCH received\n");
    pr_winsize(STDIN_FILENO);
}

int main(void)
{
    //首先通过 isatty();函数判断文件描述符是否为终端机
    if( isatty(STDIN_FILENO) == 0 )
    {
        exit(1);
    }
    //接受 SIGWINCH 信号
    if(signal(SIGWINCH, sig_winch) == SIG_ERR)
    {
        err_sys("signal error");
    }
    //首先打印窗口的size
    pr_winsize(STDIN_FILENO);    /* print initial size */

    //循环接受程序不能死
    for(;;)                /* and sleep forever */
        pause();
}

err_sys以及err_quit等函数不是C语言自带函数,是作者自己编写的函数。所以,想要运行书中的源代码,就必须自建一个头文件my_err.h把代码拷贝进去,然后在程序中加载。

#include <errno.h> /* for definition of errno */
#include <stdarg.h> /* ISO C variable aruments */
#include <string.h>
static void err_doit(int, int, const char *, va_list);
#define MAXLINE 255
/*
 * Nonfatal error related to a system call.
 * Print a message and return.
 */
void err_ret(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    err_doit(1, errno, fmt, ap);
    va_end(ap);
}


/*
 * Fatal error related to a system call.
 * Print a message and terminate.
 */
void err_sys(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    err_doit(1, errno, fmt, ap);
    va_end(ap);
    exit(1);
}


/*
 * Fatal error unrelated to a system call.
 * Error code passed as explict parameter.
 * Print a message and terminate.
 */
void err_exit(int error, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    err_doit(1, error, fmt, ap);
    va_end(ap);
    exit(1);
}


/*
 * Fatal error related to a system call.
 * Print a message, dump core, and terminate.
 */
void err_dump(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    err_doit(1, errno, fmt, ap);
    va_end(ap);
    abort(); /* dump core and terminate */
    exit(1); /* shouldn't get here */
}


/*
 * Nonfatal error unrelated to a system call.
 * Print a message and return.
 */
void err_msg(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    err_doit(0, 0, fmt, ap);
    va_end(ap);
}


/*
 * Fatal error unrelated to a system call.
 * Print a message and terminate.
 */
void err_quit(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    err_doit(0, 0, fmt, ap);
    va_end(ap);
    exit(1);
}


/*
 * Print a message and return to caller.
 * Caller specifies "errnoflag".
 */
static void err_doit(int errnoflag, int error, const char *fmt, va_list ap)
{
    char buf[MAXLINE];
   vsnprintf(buf, MAXLINE, fmt, ap);
   if (errnoflag)
       snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s",
         strerror(error));
   strcat(buf, "\n");
   fflush(stdout); /* in case stdout and stderr are the same */
   fputs(buf, stderr);
   fflush(NULL); /* flushes all stdio output streams */
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42205987/article/details/82081068