在《unix环境高级编程》书中,有用read和write对标准输入和标准输出文件描述符进行操作以达到复制功能。受此启发,用open,write和read等函数仿写了一个cp命令。代码如下:
#include
#include
#include
#include
#include
#include
#define MAXBUF 4096
int main(int argc, char *argv[])
{
int oldfiledes, newfiledes, n;
off_t oldfilelength;
char *pfilename = argv[1] + strlen(argv[1]) - 1;
char *pdestpath = NULL;
char *p1;
char *buf = NULL;
if (strlen(argv[1]) == 0 || strlen(argv[2]) == 0)
{
printf("Usage:my_copy filename destnation\n");
exit(0);
}
if (strstr(argv[1], "/") != NULL)
{
while(1)
{
if (*--pfilename == '/')
{
*pfilename++;
break;
}
}
}
else
{
pfilename = argv[1];
}
pdestpath = (char *)malloc(strlen(argv[2])+2);
if (pdestpath == NULL)
printf("malloc error\n");
p1 = pdestpath;
memset(pdestpath, 0, strlen(argv[2]) + 2);
strcpy(pdestpath, argv[2]);
if ((pdestpath = strstr(pdestpath, "/")) == NULL)
{
strcat(pdestpath,"/");
}
else if (*(--pdestpath) == '.')
{
pdestpath += 2;
if (strstr(pdestpath, "/") == NULL)
{
memset(pdestpath, 0, strlen(argv[2]) + 1);
} strcpy(pdestpath, argv[2]);
*(pdestpath + strlen(argv[2])) = '/';
}
strcat(pdestpath, pfilename);
if (-1 == (oldfiledes = open(argv[1], O_RDONLY)))
{
printf("open oldfiledes error\n");
}
if (-1 == (newfiledes = open(pdestpath, O_WRONLY | O_CREAT | O_TRUNC, 0666)))
{
printf("open newfiledes error\n");
exit(-1);
}
if (-1 == (oldfilelength = lseek(oldfiledes, 0, SEEK_END)))
{
exit(-1); exit(-1);
}
buf = (char *)malloc((long)(oldfilelength + 1));
if (buf == NULL)
printf("malloc error\n");
printf("buf [%p]\n", buf);
memset(buf, '0', oldfilelength + 1);
if (-1 == lseek(oldfiledes, 0, SEEK_SET))
{
printf("lseek begin error\n");
exit(-1);
}
if ((n = read(oldfiledes, buf, oldfilelength)) > 0)
{
printf("--buf [%p] n [%d] length =[%d]\n", buf, n, strlen(buf));
printf("oldfilelength=[%ld]\n", oldfilelength);
if (n != write(newfiledes, buf, n))
{
printf("write error \n");
exit(-1);
}
}
else
{
printf("read error nResult[%d]\n", n);
exit(-1);
}
printf("##buf [%p] n [%d] length =[%d]\n", buf, n, strlen(buf));
printf("oldfilelength=[%ld]\n", oldfilelength);
close(oldfiledes);
close(newfiledes);
pdestpath = p1;
free(pdestpath);
free(buf);
return 0;
}
此代码能实现基本的复制功能,但是在本地运行时,提示free指针地址错误,用valgrind却没有看到内存泄露,并且在朋友的虚拟机中运行没有提示free报错。很迷茫,待以后深入了解之后再回来查看具体原因。