執行緒實現cp-r與ls-l
阿新 • • 發佈:2019-02-17
#include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <time.h> #include <pwd.h> #include <grp.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <dirent.h> #include <linux/types.h> #include <errno.h> #include <pthread.h> #define NAME_SIZE 256 struct fnode { struct fnode *next; char name[NAME_SIZE]; }; struct fnode *insert_list(struct fnode *temp,struct fnode *head) { if(head==NULL) //if linklist is empty,for temp is the first one { head=temp; return head; } if(strcmp(temp->name,head->name)<0) //temp will be insert before first one { temp->next=head; head=temp; return head; } struct fnode *next=head->next; struct fnode *prev=head; while(next!=NULL&& strcmp(temp->name,next->name)>0) { next=next->next; prev=prev->next; } temp->next=next; prev->next=temp; return head; } output_type_perm(mode_t mode) { char type[7]={'p','c','d','b','-','l','s'}; int index=((mode>>12) & 0xF)/2; printf("%c",type[index]); char *perm[8]={"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};//rwx printf("%s",perm[mode>>6 &07]); printf("%s",perm[mode>>3 &07]); printf("%s",perm[mode>>0 &07]); } void output_user_group(uid_t uid,gid_t gid) { struct passwd *user; user=getpwuid(uid); printf(" %s",user->pw_name); struct group *group; group=getgrgid(gid); printf(" %s",group->gr_name); } output_mtime(time_t mytime) { char buf[256]; memset(buf,'\0',256); ctime_r(&mytime,buf); buf[strlen(buf)-1]='\0'; //memcpy(buf,ctime(mytime),strlen(ctime(mytime))-1); printf(" %s",buf); } void output_info(struct fnode *head) { struct fnode *temp=head; while(temp!=NULL) { struct stat mystat; if(-1==stat(temp->name,&mystat)) { perror("stat");exit(EXIT_FAILURE); } output_type_perm(mystat.st_mode); printf(" %4d",mystat.st_nlink); output_user_group(mystat.st_uid,mystat.st_gid); printf(" %8ld",mystat.st_size); output_mtime(mystat.st_mtime); printf(" %s\n",temp->name); temp=temp->next; } } void free_list(struct fnode *ptr) { struct fnode *temp=ptr; struct fnode *link=ptr; while(ptr) { temp=ptr; ptr=ptr->next; free(temp); } } int cp_file(const char *src, const char *dst,mode_t mode) { int fd_src,fd_dst; if(-1 == (fd_src =open(src,O_RDONLY))) { perror("open src");exit(EXIT_FAILURE); } if(-1 == (fd_dst =open(dst,O_WRONLY|O_TRUNC|O_CREAT,mode))) { perror("open dst");exit(EXIT_FAILURE); } int len=0; do { char buf[1024]; len=read(fd_src,buf,1024); write(fd_dst,buf,len); }while(len>0); close(fd_src); close(fd_dst); } int cp_dir(const char *src,const char *dst) { DIR *dirp = NULL; if(NULL== (dirp=opendir(src))) { perror("opendir");exit(EXIT_FAILURE); } struct dirent *entp = NULL; while ( NULL != (entp =readdir(dirp))) { if (strcmp(entp->d_name, "..")==0 || strcmp(entp->d_name, ".")==0) //ignore ./ ../ { continue; } char *name_src =(char *) malloc( strlen(src) + 1 + strlen(entp->d_name) + 1 ); sprintf(name_src,"%s/%s\0",src,entp->d_name); char *name_dst =(char *) malloc( strlen(dst) + 1 + strlen(entp->d_name) + 1 ); sprintf(name_dst,"%s/%s\0",dst,entp->d_name); struct stat stat_src; if (stat(name_src, &stat_src) == -1) { fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno)); exit(EXIT_FAILURE); } if (S_ISREG(stat_src.st_mode)) //regular file { cp_file(name_src,name_dst,stat_src.st_mode); free(name_src); free(name_dst); } else if ( S_ISDIR( stat_src.st_mode )) { if( -1 ==mkdir(name_dst,stat_src.st_mode)) { perror("mkdir1");exit(EXIT_FAILURE); } cp_dir( name_src, name_dst); free(name_src); free(name_dst); } } } void* cp_r(char *argv[]) { /* if (argc < 3) { fprintf(stderr,"usage %s src_dir dst_src\n",argv[0]);exit(EXIT_FAILURE); } */ struct stat stat_src; if (stat(argv[1], &stat_src) != 0) { fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno)); exit(EXIT_FAILURE); } umask(0000); if (S_ISREG(stat_src.st_mode)) //regular file { struct stat stat_dst; if (stat(argv[2], &stat_dst) == -1) { if(errno != ENOENT) //if errno not cause by file/dir not exist { fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno)); exit(EXIT_FAILURE); } else //if dst_flie not exist. { cp_file(argv[1],argv[2],stat_src.st_mode); } } else //dst file exist. { if(S_ISDIR(stat_dst.st_mode)) //cp a file to a exist dir { char *ptr=(char *)malloc(strlen(argv[2])+1+strlen(argv[1])+1); sprintf(ptr,"%s/%s\0",argv[2],argv[1]); cp_file(argv[1],ptr,stat_src.st_mode); } else //cp file to a exist file { printf("file %s exist, do you want overwrite it[y/n]:",argv[2]); char ch; while(!scanf("%c",&ch)) { getchar(); } if(ch =='Y' || ch == 'y' ) { unlink(argv[2]); cp_file(argv[1],argv[2],stat_src.st_mode); } else return 1; } } } else if (S_ISDIR(stat_src.st_mode)) // dir { struct stat stat_dst; if (stat(argv[2], &stat_dst) == -1) { printf("TEST1 %s\n",argv[1]); if(errno != ENOENT) //if errno not cause by file/dir not exist { fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno)); exit(EXIT_FAILURE); } else //file/dir not exist { errno=0; if(-1 == mkdir(argv[2],stat_src.st_mode)) { perror("mkdir2");exit(EXIT_FAILURE); } char *le = argv[1]; int c = 0; for (int i = 0;i < strlen(argv[1]);i++) { char l = *(argv[1]+i); if (l == '/') { c=i; break; } } le = le + c + 1; printf("DIR:%s\n",le); char *ptr=(char *)malloc(strlen(argv[1])+1+strlen(le)+1); sprintf(ptr,"%s/%s\0",argv[2],le); if(-1 == mkdir(ptr,stat_src.st_mode)) { printf("mk:%s\n",ptr);perror("mkdir3");exit(EXIT_FAILURE); } cp_dir(argv[1],ptr); free(ptr); } } else if(S_ISREG(stat_dst.st_mode)) //can't copy a dir to a file { fprintf(stderr,"can't copy a dir to a file\n");exit(EXIT_FAILURE); } else //copy a dir to a exsit dir , { char *le = argv[1]; int c = 0; for (int i = 0;i < strlen(argv[1]);i++) { char l = *(argv[1]+i); if (l == '/') { c=i; break; } } le = le + c + 1; printf("DIR:%s\n",le); char *ptr=(char *)malloc(strlen(argv[1])+1+strlen(le)+1); sprintf(ptr,"%s/%s\0",argv[2],le); if(-1 == mkdir(ptr,stat_src.st_mode)) { printf("mk:%s\n",ptr);perror("mkdir3");exit(EXIT_FAILURE); } cp_dir(argv[1],ptr); free(ptr); } } } void* ls_l(char *argv[]) { int argc = 2; int i; for(i=1;i<argc;i++) { struct fnode *linklist=NULL; struct stat stat_info; if(stat(argv[i],&stat_info)==-1) { perror("stat");exit(EXIT_FAILURE); } if (S_ISREG(stat_info.st_mode)) //regular file { struct fnode *temp=(struct fnode *)malloc(sizeof(struct fnode)); if(NULL==temp) { perror("malloc");exit(EXIT_FAILURE); } temp->next=NULL; memset(temp->name,'\0',NAME_SIZE); memcpy(temp->name,argv[i],strlen(argv[i])); linklist=insert_list(temp,linklist); output_info(linklist); // output information of the file } else if(S_ISDIR(stat_info.st_mode)) { char buf[NAME_SIZE]; getcwd(buf,128); DIR *dirp=NULL; dirp=opendir(argv[i]); if(NULL==dirp) { perror("opendir");exit(EXIT_FAILURE); } struct dirent *entp=NULL; while(entp=readdir(dirp)) { struct fnode *temp=(struct fnode *)malloc(sizeof(struct fnode)); char absolute_way[126]; sprintf(absolute_way,"%s%s\0",argv[1],entp->d_name); struct stat stat_inside; if(!((strcmp(entp->d_name,".")) && (strcmp(entp->d_name,"..")))) continue; if(stat(absolute_way,&stat_inside)==-1) { perror("stat");printf("\nd_name:%s\n",entp->d_name);exit(EXIT_FAILURE); } if(NULL==temp) { perror("malloc");exit(EXIT_FAILURE); } /**************************************************************************************/ if(S_ISDIR(stat_inside.st_mode)) { int res_1; pthread_t cp_thread; void *thread_result1; char *cp_name = (char*)malloc(156); sprintf(cp_name,"%s%s\0",argv[1],entp->d_name); printf("TEST %s\n",entp->d_name); char* point[] = {"cp_r",cp_name,"zhangxu",NULL}; res_1 = pthread_create(&cp_thread,NULL,cp_r,point); if (res_1 != 0) { perror ("Thread creation failed"); exit (EXIT_FAILURE); } res_1 = pthread_join(cp_thread, &thread_result1); printf("Waiting for cp_thread to finish...\n"); if (res_1 != 0) { perror("Thread join failed"); exit (EXIT_FAILURE); } else { temp->next=NULL; memset(temp->name,'\0',NAME_SIZE); memcpy(temp->name,entp->d_name,strlen(entp->d_name)); linklist=insert_list(temp,linklist); free(cp_name); } /* pid_t pid; int status; char* pass_argv = argv; if ((pid = fork()) == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { char *cp_name = (char*)malloc(256); sprintf(cp_name,"%s%s\0",argv[1],entp->d_name); char* point[] = {"cp_r",cp_name,"yourname",NULL}; // printf("命令:%s\n",ls_name); // system(ls_name); // int ret = execv("/home/vic/Desktop/cp_r",point); int ret = execl("/home/vic/Desktop/cp_r","./cp_r",cp_name,"yourname",NULL); if(ret == -1) { perror("execl error"); } free(cp_name); free(point); exit(0); } else { printf("child_pid:%d\n",(waitpid(pid,&status,0))); printf("CP RIGHT\n"); temp->next=NULL; memset(temp->name,'\0',NAME_SIZE); memcpy(temp->name,entp->d_name,strlen(entp->d_name)); linklist=insert_list(temp,linklist); } */ } /*********************************************************************************************/ else { temp->next=NULL; memset(temp->name,'\0',NAME_SIZE); memcpy(temp->name,entp->d_name,strlen(entp->d_name)); linklist=insert_list(temp,linklist); } } chdir(argv[i]);//change the current dirctory close(dirp); output_info(linklist); chdir(buf); } free_list(linklist); } return 1; } int main (int argc,char* argv[]) { if(argc < 2) { printf("usage :%s dir_name\n",argv[0]);exit(EXIT_FAILURE); } int res; pthread_t ls_thread; void *thread_result; res = pthread_create(&ls_thread, NULL, ls_l, argv); if (res != 0) { perror ("Thread creation failed"); exit (EXIT_FAILURE); } res = pthread_join(ls_thread, &thread_result); printf("Waiting for ls_thread to finish...\n"); if (res != 0) { perror("Thread join failed"); exit (EXIT_FAILURE); } return 1; }