容纳操作系统的内存空间叫做系统空间,容纳应用程序的内存空间叫做用户空间
系统资源:处理器,输入输出,进程管理,内存,设备,计时器,进程间通信,网络
(1)它能做什么? ·分析程序」
(2)它是如何实现的? ·学习系统调用」
(3) 能不能自己写一个? ·编程实现」unix能做些什么?
(用户角度):登录(一个用户有一个shell进程,有这个进程来处理用户的请求),运行程序,注销,目录操作,文件操作,文件权限
(系统角度):通信,协作,网络访问date:日期 fortune: 随机出现一个诗句
ls , cd , pwd , mkdir , rmdir
cat,more,less,pg –查看文件内容 , cp , rm , mv , lpr(打印文件) , lp
bc:计算器,可以处理很大的数,可编程的(类似C语言语法),(内部通过调用真正的计算机dc来实现,bc是dc的预处理器,类似于浏览器与服务器的关系)
more01.c
#include<stdio.h>
//#include <stdlib.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)//有ac个文件,轮流处理
{
if((fp=fopen(*++av,"r"))!=NULL)//只读方式打开地文件
{
do_more(fp);//成功打开一个文件则进行处理处理
fclose(fp);
}
else
exit(1);//不成功打开则退出
}
return 0;
}
void do_more(FILE *fp)//处理文件的函数
{
char line[LINELEN];//缓冲区
int num_of_lines=0;屏幕中已显示的行数
int see_more(),reply;
while(fgets(line,LINELEN,fp)){//从文件中欧你读取一行,读到文件结束符则退出
if(num_of_lines==PAGELEN){//从0开始,如果已输出的行数等于24
reply=see_more();//则停止输出,等待用户输入命令getchar()
if(reply==0)
//如果see_more()返回值是0则推出,(输入了q或终止信号)
break;
num_of_lines-=reply;//已输出行数减少一行,继续读取文件
}
if(fputs(line,stdout)==EOF)
exit(1);
num_of_lines++;//每显示一行自增1
}
}
int see_more()//输出满 PAGELEN 行后等待处理用户的命令
{
int c;
printf("\003[7m more? \003[m");//在最低行输出提示信息
while((c=getchar())!=EOF)//获取用户输入的命令
{
if(c=='q')
return 0;
if(c==' ')
return PAGELEN;
if(c=='\n')
return 1;
}
return 0;
}
存在的问题:
(1) 最低端的旧的提示信息more? 会随着屏幕向上滚
(2) 按下空格键或‘q’后需要按回车程序才会继续执行
(3) 执行命令 ls /bin | ./more01 ,结果并不是我们想象的会每24行,分页显示,而是一次性将 ls /bin 所有的结果输出
第三个问题原因是: 管道 | 已经将more01的标准输入重定向到了标准输出,而more01使用getchar() ,它是从标准中读取数据的,所以ls /bin 将结果直接作为more01的输入,没有用户的什么事。
解决这个问题的办法就是:
(1)从标准输入中获取要分页的数据;
(2)从/dev/tty获取用户的输入
/dev/tty是显示器和键盘的设备描述文件,向这个文件写入数据会输出到显示器,而从中读取会从键盘中读取
more02.c
#include<stdio.h>
#include<stdlib.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)
{
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("\003[7m more? \003[m");
while((c=getc(cmd))!=EOF)//输入来源是键盘getc(cmd),而不是getchar()
{
if(c=='q')
return 0;
if(c==' ')
return PAGELEN;
if(c=='\n')
return 1;
}
return 0;
}