2010年(22)
分类: C/C++
2010-08-15 17:53:07
在实现cp命令(6)(以下简称cp(6))中我们加入了-p选项,即使用cp命令时加入-p才会将源文件的属性复制给目的文件,否则只拷贝文件中的内容。但是我们看看下面cp的运行结果。
cp(6)中不是说只有加-p才会复制源文件的属性吗?怎么cao.c和源文件的属性一模一样?
gues@huangwei-desktop:~/code/shell_command$ ls -l ch222.c -rwxr--r-- 1 gues gues 5327 2010-08-09 20:45 ch222.c gues@huangwei-desktop:~/code/shell_command$ cp ch222.c cao.c gues@huangwei-desktop:~/code/shell_command$ ls -l cao.c -rwxr--r-- 1 gues gues 5327 2010-08-09 20:54 cao.c
为什么此时目的文件的属性又是644(cp(6)中说644是新建文件的默认属性)?
gues@huangwei-desktop:~/code/shell_command$ ls -l changemode.c -rw-rw-r-- 1 gues gues 5327 2010-08-09 10:31 changemode.c gues@huangwei-desktop:~/code/shell_command$ cp changemode.c wo.c gues@huangwei-desktop:~/code/shell_command$ ls -l wo.c -rw-r--r-- 1 gues gues 5327 2010-08-09 20:56 wo.c
起初,当我发现上述结果后,脑中有数个为什么。为什么复制文件的时候,文件属性会这么多变?不断出问题?其实,是因为我们忽略了文件屏蔽字:umask。在新建文件或者目录的时候,新文件的实际存取权限是mode&~umask。比如用open创建(或打开)文件,那mode就是open函数的第三个参数。既然这样,那我们来检验一下上述命令。通过输入umask命令,我们可以看到当前屏蔽字为022。与上述源文件进行mode&~umask运算后,刚好和目的文件的属性一致。那么现在我们终于找到问题的原因所在了。
好了,让我们忘掉cp(6)中所说的一切,重新整理思路:
在使用cp命令的时候,当目的文件不存在时,会新建与源文件同名的新文件。这个新文件的实际权限由:mode&~umask运算后的结果来决定。此时的mode为源文件的权限。而当目的文件存在时,则会保持原目的文件的属性,除非在cp命令中加入-p选项。
好了,我们现在搞清楚cp命令在不加-p选项时候的文件权限问题,至于代码修改,只需修改将open中的第三个参数修改成源文件的权限即可。具体代码实现如下:
//open the dest file if((fdwt=open(dest_path,O_CREAT|O_TRUNC|O_RDWR,src_buf.st_mode))==-1) { perror("open_destfile"); exit(1); }