编写自己的cp命令
2014-05-09 14:43
288 查看
有时候要对整个目录做备份,修改cp1.c使得当两个参数都是目录时,把第一个目录中的所有文件复制到第二个目录中,文件名不变。那么该如何实现?
我们先来看看cp1.c的实现方式,它从一个文件中读取数据然后写到另一个文件中,通过系统调用open(或者creat)、read、wirte和close来完成。从上面我们看出,cp1.c只是针对于一个文件进行的复制操作,而现在我们需要完成对整个目录的备份。参数由一个单独的文件(file)变成一个目录(directory),所以我们首先想到的就是要先进入到这个目录下,然后对该目录下的文件依次进行cp操作,那么这就涉及到了目录的操作,而我们在第三章ls命令的实现过程中,用到的就是对目录的操作,涉及到的系统调用包含有opendir、readdir和closedir。所以现在我们需要把两者用到的技术联系起来,以便完成对目录的备份工作。
具体实现:
1、命令行参数
int argc、char *argv[]
2、cp源、目的的类型判断
src为dir,dst也必须是dir
src为file,dst可以是anything
3、目录操作
opendir进入src目录下;
while{
readdir获得当前目录下的文件(或目录),递归判断是否还是目录,如果是继续深入;
srcpath、dstpath获取,调用cp完成复制;
}
closedir完成目录复制
4、cp实现
in=open(src);out=creat(dst)
while{
read(in);
write(out);
}
close(in);close(out)
具体的代码如下:
改进(添加目录判断)之后的具体实现:
我们先来看看cp1.c的实现方式,它从一个文件中读取数据然后写到另一个文件中,通过系统调用open(或者creat)、read、wirte和close来完成。从上面我们看出,cp1.c只是针对于一个文件进行的复制操作,而现在我们需要完成对整个目录的备份。参数由一个单独的文件(file)变成一个目录(directory),所以我们首先想到的就是要先进入到这个目录下,然后对该目录下的文件依次进行cp操作,那么这就涉及到了目录的操作,而我们在第三章ls命令的实现过程中,用到的就是对目录的操作,涉及到的系统调用包含有opendir、readdir和closedir。所以现在我们需要把两者用到的技术联系起来,以便完成对目录的备份工作。
具体实现:
1、命令行参数
int argc、char *argv[]
2、cp源、目的的类型判断
src为dir,dst也必须是dir
src为file,dst可以是anything
3、目录操作
opendir进入src目录下;
while{
readdir获得当前目录下的文件(或目录),递归判断是否还是目录,如果是继续深入;
srcpath、dstpath获取,调用cp完成复制;
}
closedir完成目录复制
4、cp实现
in=open(src);out=creat(dst)
while{
read(in);
write(out);
}
close(in);close(out)
具体的代码如下:
/** cp1.c * version 1 of cp - uses read and write with tunable buffer size * * usage: cp1 src dest */ #include <stdio.h> #include <unistd.h> #include <fcntl.h> #define BUFFERSIZE 4096 #define COPYMODE 0644 void oops(char *, char *); main(int ac, char *av[]) { int in_fd, out_fd, n_chars; char buf[BUFFERSIZE]; /* check args */ if ( ac != 3 ){ fprintf( stderr, "usage: %s source destination\n", *av); exit(1); } /* open files */ if ( (in_fd=open(av[1], O_RDONLY)) == -1 ) oops("Cannot open ", av[1]); if ( (out_fd=creat( av[2], COPYMODE)) == -1 ) oops( "Cannot creat", av[2]); /* copy files */ while ( (n_chars = read(in_fd , buf, BUFFERSIZE)) > 0 ) if ( write( out_fd, buf, n_chars ) != n_chars ) oops("Write error to ", av[2]); if ( n_chars == -1 ) oops("Read error from ", av[1]); /* close files */ if ( close(in_fd) == -1 || close(out_fd) == -1 ) oops("Error closing files",""); } void oops(char *s1, char *s2) { fprintf(stderr,"Error: %s ", s1); perror(s2); exit(1); }
改进(添加目录判断)之后的具体实现:
/** cp2.c ** ------------------------------------------------------------ cp2.c is a revised version of cp1.c that can copy an entire directory file by file to a second directory. It also supports some of the features required by earlier exercises. ** ------------------------------------------------------------ ** ** * A version of cp1.c that works if src or dest name directories * (but not if src is a directory and dest is not) * * usage: cp1 src dest * If dest names a directory, then copy src to dest/src * If src names a directory, then copy all files in src to dest * If src is a directory and dest is NOT a directory, quit * Note: if src has a leading path, then only use last component * * build: cc sol03.14.c -o sol03.14 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #include <dirent.h> #define BUFFERSIZE 4096 /* * note: the real copy takes the mode of the copy from * the mode of the source. */ #define COPYMODE 0644 void oops(char *, char *); void *emalloc(size_t); int main(int ac, char *av[]) { if ( ac != 3 ){ fprintf( stderr, "usage: %s source destination\n", *av); exit(1); } /* * if source is a dir, then the dest has to be, too */ if ( isadir(av[1]) ){ if ( isadir(av[2]) ) copydir(av[1], av[2]); else { fprintf(stderr,"cp1: %s is not a directory\n", av[2]); exit(1); } } /* * if source is not a dir, then the dest can be anything */ else do_copy( av[1], av[2] ); return 0; } /* * copydir() * loops through all files in srcdir, copying each to destdir * uses do_copy but builds the paths here * Note: this function skips subdirectories of srcdir */ copydir(char *srcdir, char *destdir) { char *srcpath, *destpath; DIR *dir_ptr; struct dirent *direntp; srcpath = (char *) emalloc(strlen(srcdir)+1+MAXNAMLEN+1); destpath = (char *) emalloc(strlen(destdir)+1+MAXNAMLEN+1); if ( (dir_ptr = opendir(srcdir)) == NULL ) oops("Cannot open directory", srcdir); /* * loop through all items in src dir * Do not copy directories, and report that so user * realizes not all the items are copied. */ while( ( direntp = readdir(dir_ptr)) != NULL ) { sprintf(srcpath,"%s/%s", srcdir, direntp->d_name); if ( isadir(srcpath) ){ if ( strcmp(direntp->d_name,".") != 0 && strcmp(direntp->d_name,"..") != 0 ) printf("skipping directory %s\n", srcpath); continue; } sprintf(destpath, "%s/%s", destdir, direntp->d_name); do_copy( srcpath, destpath ); } closedir(dir_ptr); free(srcpath); free(destpath); } /* * copies a file from src to dest * If dest is a directory, then do_copy() copies to * a file in dest with the name taken from the filename for * src */ do_copy(char *src, char *dest) { int in_fd, out_fd, n_chars; char buf[BUFFERSIZE]; char *destfilename; char *make_destfilename(char*,char*); destfilename = make_destfilename(src, dest); /* * open files */ if ( (in_fd=open(src, O_RDONLY)) == -1 ) oops("Cannot open ", src); if ( (out_fd=creat( destfilename, COPYMODE)) == -1 ) oops( "Cannot creat", destfilename); /* * copy files */ while ( (n_chars = read(in_fd , buf, BUFFERSIZE)) > 0 ) if ( write( out_fd, buf, n_chars ) != n_chars ) oops("Write error to ", destfilename); if ( n_chars == -1 ) oops("Read error from ", src); /* * close files */ if ( close(in_fd) == -1 || close(out_fd) == -1 ) oops("Error closing files",""); } void oops(char *s1, char *s2) { fprintf(stderr,"Error: %s ", s1); perror(s2); exit(1); } /* * if dest is a directory, then combine src and dest * (see header to this program) */ char * make_destfilename(char *src, char *dest) { struct stat info; char *srcfilename; char *rv; if ( stat(dest, &info) == -1 ) /* let someone else handle this */ return dest; if ( ! S_ISDIR(info.st_mode) ) /* ok to copy to other types */ return dest; /* find last component of source name */ if ( (srcfilename = strrchr(src, '/')) != NULL ) srcfilename++; else srcfilename = src; /* use that to construct target name */ rv = emalloc(strlen(srcfilename) + strlen(dest) + 2); sprintf(rv, "%s/%s", dest, srcfilename); return rv; } void * emalloc(size_t n) { void *rv = malloc(n); if ( rv == NULL ) oops("Out of memory",""); return rv; } /* * boolean: tells if arg names a directory */ isadir(char *str) { struct stat info; return ( stat(str,&info) != -1 && S_ISDIR(info.st_mode) ); }
相关文章推荐
- linux自己编写的 cp 命令
- 关于cp命令的编写
- 自己动手写cp命令
- 编写自己的who命令
- 自己编写 shell 命令 实现安全的删除文件
- 自己编写more命令
- 《APUE.3E》习题4.6编写自己的cp(l)程序,它复制包含空洞的文件,但不将字节0包含到输出文件中去
- python 代码审计-命令执行漏洞(自己编写的代码)
- 自己编写more命令
- 实现自己的cp命令
- linux:编写自己的ls命令
- 编写自己的ls命令
- 淘宝服务市场 PHP封装商品橱窗类 (仅提供思路分析,类内调用的命令还需要自己编写)
- 自己动手编写一个简单的who命令(不带参数)
- ubuntu 编写自己的ls命令
- APUE习题4.6源代码----实现自己的简易 cp 命令
- 自己编写的more命令
- linux系统编程:自己动手写一个cp命令
- ubuntu 编写自己的ls命令
- 自己用C语言编写who命令