20135219洪韶武——信息安全系统设计基础第十周学习总结
1.I/O重定向
【重定向其实是unix系统优越性的一种体现(与管道相似);将一种操作的结果重定向到另外一种操作上,这样的思想保证了“专务专用”,将单个操作做到极致,又为用户自己提供了完善功能的平台(比如重定向,比如管道)。】 - unix外壳提供了I/O重定向操作符,允许用户将磁盘文件和标准输入输出连接起来。例如:
ls > foo.txt;
使得外壳加载和执行ls程序,将标准输出重定向到foo.txt。
-
工作方式:
#include <unistd.h> int dup2(int oldfd,int newfd);
拷贝描述符表项oldfd到描述符表项newfd,同时覆盖掉newfd之前的内容。如果newfd已经打开,就先关闭newfd再进行操作。
-
调用dup2(4,1)示例:
前提:假设描述符1(标准输出)对应于文件A,4对应于文件B,A和B的引用计数等于1.
过程:两个描述符都指向文件B,文件A已经被关闭,它之前对应的文件表和v-node也已经被删 除;文件B的引用计数增加,之后的任何标准输出(描述符1)的数据都被重定向到文件B。
2.标准I/O库
【之前的输入输出函数并没有特定性,而是适用于通常情况下的I/O;标准I/O库针对I/O的具体情况,分类给出了特定的I/O函数;从一定角度而言,是“高级”的I/O函数。另外,与此相关的“流”的概念是和指针很相似的,也是一种“抽象”。】
-
总述:这个库提供了unixI/O较高级别的替代。
-
类型:
- 打开和关闭文件的函数(fopen和fclose);
- 读和写字节的函数(fread和fwrite);
- 读和写字符串的函数(fgets和fputs)
-
流的应用: 一个流就是指向一个FILE类型的结构的指针(比如,每有一个ASNI C文件打开,都会同时打开STDIN,STDOUT,STDERR三个流)。
- 含义:流是对文件描述符和流缓冲区的抽象。(流缓冲区的目的和RIO类似,就是减少开销较高的unix系统调用的数量)
3.关于输入与输出函数的一些矛盾点
【C语言编程的时候,经常会因为输入域输出交叉调用导致输入或者输出函数不能取到想要的值】
-
输入函数不能紧跟在输出函数之后——如果输出函数之后没有加上fflush,fseek,fsetpos等。前者是清空与流相关的缓冲区;后两者用lseek函数重置当前的文件位置;
-
输出函数不能紧跟在输入函数之后——如果输入函数之后没有fseek,fsetpos,rewind等。
4.基于错误处理包装函数
-
思想:给定的基本级系统函数foo,我们有相同参数的、函数名大写的包装函数Foo;包装函数调用基本函数并检查错误。如果发现了错误,包装函数就终止进程并返回一条信息;当基本函数无误的时候,包装函数就返回调用者。(包装函数被封装在源文件csapp.c中)
5.unix系统中的错误处理
-
unix风格:例如fork函数和外套函数,返回值既包括错误代码,又包括有用的结果。
if((pid = wait(NULL))<0) { fprintf(stderr,"wait error:%s\n",strerror(errno));//将errno设置为指向错误原因的代码 exit(0); }
-
Posix风格:例如pthread,函数只返回调用成功(0)或者失败(非0),任何有用的信息都返回在通过调用引用进来的参数中。
-
DNS风格:gethostbyname和gethostbyaddr检索NDS(域名系统)库;它们在错误的时候会返回NULL,并设置全局变量h_errno。
-
错误处理包装函数
-
unix风格
pid_t Wait(int *status) { pid_t pid; if(pid = wait(status)<0) unix_error("wait error"); return pid; }
-
Posix风格
void Pthread_detach(pthread_t tid) { int rc; if(rc=pthread_detach(tid) != 0) posix_error(rc,"Pthread_detach error"); }
-
DNS风格
struct hostent *Gethostbyname(const char *name) { struct hostname *p; if((p = gethostbyname(name)) == NULL) dns_error("Gethostbyname error"); return p; }
-