初窥Unix系统编程
本书通过以下3个步骤来学习。
1. 分析程序
首先分析现有的程序,了解它的功能及实现原理
2. 学习系统调用
看程序都用到哪些系统调用,以及每个系统调用的功能和使用方法。
3. 编程实现
利用学到的原理和系统调用,自己编程实现原来程序所实现的功能。
以上3步可以通过下面3个问题来实现:
* 它能做什么?
* 它是如何实现的?
* 能不能自己编写一个?
作者以more的命令为例,说明了Unix系统编程其实并不是很难,但也不是很容易的事情。
/* more01.c - version 0.1 of more
* read and print 24 lines then pause for a few special commands
*/
#include <stdio.h>
#define PAGELEN 24
#define LINELEN 512
void do_more(FILE * );
int see_more();
int main(int ac, char *av[])
{
FILE *fp;
if (ac == 1)
do_more(stdin);
else
while (--ac)
if ((fp = fopen(*++av, "r")) != NULL)
{
do_more(fp);
fclose(fp);
}
else
exit(1);
return 0;
}
void do_more(FILE *fp)
/*
* read PAGELEN lines, then call see_more() for further instructions
*/
{
char line[LINELEN];
int num_of_lines = 0;
int see_more(), reply;
while (fgets(line, LINELEN, fp)) {
if (num_of_lines == PAGELEN) {
reply = see_more();
if (reply == 0)
break;
num_of_lines -= reply;
}
if (fputs(line, stdout) == EOF)
exit(1);
num_of_lines++;
}
}
int see_more()
/*
* print message, wait for response, return # of lines to advance
* q means no, space means yes, CR means one line
*/
{
int c;
printf("\033[7m more? \033[m"); /* reverse on a vt100 */
while ((c = getchar()) != EOF) /* get response */
{
if (c == 'q') /* q->N */
return 0;
if (c == ' ') /* ' ' => next page */
return PAGELEN; /* how many to show */
if (c == '\n') /* Enter key => 1 line */
return 1;
}
return 0;
}
/* more02c - version 0.2 of more
* read and print 24 lines then pause for a few special commands
* feature of version 0.2: reads from /dev/tty for commands
*/
#include <stdio.h>
#define PAGELEN 24
#define LINELEN 512
void do_more(FILE * );
int see_more(FILE * );
int main( int ac, char *av[] )
{
FILE *fp;
if ( ac == 1 )
do_more(stdin);
else
while(--ac)
if( (fp = fopen( *++av, "r" )) != NULL )
{
do_more( fp );
fclose( fp );
}
else
exit( 1 );
return 0;
}
void do_more( FILE *fp )
/*
* read PAGELEN lines, then call see_more() for further instructions
*/
{
char line[LINELEN];
int num_of_lines = 0;
int see_more(), 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 == PAGELEN ) {
reply = see_more(fp_tty);
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;
printf("\033[7m more? \033[m");
while( (c=getc(cmd)) != EOF )
{
if ( c == 'q' )
return 0;
if ( c == ' ' )
return PAGELEN;
if ( c == '\n' )
return 1;
}
return 0;
}