Chinaunix首页 | 论坛 | 博客
  • 博客访问: 56934
  • 博文数量: 22
  • 博客积分: 1546
  • 博客等级: 上尉
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-20 20:33
文章分类
文章存档

2010年(22)

分类: C/C++

2010-08-09 19:33:08

Update: 8/9

上次给大家将了my_cp之后,一些同学提出关于文件权限的问题,比如不同用户组之间的文件拷贝涉及到的权限问题。之前对my_cp的测试以及整体设计我都只是针对文件所有者而言,因此这个问题还有待于完善。针对权限问题,我觉得可能还有不少BUG,所以今天就反复测试,结果就发现了如下问题。

我们在进行拷贝文件时,当目的文件不存在时会新建这个目的文件,并进行内容拷贝。目的文件的权限为默认的644。参考下面:

gues@huangwei-desktop:~/code/shell_command$ ls -l test.c
-rw-rw-r-- 1 gues gues 5327 2010-08-09 10:31 test.c
gues@huangwei-desktop:~/code/shell_command$ cp test.c newtest.c
gues@huangwei-desktop:~/code/shell_command$ ls -l test.c newtest.c
-rw-r--r-- 1 gues gues 5327 2010-08-09 10:45 newtest.c
-rw-rw-r-- 1 gues gues 5327 2010-08-09 10:31 test.c

目的文件已经存在时,也会如同上述结果:只拷贝权限,不影响目的文件权限,即保持原目的文件的属性。

那么如何才能拷贝权限?此时就得加入-p选项。目前的my_cp并没有注意到这个问题,只要涉及到拷贝文件,都会将内容和属性一起拷贝。因此我们接下来修改代码:修复my_cp存在的上述漏洞,并且加入-p选项。同时,我们应该稍微修改代码的逻辑判断,为其他选项留条后路。好了,开始吧!

首先在主函数中,我们增加一个对选项-p的判断,注意同时要在声明相应的变量param_p和index_p数组,功能和-r选项相同,具体可参见前文。并且,如果日后要添加其他选项那么直接添加即可。注意,我还增加了一个param全局变量(如果选项不合法,也不碍事),只有命令中含有任何选项,那么它就为真(下面就将用到)。

	//check the legality of the options,only -r or -R
	for(i=1;i<\argc;i++)
	{
		if(argv[i][0]=='-')
		{
			param=1;//have a option
			if((!strcmp(argv[i],"-r")||!strcmp(argv[i],"-R")))
			{
				param_r+=1;
				index_r[i]=i;
			}
			else if(!strcmp(argv[i],"-p"))
			{
				param_p+=1;
				index_p[i]=i;
			}
			/*
			 *if the command include another option,you can add the similar code in here.
			 *You must also add the variable param_?  and index_?[]
			 */
			else
			{
				printf("my_cp:无效选项: %s\n",argv[i]);
				exit(1);
			}
		}
	}

对于获得文件操作数个数和源文件个数的代码也要修改。注意这里的param_r或param_p并不一定为1,当存在相应选项时。因为输入多个相同选项,其效果和一个选项是一样的。

	//get the number of src file
	if(param)
	{
		num=argc-1;//because of "./my_cp"

		if(param_r)
      	        {
		       num-=param_r;
         	}

         	if(param_p)
        	{
			num-=param_p;
        	}

		/*if the command include another option,you can add the similar code in here*/

		src_num=num-1;//because of "dest file"
	}
	else
	{
		//the command doesn't include any option
		num=argc-1;
		src_num=num-1;
	}

另外,当文件数目不合法时,我也对其判断做了优化,具体参见代码。

	if(num<2)
	{
		if(num==0)
		{
			printf("my_cp:缺少了文件操作数\n");
			exit(1);
		}
		if(num==1)
		{
			printf("my_cp:缺少了要操作的目标文件\n");
	        	exit(1);
		}
	}

另外在获取目的文件和源文件的时候,也应该相应添加对-p选项的判断。以上修改使得我们增加其他选型的时候会变得更容易,代码可读性更高。

接下来就是修补上述my_cp的bug了。根据上述举例,只有加入了-p选项时,才会将源文件的属性复制给目的文件,因此我们只要将上述文字翻译成代码即可。

	//set the dset file's access right when the “-p” existed
	if(param_p)
	{
		if(fchmod(fdwt,buf.st_mode)==-1)
        	{
			perror("fchmod");
              		exit(1);
         	}
        	//set file's user id and group id
         	if(fchown(fdwt,buf.st_uid,buf.st_gid)==-1)
         	{
			perror("fchown");
              		exit(1);
         	}
	}

这里还没有完,还记得我们上面讨论分目的文件存在和目的文件不存在两种情况吗?我们还必须修改打开目的文件时open函数的参数。这些参数的的功能:当目的文件不存在时,新建这个文件,文件属性由opne函数第三个参数决定(644);否则,只是清空目的文件中的内容。这些参数刚好满足我们一开始举例后描述的情况。

	//open the dest file
	if((fdwt=open(dest_path,O_CREAT|O_TRUNC|O_RDWR,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))==-1)
	{
		perror("open");
		exit(1);
	}

OK,这下就可以解决上述漏洞了。

阅读(938) | 评论(0) | 转发(0) |
0

上一篇:实现cp命令(5)

下一篇:实现cp命令(7)

给主人留下些什么吧!~~