📄 00000021.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: SuperSB (孤鹰), 信区: Linux <BR>标 题: [转载]unix环境高级编程-附C <BR>发信站: BBS 水木清华站 (Wed Mar 15 14:32:37 2000) <BR> <BR> <BR> <BR> <BR>发信人: taosm (128+64-->cool), 信区: unix <BR>标 题: unix环境高级编程--附录C 习题答案 <BR>发信站: 西十八BBS (Sat Mar 11 14:37:49 2000), 转信 <BR> <BR>附录C 习题答案 <BR> <BR>第一章 <BR>1.1 利用ls命令中的下面两个选项:-i--显示文件或目录的i节点数目(关于i节点 <BR>在4.14节中会详细讨论);-d--如果参数是一目录,只列出其名字,而不是目录中 <BR>的所有文件。 <BR>执行下面命令的结果为: <BR>$ ls -ldi /etc/. /etc/.. <BR> 3077 drwxr-sr-x 7 bin 2048 Aug 5 20:12 /etc/./ <BR> 2 drwxr-xr-x 13 root 512 Aug 5 20:11 /etc/../ <BR>$ls -ldi /. /.. <BR> 2 drwxr-xr-x 13 root 512 Aug 5 20:11 /./ <BR> 2 srwxr-xr-x 13 root 512 Aug 5 20:11 /../ {.和..的的i节点数均为2 <BR>的i节点数均为2 <BR>1.3 假如perror的ptr参数是一个指针,则perror就可以改变ptr所指串的内容。所 <BR>以利用限定词const使得perror不能修改ptr所指的串。而strerror的参数是错误号 <BR>,由于其是整数类型并且C传递的是参数值,因此strerror不能修改参数的值,也 <BR> <BR> <BR>就没有必要使用const属性。 <BR>1.4 调用fflush,fprintf和vprintf函数会改变errno的值。如果它的值变了但没 <BR>有保存,则最终显示的错误信息是不正确的。 <BR>在过去开发许多程序中都可以发现不保存errno的情况,典型的打印出的错误信息 <BR>是"Not a typewriter."。在5.4节中标准I/O库根据标准I/O流是否指向终端设备而 <BR>改变流的缓存器。istty(11.9节)通常用来判断流是否指向终端设备,如果流不指 <BR>向终端设备,errno可能置为ENOTTY,从而引起该错误。程序C.1表现了这个属性。 <BR> <BR>#include <stdio.h> <BR>/* <BR> * The following prints errno=25 (ENOTTY) under 4.3BSD and SVR2, <BR> * when stdout is redirected to a file. <BR> * Under SVR4 and 44BSD it works OK. <BR> */ <BR>int <BR>main() <BR>{ <BR> int fd; <BR> extern int errno; <BR> if ( (fd = open("/no/such/file", 0)) < 0) { <BR> printf("open error: "); <BR> printf("errno = %d\n", errno); <BR> } <BR> exit(0); <BR>} <BR>程序 C.1 errno和printf的交互作用 <BR>执行上面的程序,结果为: <BR>$ grep BSD /etc/motd <BR>4.3 BSD UNIX #29: Thu Mar 29 11:14:13 MST 1990 <BR>$ a.out <BR>open error: error = 2 {工作正常,stdout是一个终端} <BR>$ a.out > temp.foo <BR>$ cat temp.foo <BR>open error: error = 25 {错误} <BR>1.5 2038年。 <BR>1.6 大约248天。 <BR> <BR> <BR>第二章 <BR>2.1 下面是4.3+BSD中使用的技术。在<machine/ansi.h> 中,用大写字母定义可以 <BR>在多个头文件中出现的基本数据类型。例如: <BR> #ifndef _ANSI_--H_ <BR> #define _ANSI_H_ <BR> <BR> #define _CLOCK_T_ unsigned long <BR> #define _SIZE_T_ unsigned int <BR> … <BR> #endif /*_ANSI_H_*/ <BR> 以下面的顺序可以在这6个头文件中分别定义size_t。 <BR> #ifdef _SIZE_T_ <BR> typedef _SIZE_T_ size_t; <BR> #undef _SIZE_T_ <BR> #endif <BR> 这样,实际上只执行一次typedef。 <BR> <BR> <BR>第三章 <BR>3.1 所有的磁盘I/O都要经过内核的块缓存器,唯一例外的是对原始磁盘设备的I/ <BR>O,但是我们不考虑这种情况(Bach [1986] 中的第三章讲述了这种缓存器的操作) <BR>。既然read或write的数据都要被内核缓存,那么术语"无缓存装置的I/O"指的是在 <BR>用户的进程中对这两个函数不会自动缓存,每次read或write就要进行一次系统调 <BR>用。 <BR>3.3 每次调用open函数就分配一个文件表项,如果两次打开的是相同的文件,则两 <BR>个文件表项指向相同的v节点。调用dup引用已存在的文件表项(此处指fd1的文件表 <BR>项),见图C.1。当F_SETFD作用于fd1时,只影响fd1的文件描述符标志;F_SETFL作 <BR>用于fd1时,则影响fd1及fd2的文件描述符标志。 <BR>图C.1 open和dup的结果 <BR>3.4 如果fd是1,执行dup2(fd,1)后返回1,但是没有关闭描述符1(参见3.12节)。 <BR>调用3次dup2后,3个描述符指向相同的文件表项,所以不需要关闭描述符。 <BR> 如果fd是3,调用3次dup2后,有4个描述符指向相同的文件表项,所以就需要关闭 <BR>描述符3。 <BR>3.5 shell是从左到右处理命令行,所以 <BR>a.out > outfile 2 >&1 <BR>首先设置标准输出到outfile,然后执行dups将标准输出复制到描述符2(标准错误 <BR>)上,其结果是将标准输出和标准错误设置为相同的文件,即描述符1和2指向相同 <BR>的文件表项。 <BR> 而对于命令行 <BR> a.out 2 > &1 >outfile <BR> 由于首先执行dups,所以描述符2成为终端(假设命令是交互执行的),标准输出重 <BR>定向到outfile。结果是描述符1指向outfile的文件表项,描述符2指向终端的文件 <BR>表项。 <BR>3.6 这种情况之下,仍然可以用lseek和read函数读文件中任何一处的内容。但是 <BR>write函数在写数据之前会自动将文件偏移量设置为文件尾,所以写文件时只能从 <BR>文件尾开始,不能在任意位置。 <BR> <BR> <BR>第四章 <BR>4.1 stat函数总是顺一个符号连接向前,所以修改后的程序不会显示文件类型是" <BR>符号连接"。例如:/bin是/usr/bin的一个符号连接,但是stat函数的结果只显示 <BR>/bin是一个目录,而不说明它是一个符号连接。若一个符号连接指向一不存在的文 <BR>件,则stat出错返回。 <BR>4.2 将下面的几行语句加入<ourhdr.h> <BR> #if defined ( S_IFLNK ) && !defined ( S_ISLNK ) <BR> #define S_ISLNK ( mode ) ((( mode ) & S_IFMT ) == S_IFLNK ) <BR> #endif <BR> 这是一个我们编写的头文件如何屏蔽某些系统差别的实例。 <BR>4.3 关闭了该文件的所有存取权限。 <BR> $ umask 777 <BR> $ data > temp.foo <BR> $ ls -l temp.foo <BR> ---------- l stevens 29 Jan 14 <BR>6:39 temp.foo <BR>4.4 下面的命令表示关闭用户读权限的情况。 <BR> $ data > foo <BR> $ chmod u-r foo {关闭用
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -