#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <unistd.h> #include <dirent.h> #include <string.h> #include <errno.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/types.h> #define BLOCK 4096 #define MAX_PATH 256 static char buff[BLOCK]; static char path[MAX_PATH]; static bool cp_dir(DIR*); static struct stat stbuf; int main(int argc,const char *argv[]) { if(argc != 3) { fprintf(stderr,"invalid arg num!\n"); exit(EXIT_FAILURE); } DIR *dp = opendir(argv[1]); if(dp == NULL) { fprintf(stderr," 1:\t%s\n",strerror(errno)); exit(EXIT_FAILURE); } strcpy(path,argv[2]); if(stat(argv[1],&stbuf) < 0) { fprintf(stderr,"2:\t%s \n",strerror(errno)); exit(EXIT_FAILURE); } if(mkdir(path,stbuf.st_mode) < 0) { fprintf(stderr,"3:\t%s\n",strerror(errno)); exit(EXIT_FAILURE); } return cp_dir(dp); } static struct dirent *dirp; static bool cp_dir(DIR *dp) { int sfd = dirfd(dp); int dfd; fchdir(sfd); int n = strlen(path); path[n++] = '/'; path[n] = 0; while((dirp = readdir(dp)) != NULL) { if(strcmp(dirp->d_name,".") == 0 || strcmp(dirp->d_name,"..") == 0) continue; if(stat(dirp->d_name,&stbuf) < 0) { fprintf(stderr,"4:\t%s\n",strerror(errno)); return false; } strcpy(path+n,dirp->d_name); if(S_ISDIR(stbuf.st_mode)) { DIR *sdp = opendir(dirp->d_name); if(mkdir(path,stbuf.st_mode) < 0) { fprintf(stderr,"5:\t%s\n",strerror(errno)); return false; } cp_dir(sdp); closedir(sdp); } else { int cfd = open(dirp->d_name,O_RDONLY); int tfd = open(path,O_CREAT|O_EXCL|O_WRONLY,stbuf.st_mode); int n; while((n = read(cfd,buff,BLOCK)) > 0) { if(write(tfd,buff,n) < n) { fprintf(stderr,"6:\t%s\n",strerror(errno)); break; } } close(cfd); close(tfd); } } chdir(".."); path[n-1] = 0; }
原文地址:http://blog.csdn.net/yuanliang01xiaolang/article/details/41516885