📄 lect08-bb.ppt
字号:
free 0.171.30.230 0x10757327 esp 192.1.2.23free 83.205.60.34 0x9234094 esp 192.1.2.23free 187.108<html><head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>
[转载]unix环境高级编程-附C fkbch 2000.04.23
</title>
</head> <body bgcolor="#000000" text="#C0C0C0" link="#00FFFF" vlink="#FF00FF" alink="#FF00FF">
<p><b><font size="5">S-Term文章下载</font></b></p>
<p><font size="2" color="#FF00FF">支持强大脚本功能的Term,支持SSH的Term,可超强定制的Term</font></p>
<p align="center">[<a href="index.htm">回到开始</a>]
[<a href="20.htm">上一篇</a>][<a href="22.htm">下一篇</a>]
<hr><p></p>
发信人: 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 /../ {.和..的<br>
的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 {关闭用?<br>
读权限}<br>
$ ls -l foo<br>
验证文件的权限}<br>
--w-rw-r-- l stevens 29 Jul 31 09:00<br>
oo<br>
$ cat foo<br>
{读文件}<br>
cat: foo: Permission denied<br>
4.5 如果用open或creat创建已经存在的文件,则该文件的存取权限不变。通过程<br>
序4.3可以验证这点。<br>
$ rm foo bar<br>
删除文件}<br>
$ data > foo<br>
创建文件}<br>
$ data > bar<br>
$ chmod a-r foo bar {关闭所?<br>
的读权限}<br>
$ ls -l foo bar {验证其?<br>
限}<br>
--w--w---- l stevens 29 Jul 31 10:47<br>
ar<br>
--w--w---- l stevens 29 Jul 31 10:47<br>
oo<br>
$ a.out<br>
运行程序4.3}<br>
$ ls -l foo bar {检查文件的权限?<br>
大小}<br>
--w--w---- l stevens 0 Jul 31 10:47 bar<br>
--w--w---- l stevens 0 Jul 31 10:47<br>
oo<br>
可以看出存取权限没有改变,但是文件长度缩短了。<br>
4.6 目录的长度从来不会是0,因为它总是包含 .和 ..两项。符号连接的长度指其<br>
路径名的包含的字符数,由于路径名中至少有一个字符,所以长度也不为0。<br>
4.8 当创建新的core文件时,内核对其存取权限有一个默认设置,在本例中是:r<br>
w-r--r--。这一缺省值可能会也许不会被umask的值修改。Shell对创建的重定向的<br>
新文件也有一个默认的访问权限,本例中为rw-rw-rw-。这个值总是被当前的umas<br>
k修改,在本例中umask为02。<br>
4.9 不能使用du的原因是它需要文件名或目录名作为参数,例如:<br>
du tempfile<br>
du .<br>
只有当unlink函数返回时才释放tempfile的目录项,du命令没有计算仍然被temp<br>
file占用的空间。在本例中只能使用df命令察看文件系统中实际可用的自由空间。<br>
<br>
4.10 如果被unlink的链接不是该文件的最后一个链接,该文件不会删除。此时,<br>
unlink函数更新文件的状态改变时间。如果是最后一个链接,该文件将被物理删除<br>
。这时再去更新文件的状态改变时间就没有意义,因为包含文件所有信息的i节点<br>
将会随着文件的删除而被释放。<br>
4.11 用opendir打开一个目录后,循环调用函数dopath。假设opendir使用一个文<br>
件描述符,并且只有处理完目录后调用closedir才释放描述符,这就意味着每次打<br>
开目录就要降一级使用另外一个描述符。所以系统可打开文件数就限制了文件系统<br>
中树的深度。SVR4中的ftw允许调用者指定使用的描述符数,这隐含着该实现可以<br>
关闭描述符并且重用它们。<br>
4.13 chroot函数用于辅助Internet文件传输程序(FTP)中的安全性。系统中没有帐<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -