Linux开发习作】more命令的编写(2)

简介:

可以根据终端大小自动调整输出,并且修正了上一个版本的一些小bug,更加贴近现在Linux用的More。

/*
* =====================================================================================
*
* Filename: more02.c
*
* Description: A User Version of Command more
*
* Version: 2.0
* Created: 12/03/2008 06:36:56 PM
* Revision: none
* Compiler: gcc
*
* Author: Futuredaemon (BUPT), futuredaemon@gmail.com
* Company: BUPT_UNITED
*
* =====================================================================================
*/

#include 
#include 
#include 
#include 
#include 

#define LINELEN 512 /*The length of Line to be printed */

void do_more(FILE *);
int see_more(FILE *);
void noneprint(int); /* To control the terminal echo */
static void sig_winch(int);
static void pr_winsize(int);

struct winsize size;

int main ( int argc, char *argv[] )
{
FILE *fp; /* File Descriptor */
if(signal(SIGWINCH,sig_winch)==SIG_ERR)
perror("Signal Error");
pr_winsize(1);
if ( argc ==1 ) /* If no files exist,use the keyboard */
do_more(stdin); 
/* Through this method,a program may support pipe '|' */
else
while(--argc)
if((fp=fopen(*++argv,"r"))!=NULL)
{
do_more(fp);
fclose(fp);
}
else
exit(1);
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */

void do_more(FILE *fp)
{
char line[LINELEN];
int num_of_lines=0;
int reply;
FILE *fp_tty;
fp_tty = fopen( "/dev/tty" , "r");
if (fp_tty==NULL)
exit(1);

while(fgets( line,LINELEN,fp))
{
if( num_of_lines == (size.ws_row-2))
{
reply = see_more(fp_tty);
noneprint(0);
if( reply == 0)
break;
num_of_lines-=reply;
}

if( fputs (line,stdout)==EOF)
exit(1);
num_of_lines++;
}

}

int see_more(FILE *cmd)
{
int c;
system ("stty -F /dev/tty cbreak");/*打开/dev/tty作为输入终端,并且控制属性为不需要回车*/
printf("/033[7m more? /033[m");
noneprint(1);
while((c=getc(cmd))!=EOF)
{
if(c == 'q')
{
printf("/n");
return 0;
} 
if(c == ' ')
{
//printf("/033[2J"); 
printf("/n");
return size.ws_row;
}
if(c == '/n')
{
printf("/33[7D/33[K"); 
return 1;
}
}
system ("stty -F /dev/tty -cbreak");/*恢复终端属性为需要回车*/
return 0;
}

void noneprint(int flag)
{
struct termios init_setting;
struct termios pend_setting;

if (tcgetattr(1, &init_setting) < 0)
{
perror("Getting the attribute Error!");
exit (1);
}
pend_setting = init_setting;
if(flag==1)
pend_setting.c_lflag &= ~ECHO;
else
pend_setting.c_lflag |= ECHO;
tcsetattr (1, TCSANOW, &pend_setting);
}

static void pr_winsize(int fd)
{
if(ioctl(fd,TIOCGWINSZ, (char *)&size)<0)
perror("TIOCGWINSZ Error!");
}

static void sig_winch(int signo)
{
pr_winsize(1);
} 

本文转自gnuhpc博客园博客,原文链接http://www.cnblogs.com/gnuhpc/archive/2012/01/13/2321369.html,如需转载请自行联系原作者
相关文章
|
12天前
|
运维 安全 Linux
Linux中传输文件文件夹的10个scp命令
【10月更文挑战第18天】本文详细介绍了10种利用scp命令在Linux系统中进行文件传输的方法,涵盖基础文件传输、使用密钥认证、复制整个目录、从远程主机复制文件、同时传输多个文件和目录、保持文件权限、跨多台远程主机传输、指定端口及显示传输进度等场景,旨在帮助用户在不同情况下高效安全地完成文件传输任务。
104 5
|
12天前
|
Linux
Linux系统之expr命令的基本使用
【10月更文挑战第18天】Linux系统之expr命令的基本使用
48 4
|
2天前
|
Linux Shell 数据安全/隐私保护
|
3天前
|
域名解析 网络协议 安全
|
10天前
|
监控 Linux Shell
|
9天前
|
运维 监控 网络协议
|
13天前
|
Unix Linux
Linux | Rsync 命令:16 个实际示例(下)
Linux | Rsync 命令:16 个实际示例(下)
26 3
Linux | Rsync 命令:16 个实际示例(下)
|
16天前
|
安全 Linux
Linux系统之lsof命令的基本使用
【10月更文挑战第14天】Linux系统之lsof命令的基本使用
71 2
Linux系统之lsof命令的基本使用
|
1天前
|
Linux 开发工具
linux文本管理命令
本文档介绍了Linux系统中常用的文本处理命令,包括`echo`、`cat`、`head`、`tail`、`wc`、`less`、`grep`以及重定向符号的使用方法和练习题。此外,还详细讲解了VIM编辑器的特点、工作模式、常用快捷键和高级技巧,帮助用户高效地进行文本编辑和处理。
17 4
|
18天前
|
Linux
Linux 系统五种帮助命令的使用
Linux 系统五种帮助命令的使用
37 14