diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 26405026..dcaebeb6 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "May 14, 2009" +.TH XORRISO 1 "May 17, 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -1288,6 +1288,12 @@ is performed if the decision is "yes" or "true". See operator -if. \fB\-true\fR and \fB\-false\fR : Always match resp. match not. Evaluation goes on. .br +\fB\-sort_lba\fR : +Always match. This causes -find to perform its action in a sequence sorted by +the ISO image block addresses of the files. It may improve throughput with +actions which read data from optical drives. Action will always get the +absolute path as parameter. +.br Available operators are: .br \fB\-not\fR : diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 3eb9f7d9..dbd4c6bc 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -2898,12 +2898,17 @@ int Findjob_new_node(struct FindjoB *job, struct ExprnodE **fnode, } -/* If an operator is expected : use -and */ +/* If an operator is expected : use -and + @param flag bit0= prepare for a pseudo-test: + if an operator is expected, do nothing and return 2 +*/ int Findjob_default_and(struct FindjoB *o, int flag) { int ret; if(Findjob_cursor_complete(o, 0)) { + if(flag & 1) + return(2); ret= Findjob_and(o, 0); if(ret <= 0) return(ret); @@ -3212,6 +3217,8 @@ int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag) /* @param value -1= only without property, 1= only with property + @param flag bit0= pseudo-test: + if no operator is open, do nothing and return 2 */ int Findjob_set_prop_filter(struct FindjoB *o, int test_type, int value, int flag) @@ -3219,8 +3226,8 @@ int Findjob_set_prop_filter(struct FindjoB *o, int test_type, int value, struct ExprtesT *t; int ret; - ret= Findjob_default_and(o, 0); - if(ret <= 0) + ret= Findjob_default_and(o, flag & 1); + if(ret <= 0 || ret == 2) return(ret); t= o->cursor->test; @@ -3359,12 +3366,14 @@ int Findjob_set_decision(struct FindjoB *o, char *decision, int flag) /* @param value -1= true, 1= false + @param flag bit0= pseudo-test: + if no operator is open, do nothing and return 2 */ int Findjob_set_false(struct FindjoB *o, int value, int flag) { int ret; - ret= Findjob_set_prop_filter(o, 0, value, 0); + ret= Findjob_set_prop_filter(o, 0, value, flag & 1); return(ret); } @@ -14765,6 +14774,7 @@ ex:; do not reset find_compare_result bit2= do not count deleted files with rm and rm_r bit3= use Xorriso_findi_sorted() rather than Xorriso_findi() + (this can also be ordered by test -sort_lba) */ int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) @@ -14905,6 +14915,12 @@ not_enough_arguments:; #endif /* Xorriso_findjob_on_expR */ + } else if(strcmp(argv[i], "-sort_lba") == 0) { + flag|= 8; + /* If an operator is open: insert a -true test, else do nothing */ + ret= Findjob_set_false(job, -1, 1); + if(ret == 2) + ret= 1; } else if(strcmp(argv[i], "-exec")==0) { if(i+1>=end_idx) { not_enough_exec_arguments:; @@ -15103,7 +15119,7 @@ sorry_ex:; 0); else if(flag & 8) { cpt= start_path; - ret= Xorriso_findi_sorted(xorriso, first_job, 1, &cpt, 0); + ret= Xorriso_findi_sorted(xorriso, first_job, (off_t) 0, 1, &cpt, 0); } else ret= Xorriso_findi(xorriso, first_job, NULL, (off_t) 0, NULL, start_path, &dir_stbuf, 0, (flag&4)>>1); @@ -18855,9 +18871,6 @@ next_command:; } else if(strcmp(cmd,"find")==0 || strcmp(cmd,"findi")==0) { ret= Xorriso_option_find(xorriso, argc, argv, idx, 0); - } else if(strcmp(cmd,"find_sorted")==0) { - ret= Xorriso_option_find(xorriso, argc, argv, idx, 8); - } else if(strcmp(cmd,"findx")==0) { ret= Xorriso_option_find(xorriso, argc, argv, idx, 1); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index ced79313..930788a1 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.05.16.165940" +#define Xorriso_timestamP "2009.05.17.115101" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index d3025618..a2dae3ec 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -7345,23 +7345,32 @@ int Xorriso__findi_sorted_cmp(const void *p1, const void *p2) bit1= do not perform job->action on resulting node array */ int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, - int filec, char **filev, int flag) + off_t boss_mem, int filec, char **filev, int flag) { int i, ret; - struct FindjoB array_job; + struct FindjoB array_job, *proxy_job= NULL, *hindmost= NULL, *hmboss= NULL; struct stat dir_stbuf; IsoNode *node; char abs_path[SfileadrL]; + off_t mem_needed= 0; + + array_job.start_path= NULL; - /* <<< */ if(job->action>=9 && job->action<=13) { /* actions which have own findjobs */ - - /* >>> cannot deal with chained find yet */; - - return(-1); + /* array_job replaces the hindmost job in the chain */ + for(hindmost= job; hindmost->subjob != NULL; hindmost= hindmost->subjob) + hmboss= hindmost; + if(hmboss == NULL) + {ret= -1; goto ex;} + memcpy(&array_job, hindmost, sizeof(struct FindjoB)); + hmboss->subjob= &array_job; + proxy_job= job; + } else { + memcpy(&array_job, job, sizeof(struct FindjoB)); + proxy_job= &array_job; + hindmost= job; } - /* >>> if action == find : array_job would need to replace the hindmost */ - memcpy(&array_job, job, sizeof(struct FindjoB)); + array_job.start_path= NULL; /* is owned by the original, not by array_job */ /* Count matching nodes */ Xorriso_destroy_node_array(xorriso, 0); @@ -7371,14 +7380,37 @@ int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, xorriso->node_counter++; continue; } - array_job.start_path= filev[i]; - ret= Xorriso_findi(xorriso, &array_job, NULL, (off_t) 0, NULL, + ret= Findjob_set_start_path(proxy_job, filev[i], 0); + if(ret <= 0) + goto ex; + ret= Xorriso_findi(xorriso, proxy_job, NULL, boss_mem, NULL, filev[i], &dir_stbuf, 0, 0); if(ret <= 0) goto ex; } if(xorriso->node_counter <= 0) - return(1); + {ret= 1; goto ex;} + + mem_needed= boss_mem + xorriso->node_counter * sizeof(IsoNode *); + if(!(flag &1)) { + ret= Xorriso_check_temp_mem_limit(xorriso, mem_needed, 0); + if(ret <= 0) { + /* Memory curbed : Perform unsorted find jobs */ + if(hmboss != NULL) + hmboss->subjob= hindmost; + for(i= 0; i < filec; i++) { + ret= Findjob_set_start_path(job, filev[i], 0); + if(ret <= 0) + goto ex; + ret= Xorriso_findi(xorriso, job, NULL, boss_mem, NULL, + filev[i], &dir_stbuf, 0, 0); + if(ret <= 0) + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } + {ret= 1; goto ex;} + } + } /* Copy matching nodes into allocated array */ xorriso->node_array_size= xorriso->node_counter; @@ -7399,8 +7431,10 @@ int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, continue; } - array_job.start_path= filev[i]; - ret= Xorriso_findi(xorriso, &array_job, NULL, (off_t) 0, NULL, + ret= Findjob_set_start_path(proxy_job, filev[i], 0); + if(ret <= 0) + goto ex; + ret= Xorriso_findi(xorriso, proxy_job, NULL, mem_needed, NULL, filev[i], &dir_stbuf, 0, 0); if(ret <= 0) goto ex; @@ -7409,18 +7443,15 @@ int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, Xorriso__findi_sorted_cmp); if(flag & 2) - return(1); - - /* Perform job->action on xorriso->node_array */; - - /* >>> if action == find : perform action of the hindmost */ + {ret= 1; goto ex;} + /* Perform job->action on xorriso->node_array */ for(i= 0; i < xorriso->node_counter; i++) { node= xorriso->node_array[i]; ret= Xorriso_path_from_node(xorriso, node, abs_path, 0); if(ret <= 0) goto ex; - ret= Xorriso_findi_action(xorriso, job, NULL, (off_t) 0, + ret= Xorriso_findi_action(xorriso, hindmost, NULL, (off_t) 0, abs_path, abs_path, node, 0, 1); if(ret <= 0) if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) @@ -7429,6 +7460,10 @@ int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, ret= 1; ex:; + if(hmboss != NULL) + hmboss->subjob= hindmost; + if(array_job.start_path != NULL) + free(array_job.start_path); return(ret); }