Q1. 用stat 函数替换图4-3程序中的lstat 函数,如若命令行参数之一是符号链接,会发生什么变化?
改之前:
[root@clstore3 ~]# ./lstat /etc/passwd /etc /dev/log /dev/tty /dev/sr0 /dev/cdrom
/etc/passwd: regular
/etc: directory
/dev/log: socket
/dev/tty: character special
/dev/sr0: block special
/dev/cdrom: symbolic link
可以看出,lstat 把/dev/cdrom 当着软链接去看。
现在我们把程序lstat 改为stat 之后,允许结果如下,可以看stat查看的是符号链接所引用的文件的信息。
结论:lstat 函数类似于stat,但当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是有该符号链接引用的文件的信息。
[root@clstore3 ~]# ./stat /etc/passwd /etc /dev/log /dev/tty /dev/sr0 /dev/cdrom
/etc/passwd: regular
/etc: directory
/dev/log: socket
/dev/tty: character special
/dev/sr0: block special
/dev/cdrom: block special
#include "apue.h"
int
main(int argc, char *argv[])
{
int i;
struct stat buf;
char *ptr;
for ( i = 1; i < argc; i++) {
printf("%s: ", argv[i]);
if (stat(argv[i], &buf) < 0){ /* this need to change lstat from stae*/
err_ret("lstat error");
continue;
}
if ( S_ISREG(buf.st_mode))
ptr = "regular";
else if ( S_ISDIR(buf.st_mode))
ptr = "directory";
else if ( S_ISCHR(buf.st_mode))
ptr = "character special";
else if ( S_ISBLK(buf.st_mode))
ptr = "block special";
else if ( S_ISFIFO(buf.st_mode))
ptr = "fifo special";
else if ( S_ISLNK(buf.st_mode))
ptr = "symbolic link";
else if ( S_ISSOCK(buf.st_mode))
ptr = "socket";
else
ptr = "** unknow mode **";
printf("%s\n", ptr);
}
exit(0);
}
Q2.
如果文件模式创建屏蔽字是777(八进制),结果会怎样?用shell 的umask 命令验证该结果。
[root@clstore3 ~]# umask
0022
改为777后
[root@clstore3 ~]# umask 777
[root@clstore3 ~]# umask
0777
创建一个test3文件子后,只有root可以看,也不可以更改了。
[root@clstore3 ~]# vim test3.txt
[root@clstore3 ~]# ls -al test3.txt
----------. 1 root root 12 Nov 13 10:44 test3.txt
Q3.关闭一个你所有拥有的用户的读权限,将导致拒绝你访问你自己的文件,对此进行验证。
[root@clstore3 ~]# chmod 640 /home/zhangb/Makefile
[root@clstore3 ~]# ls -al /home/zhangb/Makefile
-rw-r-----. 1 root root 18709 May 22 17:32 /home/zhangb/Makefile
切换到用户zhangb,由于用户zhangb没有该文件的读权限,所以不能查看该文件。
[root@clstore3 ~]# su - zhangb
522868 $ ls -al Makefile
-rw-r-----. 1 root root 18709 May 22 17:32 Makefile
522868 $ less Makefile
Makefile: Permission denied
522868 $ whoami
522868
Q4,创建文件foo 和bar后,运行图4-9的程序,将发生什么情况?
什么都没有发生, 权限为没有任何改变。
[root@clstore3 ~]# touch foo bar
[root@clstore3 ~]# ls -al foo bar
-rw-r--r--. 1 root root 0 Nov 13 11:34 bar
-rw-r--r--. 1 root root 0 Nov 13 11:34 foo
[root@clstore3 ~]# ./create_foobar
[root@clstore3 ~]# ls -al foo bar
-rw-r--r--. 1 root root 0 Nov 13 11:34 bar
-rw-r--r--. 1 root root 0 Nov 13 11:34 foo
###############################################################
[root@clstore3 ~]# cat create_foobar.c
#include "apue.h"
#include <fcntl.h>
#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
int
main(void)
{
umask(0);
if ( creat("foo",RWRWRW) < 0)
err_sys("create error for foo");
umask ( S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (creat("bar", RWRWRW) < 0 )
err_sys("create error for bar");
exit(0);
}
Q4.5 4.12节中讲到一个普通文件的大小可以是0,同时我们又知道st_size字段是为目录或符号链接定义的,那么目录和符号链接的长度可否为0?
A:对于普通文件,其文件长度可以是0,在开始读写这种文件是,将得到文件(end-of-file)指示。
对于目录,文件长度通常是一个(16or512)的整倍数。
符号链接-文件长度是在文件名中的实际字节数。
[root@clstore3 /]# ls -al /dev/cdrom
lrwxrwxrwx. 1 root root 3 May 29 21:55 /dev/cdrom -> sr0
[root@clstore3 var]# ls -al mail
lrwxrwxrwx. 1 root root 10 Sep 15 2014 mail -> spool/mail
Q4.6,编写一个类似cp1的程序,它复制包含空洞的文件,但不将字节0写到输入文件中去.
[root@clstore3 ~]# od -c file.hole
0000000 a b c d e f g h i j \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0040000 A B C D E F G H I J
0040012
[root@clstore3 ~]# od -c file.out
0000000 a b c d e f g h i j A B C D E F
0000020 G H I J
0000024
程序代码部分
#include <stdio.h>
#include <stdlib.h>
/* this program is to copy a file ( ignore the hole part if there is a hole in it
* zhangbo 2015/11/13 */
int main ()
{
int c;
FILE *in, *out;
in = fopen("file.hole","r");
out = fopen("file.out","w");
c = fgetc(in);
while ( c != EOF )
{
/* this is to copy the file, if encounter file with a hole in it '\0', do nothing,
* otherwise, copy the content to file.out*/
if ( c != '\0')
fputc(c,out);
c = fgetc(in);
}
exit(0);
}
apue Note in output from the ls command in section 4.12 that the file core and core.copy have different access permission. If the umask value didn’t change between the creation of these two files. explain how the difference could have occurred. ?
Q4.8 when running program 4.5 we check the available disk space with the df(1) command. why didn’t we use the du(1) command.
du command reports that the amount of disk space used by the file. 512-byte blocks.
Df displays the amount of disk space available on the file system containing each file name argument.
Q4.9 In figure 4.20, we show the unlink function as modifying the changed-status time of the file itself. How can this happen?
The modification time indicates when the contents of the file were last modified.
The changed-status time indicates when the i-node of the file was last modified.
some operations the affect the i-node without changing the actual contents of the files:
change the file access permissions/user ID, and change the number of links and so on.
The unlink function changes the i-node contents of the file and it is for changed-status time.
test1 are the hard link to test.txt,我们可以看到在unlink test1.txt 后,test.txt 的changed-status time 变成了16:59, 证明unlink 更改了i-node里的信息link减1,导致最后的changed-status 变成了最新的
zhangbodeMacBook-Pro:script zhangbo$ ls -lc test*
-rw-r--r-- 3 zhangbo staff 12 11 16 16:49 test.txt
-rw-r--r-- 3 zhangbo staff 12 11 16 16:49 test1.txt
zhangbodeMacBook-Pro:script zhangbo$ ./a.out
file unlinked
done
zhangbodeMacBook-Pro:script zhangbo$ ls -lc test*
-rw-r--r-- 2 zhangbo staff 12 11 16 16:59 test.txt
Three time fields are maintained for each file, Their purpose is summarized in the below.
st_atime last-access time of tile read -u (ls option ls -u )
st-mtime last-modification time of file date write
st-ctim last-change time of i-node status chmod,chown -c
Q4.10 in Section 4.22 how does the system’s limit on the number of open files effect the mighty function?
Opendir 打开一个目录后,递归调用dopath函数。假设opendir使用一个文件描述符,并且只有在处理完目录后才调用closedir释放描述符,这就意味这每次将一级就要使用另外一个描述符。所以进程可以打开的最大描述符数就限制了我们可以遍历的文件系统的深度。
Q4.11 In section 4.22, our version of ftw never changes its directory, Modify this routine so that each time it encounters a directory, it uses the chdir function to change to that directory. allowing it to use the filename and not the pathname for each call to stat. When all the entries in the directory have been processed, execute chdir(“..”) compare the time used by this version and the version int the next.
每次到要做两次chdir,这样会耗费系统的资源,感觉耗时。
Q4.12. Each process also have a root directory that is used for resolution of absolute phonemes.
this root directory can be changed with the chroot function. Look up the description for this function in your manuals when might this function be useful?
chroot 函数被英特网文件传输协议(FTP)程序用于辅助安全性,系统中咩有账户的用户(匿名用户)放在一个单独的目录下,利用chroot将目录当着新的根目录,就可以阻止用户访问此目录之外的文件。
chroot也可以在另一台机器上构造一个文件系统结构的副本,然后修改此副本更改原来的文件系统,这可以用于测试新软件包的安装(标准答案)
Q4.13 how can you set only one of the two time values with the utimes functions?
utimes 太老了,搞不定,就用了个utime.跟它差不多,功能是一样的。
utime 的结构是
struct utimbuf
{
__time_t actime; /* Access time. */
__time_t modtime; /* Modification time. */
};
[root@clstore3 ~]# vim file.out
[root@clstore3 ~]# ls -al file.out
-rw-r--r--. 1 root root 13 Nov 18 18:25 file.out
[root@clstore3 ~]# ls -lu file.out
-rw-r--r--. 1 root root 13 Nov 18 18:25 file.out
[root@clstore3 ~]# ./a.out
运行后的时间,access time 时间没有变化,但mod 时间变了,
[root@clstore3 ~]# ls -al file.out
-rw-r--r--. 1 root root 13 Nov 15 18:25 file.out
[root@clstore3 ~]# ls -lu file.out
-rw-r--r--. 1 root root 13 Nov 18 18:25 file.out
# cat zap.c -- 该程序来源于 http://m.blog.csdn.net/blog/zhoulaowu/14158137
#include <utime.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int i, fd;
struct stat statbuf;
char pathname[] = "/root/file.out";
struct utimbuf ubuf;
/*struct timespec times[2];*/
struct timespec times[2];
if (stat(pathname, &statbuf) == -1) {
printf("stat error for %s\n", argv[i]);
} else
{
ubuf.modtime = statbuf.st_mtime - 30000;
ubuf.actime = statbuf.st_atime ;
if ( utime(pathname, &ubuf) == -1 )
printf("utime error for %s\n", pathname);
}
exit(0);
}
Q4.14. some versions of the finger command output “new mail received …” and “unread since …” where …are the corresponding time and dates. How can the program determine these two times and dates
查看最后一次 access 时间 of a file.
Q4.15. Examine the archive formats used by the clio and tar commands. ( these descriptions are usually found in section 5 of the Unix programmer’s manual)how many of the three possible time values are saved for each file? when a file is restored, what value do you think the access time is set to. and why?
mtime and atime for tar.
tar 在抽取文件是,默认不改变文件的modify time,用户的 access time 被修改。
[root@clstore3 test1]# tar -xf tar.tat
[root@clstore3 test1]# ls -l ---可以查看用户的modify 时间,没有被修改。
total 12
-rw-r--r--. 1 root root 0 Nov 19 15:51 blues --mtime 没有被修改。
-rw-r--r--. 1 root root 0 Nov 19 15:51 folk
-rw-r--r--. 1 root root 0 Nov 19 15:51 jazz
-rw-r--r--. 1 root root 10240 Nov 19 17:35 tar.tat
[root@clstore3 test1]# ls -u
blues folk jazz tar.tat
[root@clstore3 test1]# ls -lu
total 12
-rw-r--r--. 1 root root 0 Nov 19 17:39 blues --atime 被修改为文件的抽取时间。
-rw-r--r--. 1 root root 0 Nov 19 17:39 folk
-rw-r--r--. 1 root root 0 Nov 19 17:39 jazz
-rw-r--r--. 1 root root 10240 Nov 19 17:35 tar.tat
[root@clstore3 test1]# date
Thu Nov 19 17:39:59 CST 2015
同样的抽取是+M参数后,mtime and atime 都被改到被抽取的时间,可以看到mtime and atime 和现在的时间是一直的。
[root@clstore3 test1]# tar -mxf tar.tat
[root@clstore3 test1]# ls -al
total 20
drwxr-xr-x. 2 root root 4096 Nov 19 17:45 .
drwxr-xr-x. 4 root root 4096 Nov 19 17:28 ..
-rw-r--r--. 1 root root 0 Nov 19 17:45 blues
-rw-r--r--. 1 root root 0 Nov 19 17:45 folk
-rw-r--r--. 1 root root 0 Nov 19 17:45 jazz
-rw-r--r--. 1 root root 10240 Nov 19 17:35 tar.tat
[root@clstore3 test1]# ls -lu
total 12
-rw-r--r--. 1 root root 0 Nov 19 17:45 blues
-rw-r--r--. 1 root root 0 Nov 19 17:45 folk
-rw-r--r--. 1 root root 0 Nov 19 17:45 jazz
-rw-r--r--. 1 root root 10240 Nov 19 17:35 tar.tat
[root@clstore3 test1]# date
Thu Nov 19 17:45:14 CST 2015
Q4.16. Does the unix system have a fundamental limitation on the depth of a directory tree? To find our, write a program that creates a directory and then changes to that directory in a loop. Make certain that the length of the absolute pathname of the of the leaf of the directory is greater than your system’s PATH_MAX limit. Can you call getcwd to fetch the directory’s pathname? how do the standard UNIX system tools deal with this long pathname?
总体上说文件深度的应该是有限制的,但不同的系统限制也不同。
我的机器在到203多的时候就不能显示了,就说结果太大了。mac and linux 大概路径长度为1052个字符,然后就不行了。 但是mac 还是可以mkdir而且成功的。 unix 下就直接到203的时候不行了.
Linux and mac os pathname ~= 1052 字符
mac os 可以继续创建文件夹,但linux 就不可以了。
new current directory is:Result too large
current directory level: 8667
mkdir successed.
new current directory is:Result too large
current directory level: 8668
mkdir successed.
new current directory is:Result too large
current directory level: 8669
mkdir successed.
[root@clstore3 ~]# tail test.txt | sed -n '5,7p'
current directory level: 203
mkdir successed.
new current directory is:/root/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test/test
[root@clstore3 ~]# tail test.txt | sed -n '10p' | wc -c
1052
程序源码
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main( int argc, char *argv[])
{
char path[1000];
char file[1000];
argv[1] = "test";
char *d ;
char *s = "/view";
int i;
getwd(path);
printf("current directory is: %s\n", path);
for ( i = 1; i <= 10000; i++){
printf("current directory level: %d\n", i);
if ( mkdir(argv[1], S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH) < 0)
{
printf("mkdir failed\n");
return 2;
}
if(chdir(argv[1]) < 0 )
{
printf("chdir failed \n");
return 2;
}
getwd(path);
/*strcpy(path, argv[1]);*/
printf("mkdir successed.\n new current directory is:%s\n",path);
}
return 0;
}
Can you archive the directory using either tar or clio?
4.17. In section 3.16, we describe the /dev/fd feature. for any user to be able to access these files. their permissions must be rw-rw-rw. some programs that create an output file delete the file first, in case in already exists. ignoring the return code:
unlink(path);
if (( fd = create(path, FILE_MODE)) < 0 )
erro_sys(…);
what happens if path is /dev/fd/1 ?
系统直接拒绝我unlink
zhangbodeMacBook-Pro:script zhangbo$ ./a.out
unlink error: Permission denied
zhangbodeMacBook-Pro:script zhangbo$ ls -al /dev/fd
total 0
crw--w---- 1 zhangbo tty 16, 3 11 21 14:21 0
crw--w---- 1 zhangbo tty 16, 3 11 21 14:21 1
crw--w---- 1 zhangbo tty 16, 3 11 21 14:21 2
zhangbodeMacBook-Pro:script zhangbo$ cat delete_fd.c
#include <apue.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
char *path;
int fd;
int main(void)
{
path="/dev/fd/1";
if (unlink(path) < 0 )
err_sys("unlink error");
/*if ((fd = creat(path, FILE_MODE)) < 0 )
err_sys("hello this is error");*/
}
我手工去rm 1 的时候被拒绝,官方解释是/dev 这个目录下面的写权限被关闭了,但我感觉感觉不是的,
我到/dev 下面去删点别(/dev/fd and /dev/zero )的东西也可以。在测试机器上做的centos 6.2重启过后又好了看来linux 还是有很强大的自我恢复功能的。
恳请看官有好的解释通知俺一声。
[root@client2 ~]# ls -al /dev/fd
lrwxrwxrwx. 1 root root 13 10月 21 08:40 /dev/fd -> /proc/self/fd
[root@client2 ~]# ls -al /dev/fd/
总用量 0
dr-x------. 2 root root 0 11月 21 01:29 .
dr-xr-xr-x. 8 root root 0 11月 21 01:29 ..
lrwx------. 1 root root 64 11月 21 01:29 0 -> /dev/pts/3
lrwx------. 1 root root 64 11月 21 01:29 1 -> /dev/pts/3
lrwx------. 1 root root 64 11月 21 01:29 2 -> /dev/pts/3
lr-x------. 1 root root 64 11月 21 01:29 3 -> /proc/53116/fd
[root@client2 ~]# ls -al /proc/self/fd
总用量 0
dr-x------. 2 root root 0 11月 21 01:29 .
dr-xr-xr-x. 8 root root 0 11月 21 01:29 ..
lrwx------. 1 root root 64 11月 21 01:29 0 -> /dev/pts/3
lrwx------. 1 root root 64 11月 21 01:29 1 -> /dev/pts/3
lrwx------. 1 root root 64 11月 21 01:29 2 -> /dev/pts/3
lr-x------. 1 root root 64 11月 21 01:29 3 -> /proc/53129/fd
zhangbodeMacBook-Pro:script zhangbo$ ./a.out
unlink error: Permission denied
zhangbodeMacBook-Pro:script zhangbo$ ls -al /dev/fd
total 0
crw--w---- 1 zhangbo tty 16, 3 11 21 14:21 0
crw--w---- 1 zhangbo tty 16, 3 11 21 14:21 1
crw--w---- 1 zhangbo tty 16, 3 11 21 14:21 2