Embedded Linux CP Command implementation

Source: Internet
Author: User
Tags sprintf strcmp

Recent projects in the data export when the problem occurs, the basic idea is:

First Vfork Create a process, the child process creates 2 threads, thread 1 is responsible for the interface display, thread 2 is responsible for the data copy; The parent process saves the configuration file and exits the application;

Where thread 2 also creates a process to invoke the System CP command, and Threads 1 Vfork uses the class System command function to send the KILL command to kill the CP copy (kill-9 $ (pgrep cp));

Through the above ideas, you can know, design chaos, threads constantly create processes, processes and threads, at least brother also programming several years, how can tolerate such rubbish code exists, leisure time, change;


New ideas:

Implementation of the CP command, display interface to the timer processing;

But the question is how I cancel when I copy the data, if a file is too large what to do, the workaround is: Define a callback function, in the condition of the loop also use the return value of the function, the callback function return value is a global variable, can be resolved.


Here is the demo program:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include < time.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <sys/time.h> #include <sys/time.h> #include <errno.h> #include <dirent.h> #define Max_ Path_len (enum{false,true}bool;typedef) typedef enum{cp_skip, Cp_continue,cp_cancel, Cp_error,}status_cp;typedef Signed long long int64s;typedef unsigned long long int64u;typedef signed int int32s;typedef unsigned int I Nt32u;typedef signed short int16s;typedef unsigned short int16u;typedef signed char int8s;typedef Unsigne  D Char int8u;typedef BOOL (*oops_func) (void), typedef void (*sig_handler_t) (int), char note_text[300];char animate[4] = {'-', '/', '|', '\\'};  unsigned int animate_pos = 0;signed long Long total_size = 0;signed long Long copied_size = 0;signed long long percent = 0;void Timer_handler (int signum) {printf ("\ r%s%c", Note_text, animate[(animate_pos++)%4]); Fflush (stdout);} /* Create/Destroy Timer */void Install_timer (size_t sec, sig_handler_t handler_func) {struct sigaction act;struct itimerval tick;if (s EC > 0) {act.sa_handler = Handler_func;} Else{act.sa_handler = SIG_DFL;} Sigemptyset (&act.sa_mask); act.sa_flags = 0;sigaction (sigalrm, &act, 0); memset (&tick, 0, sizeof (tick)); Tick.it_value.tv_sec = Sec;tick.it_value.tv_usec = 0;tick.it_interval.tv_sec = Sec;tick.it_interval.tv_usec = 0;setiti Mer (Itimer_real, &tick, 0);}    int open_file (const char *_filename, int _flag, mode_t _mode) {int FD = 0;    FD = open (_filename, _flag, _mode);    if (FD < 0) {perror ("open:"); } return FD; int copy_file (const char *src_file, const char *des_file, Oops_func cancel_cp) {#define PRE_FRAMESIZE_CP 1024x768 char Buffe    R[pre_framesize_cp];char *ptr = NULL;    int nbytes_rd = 0;//bytes per read int nbytes_wr = 0;//bytes written per byte int loop_times = 0;int src_fd =-1; int DES_FD = -1;if (Src_file = = NULL | | des_file = NULL) {return-1;}    SRC_FD = Open_file (Src_file, o_rdonly, 0666); DES_FD = Open_file (des_file, O_creat | o_wronly |    O_trunc, 0666); if (src_fd < 0 | | des_fd < 0) {return-2;} /* The code below is a classic copy of the file's code */while (!CANCEL_CP () && (nbytes_rd = Read (src_fd, buffer, PRE_FRAMESIZE_CP))/* * Read from the source file every time   Take 1KB data to buf*/{if (loop_times%10 = = 0)//per read 1MB, pause copy to avoid affecting other processes or threads such as display operations {//usleep (1); loop_times = 0; }if ((Nbytes_rd = =-1) && (errno! = eintr)) {printf ("(bytesread==-1) && (errno!=eintr) \ n"); goto Copy_err;} else if (Nbytes_rd > 0) {ptr = Buffer;while (!CANCEL_CP () && (Nbytes_wr=write (DES_FD, PTR, nbytes_rd))) {/                   /printu ("NBYTES_WR =%d\n", NBYTES_WR);         if ((NBYTES_WR = =-1) && (errno! = eintr))/* A fatal error occurred */{goto copy_err;         } else if (NBYTES_WR = = nbytes_rd)/* Writes all read bytes */{break;}  else if (nbytes_wr > 0)/* Write only a portion, continue writing */{       PTR + = NBYTES_WR;         NBYTES_RD-= NBYTES_WR;   }} if (NBYTES_WR = =-1)/* Fatal error occurred while writing */{goto copy_err;    }}loop_times++;//loop execution count, to a certain number of times to perform an action} close (SRC_FD);    Close (DES_FD); Sync ();    Time delay when data copy is completed-prevent delay return 0; COPY_ERR:SRC_FD > 0? Close (SRC_FD):(src_fd =-1);d es_fd > 0?   Close (DES_FD):(des_fd =-1);    Sync (); return-3;} /* Connection directory string, main processing end/problem, frt snd two parameters can not be empty at the same time no meaning */char* Make_path (char *dest, const char *FRT, const char *snd) {if (NULL = = fr T | | strlen (frt) = = 0) {sprintf (dest, "%s", snd);} else if (NULL = = SND | | strlen (SND) = = 0) {sprintf (dest, "%s", frt);} Else{if (Frt[strlen (FRT)-1] = = '/') {sprintf (dest, "%s%s", Frt, snd);} else{sprintf (dest, "%s/%s", Frt, SND);}} return dest;} int Cp_cmd (const char* path_from, const char* path_to, const char* path_tree, Oops_func cancel_cp) {char path_tree_new[max_ Path_len];char Path_from_full[max_path_len];char path_to_full[max_path_len];int ret_val = CP_CONTINUE;struct Stat st; StRuct dirent *entry = Null;dir *dir = null;if (errno = erofs)//read-only file system, stop copying {//perror (""); return cp_error;} if (CANCEL_CP () = = TRUE) {return cp_cancel;} /* Parameter Legality detection */if (Path_from = = NULL | | path_to = = NULL) {return cp_skip;} /* Get the properties of the copy source */make_path (Path_from_full, Path_from, Path_tree), if ( -1 = = Stat (path_from_full, &st)) {fprintf (stderr, "Can ' t access \"%s\ ". \ n", path_from_full); return cp_skip;} /* If the directory is browsing, otherwise end */if (! S_isdir (St.st_mode)) {return cp_continue;} /* Open Directory */if (!) ( dir = Opendir (path_from_full))) {fprintf (stderr, "can ' t Open Directory \"%s\ ". \ n", path_from_full); return cp_skip;}  /* Traverse directory */while (!CANCEL_CP () && (entry = Readdir (dir)) = NULL) {/* build directory Path_tree_new */make_path (path_tree_new, Path_tree, Entry->d_name) Make_path (Path_from_full, Path_from, path_tree_new);/* Cannot access the skip */if ( -1 = = Stat (path_ From_full, &st) {fprintf (stderr, "Skip, can ' t access%s.\n", path_from_full); continue;} /* Ignore. And.. */if (S_isdir (St.st_mode) && (strcmp (".", entry->d_name) = = 0 | | strcmp ("..", entry->d_name) = = 0)) {continue;} if (S_isdir (St.st_mode)) {Make_path (Path_to_full, path_to, path_tree_new);/*try to make a new directory*/if (0 = = mkdir ( Path_to_full, St.st_mode)) {chmod (path_to_full, St.st_mode);}    Else{perror ("mkdir:");//fprintf (stderr, "Skip, \"%s\ "mkdir failed.\n", path_to_full); continue;} /* Recursive processing subdirectory */if (Cp_cmd (Path_from, path_to, path_tree_new, cancel_cp) = = cp_cancel) {ret_val = Cp_cancel;break;}} else if (S_isreg (St.st_mode))//can only copy ordinary files, skip character device files, block device files, FIFO files, soft links and other files {Make_path (Path_to_full, path_to, Path_tree_ new); ret_val = Copy_file (Path_from_full, Path_to_full, CANCEL_CP); if (ret_val = = Cp_error) {break;} Copied_size + = St.st_size; if (total_size > 0)//{percent = Copied_size * 100/total_size;} sprintf (Note_text, "%s:%lld B,%s:%lld B. (%d%)", "Total", total_size, "Copied", Copied_size, (int) percent)        ; }}closedir (dir); return ret_val;}    Signed Long long getdirallfilesize (const char *path) {DIR *dir; struct Dirent *Entry    struct stat stat_buf;    Signed Long Long totalsize = 0;char tmppathname[256];        if (dir = opendir (path)) = = NULL) {printf ("Cannot open dir:%s\n", path);    return 0;        } while ((Entry = Readdir (dir)) = NULL) {strcpy (tmppathname, path);        if (Path[strlen (path)-1]! = '/') {strcat (Tmppathname, "/");        } strcat (Tmppathname, entry->d_name);        Lstat (Tmppathname, &stat_buf);                if (S_isdir (Stat_buf.st_mode) && 0! = strcmp (Entry->d_name, ".")        && 0! = strcmp (Entry->d_name, ".."))        {totalsize + = Getdirallfilesize (tmppathname);        } else if (0! = strcmp (Entry->d_name, ".") && 0! = strcmp (Entry->d_name, ".."))        {totalsize + = stat_buf.st_size;    }} closedir (dir); return totalsize;} pthread_t tid1;pthread_t Tid2; BOOL g_bcpcancel = FALSE; BOOL cb_cancel_cp (void) {return g_bcpcancel;} void *thd_func_cOunter (void *args) {int loop_counter = 0;char ch;//sleep (3), while (1) {scanf ("%c", &ch), if (ch = = ' C ') {G_bcpcancel = TRU E;break;} Sleep (1);}} Char From_path[128];char to_path[128];void *thd_func_copyfile (void *args) {sprintf (Note_text, "Calc all file size, Please wait ... "); total_size = Getdirallfilesize (From_path); sprintf (Note_text,"%s:%lld kb,%s:%lld KB. (   %d percent) "," Total ", total_size>>10," Copied ", copied_size>>10, (int) percent); Cp_cmd (From_path, To_path, NULL, CB_CANCEL_CP), sync ();p thread_cancel (TID1); sleep (1);} int main (int argc, char *argv[]) {//create 2 threads, one thread can end the copy at any time//Another thread copies data Install_timer (1, Timer_handler); strcpy (from _path, argv[1]), strcpy (To_path, argv[2]);p thread_create (&AMP;TID1, NULL, thd_func_counter, NULL);p thread_create ( &tid2, NULL, thd_func_copyfile, NULL);p thread_join (TID1, NULL);p thread_join (TID2, null); Install_timer (0, Timer_ Handler);p rintf ("\ n"); return 0;}

Remember to add the-lpthread parameter at compile time.


Embedded Linux CP Command implementation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.