Made -update_r and -find -exec update safe against IsoDirIter pitfalls
This commit is contained in:
parent
1fb2576e93
commit
0dfc79bd4e
@ -1 +1 @@
|
|||||||
#define Xorriso_timestamP "2008.03.01.151219"
|
#define Xorriso_timestamP "2008.03.02.172751"
|
||||||
|
@ -2646,6 +2646,13 @@ dir_not_removed:;
|
|||||||
whereas iso_dir_iter_remove() removes the next node to come rather than
|
whereas iso_dir_iter_remove() removes the next node to come rather than
|
||||||
the most recently returned node.
|
the most recently returned node.
|
||||||
*/
|
*/
|
||||||
|
if(boss_iter!=NULL) {
|
||||||
|
sprintf(xorriso->info_text,
|
||||||
|
"Xorriso_rmi() was requested to delete iterated node %s",
|
||||||
|
Text_shellsafe(path, sfe, 0));
|
||||||
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
|
||||||
|
}
|
||||||
|
|
||||||
ret= iso_node_remove(victim_node);
|
ret= iso_node_remove(victim_node);
|
||||||
|
|
||||||
#endif /* Libisofs_iso_dir_iter_remove_repaireD */
|
#endif /* Libisofs_iso_dir_iter_remove_repaireD */
|
||||||
@ -3810,6 +3817,95 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The caller shall make no assumptions about the meaning of iter, node_array,
|
||||||
|
node_count, node_idx ! They are just opaque handles for which the caller
|
||||||
|
provides the memory of proper type.
|
||||||
|
@param flag bit0= initialize iteration
|
||||||
|
bit1= action needs full freedom of object manipulation
|
||||||
|
bit31= end iteration (mandatory !)
|
||||||
|
*/
|
||||||
|
int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node,
|
||||||
|
IsoDirIter **iter,
|
||||||
|
IsoNode ***node_array, int *node_count, int *node_idx,
|
||||||
|
IsoNode **iterated_node, int flag)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
IsoNode *node;
|
||||||
|
|
||||||
|
if(flag&1) {
|
||||||
|
*node_array= NULL;
|
||||||
|
*node_count= -1;
|
||||||
|
*node_idx= 0;
|
||||||
|
*iter= NULL;
|
||||||
|
ret= iso_dir_get_children(dir_node, iter);
|
||||||
|
if(ret<0) {
|
||||||
|
cannot_iter:;
|
||||||
|
Xorriso_cannot_create_iter(xorriso, ret, 0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if(flag&2) {
|
||||||
|
/* copy list of nodes and prepare soft iterator */
|
||||||
|
*node_count= 0;
|
||||||
|
while(iso_dir_iter_next(*iter, &node) == 1)
|
||||||
|
(*node_count)++;
|
||||||
|
iso_dir_iter_free(*iter);
|
||||||
|
*iter= NULL;
|
||||||
|
|
||||||
|
/* >>> check with temp mem limit */;
|
||||||
|
|
||||||
|
(*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *));
|
||||||
|
if(*node_array == NULL) {
|
||||||
|
sprintf(xorriso->info_text,
|
||||||
|
"Could not allocate inode list of %.lf bytes",
|
||||||
|
((double) (*node_count)+1) * (double) sizeof(IsoNode *));
|
||||||
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
||||||
|
*node_count= -1;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
ret= iso_dir_get_children(dir_node, iter);
|
||||||
|
if(ret<0)
|
||||||
|
goto cannot_iter;
|
||||||
|
while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) {
|
||||||
|
(*node_array)[*node_idx]= node;
|
||||||
|
iso_node_ref(node);
|
||||||
|
(*node_idx)++;
|
||||||
|
}
|
||||||
|
iso_dir_iter_free(*iter);
|
||||||
|
*iter= NULL;
|
||||||
|
*node_count= *node_idx;
|
||||||
|
*node_idx= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(flag&(1<<31)) {
|
||||||
|
if(*node_count>=0) {
|
||||||
|
for(i= 0; i<*node_count; i++)
|
||||||
|
iso_node_unref((*node_array)[i]);
|
||||||
|
free(*node_array);
|
||||||
|
*node_array= NULL;
|
||||||
|
*node_count= -1;
|
||||||
|
*node_idx= 0;
|
||||||
|
} else {
|
||||||
|
if(*iter!=NULL)
|
||||||
|
iso_dir_iter_free(*iter);
|
||||||
|
*iter= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(flag&(1|(1<<31)))
|
||||||
|
return(1);
|
||||||
|
if(*node_count>=0) {
|
||||||
|
/* return next node_array element */
|
||||||
|
if(*node_idx>=*node_count)
|
||||||
|
return(0);
|
||||||
|
*iterated_node= (*node_array)[*node_idx];
|
||||||
|
(*node_idx)++;
|
||||||
|
} else {
|
||||||
|
ret= iso_dir_iter_next(*iter, iterated_node);
|
||||||
|
return(ret == 1);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job,
|
int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job,
|
||||||
void *boss_iter,
|
void *boss_iter,
|
||||||
void *dir_node_generic, char *dir_path,
|
void *dir_node_generic, char *dir_path,
|
||||||
@ -3827,6 +3923,13 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job,
|
|||||||
#else /* Xorriso_fat_local_meM */
|
#else /* Xorriso_fat_local_meM */
|
||||||
char *path= NULL, *abs_path= NULL;
|
char *path= NULL, *abs_path= NULL;
|
||||||
|
|
||||||
|
#define Xorriso_findi_new_iteR yes
|
||||||
|
|
||||||
|
#ifdef Xorriso_findi_new_iteR
|
||||||
|
IsoNode **node_array= NULL;
|
||||||
|
int node_count, node_idx;
|
||||||
|
#endif
|
||||||
|
|
||||||
path= malloc(SfileadrL);
|
path= malloc(SfileadrL);
|
||||||
abs_path= malloc(SfileadrL);
|
abs_path= malloc(SfileadrL);
|
||||||
if(path==NULL || abs_path==NULL) {
|
if(path==NULL || abs_path==NULL) {
|
||||||
@ -3874,12 +3977,32 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job,
|
|||||||
if(!LIBISO_ISDIR((IsoNode *) dir_node))
|
if(!LIBISO_ISDIR((IsoNode *) dir_node))
|
||||||
{ret= 2; goto ex;}
|
{ret= 2; goto ex;}
|
||||||
|
|
||||||
|
#ifdef Xorriso_findi_new_iteR
|
||||||
|
|
||||||
|
ret= Xorriso_findi_iter(xorriso, dir_node,
|
||||||
|
&iter, &node_array, &node_count, &node_idx,
|
||||||
|
&node, 1|((action==17)<<1));
|
||||||
|
if(ret<=0)
|
||||||
|
goto ex;
|
||||||
|
while(1) {
|
||||||
|
ret= Xorriso_findi_iter(xorriso, dir_node, &iter, &node_array, &node_count,
|
||||||
|
&node_idx, &node, 0);
|
||||||
|
if(ret<0)
|
||||||
|
goto ex;
|
||||||
|
if(ret==0 || xorriso->request_to_abort)
|
||||||
|
break;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
ret= iso_dir_get_children(dir_node, &iter);
|
ret= iso_dir_get_children(dir_node, &iter);
|
||||||
if(ret<0) {
|
if(ret<0) {
|
||||||
Xorriso_cannot_create_iter(xorriso, ret, 0);
|
Xorriso_cannot_create_iter(xorriso, ret, 0);
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
}
|
}
|
||||||
while(iso_dir_iter_next(iter, &node) == 1 && !xorriso->request_to_abort) {
|
while(iso_dir_iter_next(iter, &node) == 1 && !xorriso->request_to_abort) {
|
||||||
|
|
||||||
|
#endif /* ! Xorriso_findi_new_iteR */
|
||||||
|
|
||||||
name= (char *) iso_node_get_name(node);
|
name= (char *) iso_node_get_name(node);
|
||||||
ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4);
|
ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
@ -3924,8 +4047,14 @@ ex:;
|
|||||||
#endif /* ! Xorriso_fat_local_meM */
|
#endif /* ! Xorriso_fat_local_meM */
|
||||||
|
|
||||||
Xorriso_process_msg_queues(xorriso,0);
|
Xorriso_process_msg_queues(xorriso,0);
|
||||||
|
|
||||||
|
#ifdef Xorriso_findi_new_iteR
|
||||||
|
Xorriso_findi_iter(xorriso, dir_node, &iter, &node_array, &node_count,
|
||||||
|
&node_idx, &node, (1<<31));
|
||||||
|
#else
|
||||||
if(iter!=NULL)
|
if(iter!=NULL)
|
||||||
iso_dir_iter_free(iter);
|
iso_dir_iter_free(iter);
|
||||||
|
#endif
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user