- avoid assertion failure due to access permissions (#579476)
This commit is contained in:
		
							parent
							
								
									9517481aff
								
							
						
					
					
						commit
						8440b32a33
					
				
							
								
								
									
										586
									
								
								findutils-4.5.7-bz579476.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										586
									
								
								findutils-4.5.7-bz579476.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,586 @@ | |||||||
|  |  ChangeLog        |   74 ++++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  NEWS             |    1 + | ||||||
|  |  find/defs.h      |   12 ++++++- | ||||||
|  |  find/find.c      |    8 +++-- | ||||||
|  |  find/ftsfind.c   |   53 ++++++++++++++++------------------ | ||||||
|  |  find/parser.c    |   10 +++--- | ||||||
|  |  find/pred.c      |    8 ++-- | ||||||
|  |  find/sharefile.c |    2 +- | ||||||
|  |  find/tree.c      |    1 + | ||||||
|  |  find/util.c      |   83 ++++++++++++++++++++++++++++++++++++++++++----------- | ||||||
|  |  10 files changed, 191 insertions(+), 61 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/ChangeLog b/ChangeLog
 | ||||||
|  | index abe1993..8bcae9b 100644
 | ||||||
|  | --- a/ChangeLog
 | ||||||
|  | +++ b/ChangeLog
 | ||||||
|  | @@ -1,3 +1,77 @@
 | ||||||
|  | + 2010-04-05  James Youngman  <jay@gnu.org>
 | ||||||
|  | + 
 | ||||||
|  | +	Don't issue an error message twice for the same target file.
 | ||||||
|  | +	* find/defs.h (struct state): New member,
 | ||||||
|  | +	already_issued_stat_error_msg, used to de-duplicate error
 | ||||||
|  | +	messages.  If it is true, we already issued an error message for
 | ||||||
|  | +	the current target file.
 | ||||||
|  | +	Declare fatal_target_file_error, fatal_nontarget_file_error,
 | ||||||
|  | +	nonfatal_target_file_error, nonfatal_nontarget_file_error.
 | ||||||
|  | +	Between them, they replace fatal_file_error and
 | ||||||
|  | +	nonfatal_file_error.  The *target_file_error versions are
 | ||||||
|  | +	de-duplicated and the nontarget_file_error_versions are not.
 | ||||||
|  | +	* find/util.c (nonfatal_nontarget_file_error): Implement.
 | ||||||
|  | +	(fatal_nontarget_file_error): Implement.
 | ||||||
|  | +	(nonfatal_target_file_error): Implement.
 | ||||||
|  | +	(fatal_target_file_error): Implement.
 | ||||||
|  | +	(fatal_file_error): Remove.
 | ||||||
|  | +	(nonfatal_file_error): Remove.
 | ||||||
|  | +	(error_severity): Define error_severity (moved from ftsfind.c)
 | ||||||
|  | +	(get_statinfo): Call nonfatal_target_file_error in order to avoid
 | ||||||
|  | +	a duplicate message.  ALso call error_severity after a different
 | ||||||
|  | +	call to error to preserve the constraint that we exit with a
 | ||||||
|  | +	nonzero status if we issue a diagnostic.
 | ||||||
|  | +	(cleanup): Call nonfatal_nontarget_file_error instead of
 | ||||||
|  | +	nonfatal_file_error.
 | ||||||
|  | +	* find/tree.c (build_expression_tree): Initialise
 | ||||||
|  | +	state.already_issued_stat_error_msg.
 | ||||||
|  | +	* find/find.c (main): Initialise state.already_issued_stat_error_msg.
 | ||||||
|  | +	(wd_sanity_check): Call fatal_target_file_error instead of
 | ||||||
|  | +	fatal_file_error.
 | ||||||
|  | +	(chdir_back): Call fatal_nontarget_file_error instead of
 | ||||||
|  | +	fatal_file_error.
 | ||||||
|  | +	(process_path): Initialise state.already_issued_stat_error_msg.
 | ||||||
|  | +	* find/ftsfind.c (consider_visiting): Call
 | ||||||
|  | +	nonfatal_target_file_error instead of calling error directly.
 | ||||||
|  | +	(find): Call error_severity to ensure exit status is nonzero after
 | ||||||
|  | +	a call to error.
 | ||||||
|  | +	(main): Initialise state.already_issued_stat_error_msg.
 | ||||||
|  | +	(error_severity): Move to util.c.
 | ||||||
|  | +	* find/parser.c (collect_arg_stat_info): Call
 | ||||||
|  | +	fatal_target_file_error instead of fatal_file_error.
 | ||||||
|  | +	(parse_newerXY): Likewise.
 | ||||||
|  | +	(parse_samefile): Likewise.
 | ||||||
|  | +	(parse_samefile): Likewise.
 | ||||||
|  | +	(open_output_file): Call fatal_nontarget_file_error instead of
 | ||||||
|  | +	fatal_file_error.
 | ||||||
|  | +	* find/pred.c (checked_fprintf): Likewise.
 | ||||||
|  | +	(checked_print_quoted): Likewise.
 | ||||||
|  | +	(checked_fwrite): Likewise.
 | ||||||
|  | +	(checked_fflush): Likewise.
 | ||||||
|  | +	* find/sharefile.c (entry_free): Likewise.
 | ||||||
|  | +
 | ||||||
|  | +	Fix Savannah bug #29435: fd_is_cloexec does not work on Fedora
 | ||||||
|  | +	buildhosts.
 | ||||||
|  | +	Fix open_cloexec on hosts which ignore O_CLOEXEC (i.e. old kernels).
 | ||||||
|  | +	* lib/fdleak.c (o_cloexec_works): New function, detects whether
 | ||||||
|  | +	the open flag O_CLOEXEC has any effect.
 | ||||||
|  | +	(open_cloexec): Call o_cloexec_works, just once, to find out
 | ||||||
|  | +	whether O_CLOEXEC is effective.  If not, set the close-on-exec
 | ||||||
|  | +	flag on fds by calling set_cloexec_flag.
 | ||||||
|  | +	* NEWS: Mention this bugfix.
 | ||||||
|  | +
 | ||||||
|  | +2010-04-04  Martin von Gagern  <Martin.vGagern@gmx.net>
 | ||||||
|  | +
 | ||||||
|  | +	Fix Savannah bug #27213: avoid failed assertions for
 | ||||||
|  | +	non-executable directories.
 | ||||||
|  | +	(consider_visiting): Continue (after issuing an error message)
 | ||||||
|  | +	even if ent->fts_info == FTS_NS.
 | ||||||
|  | +	* find/util.c (get_statinfo): If we cannot stat the file, issue a
 | ||||||
|  | +	diagnostic, but continue anyway.
 | ||||||
|  | +	* find/ftsfind.c (consider_visiting): Don't assert-fail if
 | ||||||
|  | +	ent->fts_info == FTS_NSOK.  Don't assert-fail if state.type is
 | ||||||
|  | +	nonzero.
 | ||||||
|  | +
 | ||||||
|  |  2010-04-04  James Youngman  <jay@gnu.org> | ||||||
|  |   | ||||||
|  |  	Fix Savannah bug #29435: fd_is_cloexec does not work on Fedora | ||||||
|  | diff --git a/NEWS b/NEWS
 | ||||||
|  | index e171b87..3f81b88 100644
 | ||||||
|  | --- a/NEWS
 | ||||||
|  | +++ b/NEWS
 | ||||||
|  | @@ -4,6 +4,7 @@ GNU findutils NEWS - User visible changes.      -*- outline -*- (allout)
 | ||||||
|  |   | ||||||
|  |  #29435: fd_is_cloexec does not work on Fedora buildhosts | ||||||
|  |   | ||||||
|  | +#27213: avoid failed assertions for non-executable directories.
 | ||||||
|  |   | ||||||
|  |  * Major changes in release 4.5.7, 2010-04-03 | ||||||
|  |   | ||||||
|  | diff --git a/find/defs.h b/find/defs.h
 | ||||||
|  | index 4ade8f4..b2e255a 100644
 | ||||||
|  | --- a/find/defs.h
 | ||||||
|  | +++ b/find/defs.h
 | ||||||
|  | @@ -504,11 +504,16 @@ extern boolean check_nofollow(void);
 | ||||||
|  |  void complete_pending_execs(struct predicate *p); | ||||||
|  |  void complete_pending_execdirs(int dir_fd); /* Passing dir_fd is an unpleasant CodeSmell. */ | ||||||
|  |  const char *safely_quote_err_filename (int n, char const *arg); | ||||||
|  | -void fatal_file_error(const char *name) ATTRIBUTE_NORETURN;
 | ||||||
|  | -void nonfatal_file_error(const char *name);
 | ||||||
|  | +
 | ||||||
|  | +void fatal_target_file_error (int errno_value, const char *name) ATTRIBUTE_NORETURN;
 | ||||||
|  | +void fatal_nontarget_file_error (int errno_value, const char *name) ATTRIBUTE_NORETURN;
 | ||||||
|  | +void nonfatal_target_file_error (int erron_value, const char *name);
 | ||||||
|  | +void nonfatal_nontarget_file_error (int erron_value, const char *name);
 | ||||||
|  | +
 | ||||||
|  |   | ||||||
|  |  int process_leading_options PARAMS((int argc, char *argv[])); | ||||||
|  |  void set_option_defaults PARAMS((struct options *p)); | ||||||
|  | +void error_severity PARAMS((int level));
 | ||||||
|  |   | ||||||
|  |  #if 0 | ||||||
|  |  #define apply_predicate(pathname, stat_buf_ptr, node)	\ | ||||||
|  | @@ -669,6 +674,9 @@ struct state
 | ||||||
|  |   | ||||||
|  |    /* Shared files, opened via the interface in sharefile.h. */ | ||||||
|  |    sharefile_handle shared_files; | ||||||
|  | +
 | ||||||
|  | +  /* Avoid multiple error messages for the same file. */
 | ||||||
|  | +  boolean already_issued_stat_error_msg;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* finddata.c */ | ||||||
|  | diff --git a/find/find.c b/find/find.c
 | ||||||
|  | index 336e120..e058814 100644
 | ||||||
|  | --- a/find/find.c
 | ||||||
|  | +++ b/find/find.c
 | ||||||
|  | @@ -135,6 +135,7 @@ main (int argc, char **argv)
 | ||||||
|  |        remember_non_cloexec_fds (); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | +  state.already_issued_stat_error_msg = false;
 | ||||||
|  |    state.shared_files = sharefile_init ("w"); | ||||||
|  |    if (NULL == state.shared_files) | ||||||
|  |      { | ||||||
|  | @@ -472,7 +473,7 @@ wd_sanity_check (const char *thing_to_stat,
 | ||||||
|  |   | ||||||
|  |    set_stat_placeholders (newinfo); | ||||||
|  |    if ((*options.xstat) (current_dir, newinfo) != 0) | ||||||
|  | -    fatal_file_error (thing_to_stat);
 | ||||||
|  | +    fatal_target_file_error (errno, thing_to_stat);
 | ||||||
|  |   | ||||||
|  |    if (old_dev != newinfo->st_dev) | ||||||
|  |      { | ||||||
|  | @@ -943,7 +944,7 @@ chdir_back (void)
 | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |        if (chdir (starting_dir) != 0) | ||||||
|  | -	fatal_file_error (starting_dir);
 | ||||||
|  | +	fatal_nontarget_file_error (errno, starting_dir);
 | ||||||
|  |   | ||||||
|  |        wd_sanity_check (starting_dir, | ||||||
|  |  		       program_name, | ||||||
|  | @@ -962,7 +963,7 @@ chdir_back (void)
 | ||||||
|  |   | ||||||
|  |        if (fchdir (starting_desc) != 0) | ||||||
|  |  	{ | ||||||
|  | -	  fatal_file_error (starting_dir);
 | ||||||
|  | +	  fatal_nontarget_file_error (errno, starting_dir);
 | ||||||
|  |  	} | ||||||
|  |      } | ||||||
|  |  } | ||||||
|  | @@ -1183,6 +1184,7 @@ process_path (char *pathname, char *name, boolean leaf, char *parent,
 | ||||||
|  |    state.type = 0; | ||||||
|  |    state.have_stat = false; | ||||||
|  |    state.have_type = false; | ||||||
|  | +  state.already_issued_stat_error_msg = false;
 | ||||||
|  |   | ||||||
|  |    if (!digest_mode (&mode, pathname, name, &stat_buf, leaf)) | ||||||
|  |      return 0; | ||||||
|  | diff --git a/find/ftsfind.c b/find/ftsfind.c
 | ||||||
|  | index b3a08f9..692d9f5 100644
 | ||||||
|  | --- a/find/ftsfind.c
 | ||||||
|  | +++ b/find/ftsfind.c
 | ||||||
|  | @@ -173,18 +173,6 @@ inside_dir (int dir_fd)
 | ||||||
|  |  static void init_mounted_dev_list (void); | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | -/* We have encountered an error which should affect the exit status.
 | ||||||
|  | - * This is normally used to change the exit status from 0 to 1.
 | ||||||
|  | - * However, if the exit status is already 2 for example, we don't want to
 | ||||||
|  | - * reduce it to 1.
 | ||||||
|  | - */
 | ||||||
|  | -static void
 | ||||||
|  | -error_severity (int level)
 | ||||||
|  | -{
 | ||||||
|  | -  if (state.exit_status < level)
 | ||||||
|  | -    state.exit_status = level;
 | ||||||
|  | -}
 | ||||||
|  | -
 | ||||||
|  |   | ||||||
|  |  #define STRINGIFY(X) #X | ||||||
|  |  #define HANDLECASE(N) case N: return #N; | ||||||
|  | @@ -371,9 +359,6 @@ show_outstanding_execdirs (FILE *fp)
 | ||||||
|  |        /* No debug output is wanted. */ | ||||||
|  |      } | ||||||
|  |  } | ||||||
|  | -
 | ||||||
|  | -
 | ||||||
|  | -
 | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  consider_visiting (FTS *p, FTSENT *ent) | ||||||
|  | @@ -410,15 +395,13 @@ consider_visiting (FTS *p, FTSENT *ent)
 | ||||||
|  |    if (ent->fts_info == FTS_ERR | ||||||
|  |        || ent->fts_info == FTS_DNR) | ||||||
|  |      { | ||||||
|  | -      error (0, ent->fts_errno, "%s",
 | ||||||
|  | -	     safely_quote_err_filename (0, ent->fts_path));
 | ||||||
|  | -      error_severity (1);
 | ||||||
|  | +      nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
 | ||||||
|  |        return; | ||||||
|  |      } | ||||||
|  |    else if (ent->fts_info == FTS_DC) | ||||||
|  |      { | ||||||
|  |        issue_loop_warning (ent); | ||||||
|  | -      error_severity (1);
 | ||||||
|  | +      error_severity (EXIT_FAILURE);
 | ||||||
|  |        return; | ||||||
|  |      } | ||||||
|  |    else if (ent->fts_info == FTS_SLNONE) | ||||||
|  | @@ -432,8 +415,7 @@ consider_visiting (FTS *p, FTSENT *ent)
 | ||||||
|  |         */ | ||||||
|  |        if (symlink_loop (ent->fts_accpath)) | ||||||
|  |  	{ | ||||||
|  | -	  error (0, ELOOP, "%s", safely_quote_err_filename (0, ent->fts_path));
 | ||||||
|  | -	  error_severity (1);
 | ||||||
|  | +	  nonfatal_target_file_error (ELOOP, ent->fts_path);
 | ||||||
|  |  	  return; | ||||||
|  |  	} | ||||||
|  |      } | ||||||
|  | @@ -442,9 +424,7 @@ consider_visiting (FTS *p, FTSENT *ent)
 | ||||||
|  |        if (ent->fts_level == 0) | ||||||
|  |  	{ | ||||||
|  |  	  /* e.g., nonexistent starting point */ | ||||||
|  | -	  error (0, ent->fts_errno, "%s",
 | ||||||
|  | -		 safely_quote_err_filename (0, ent->fts_path));
 | ||||||
|  | -	  error_severity (1);	/* remember problem */
 | ||||||
|  | +	  nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
 | ||||||
|  |  	  return; | ||||||
|  |  	} | ||||||
|  |        else | ||||||
|  | @@ -454,11 +434,24 @@ consider_visiting (FTS *p, FTSENT *ent)
 | ||||||
|  |  	   */ | ||||||
|  |  	  if (symlink_loop (ent->fts_accpath)) | ||||||
|  |  	    { | ||||||
|  | -	      error (0, ELOOP, "%s",
 | ||||||
|  | -		     safely_quote_err_filename (0, ent->fts_path));
 | ||||||
|  | -	      error_severity (1);
 | ||||||
|  | +	      nonfatal_target_file_error (ELOOP, ent->fts_path);
 | ||||||
|  |  	      return; | ||||||
|  |  	    } | ||||||
|  | +	  else
 | ||||||
|  | +	    {
 | ||||||
|  | +	      nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
 | ||||||
|  | +	      /* Continue despite the error, as file name without stat info
 | ||||||
|  | +	       * might be better than not even processing the file name. This
 | ||||||
|  | +	       * can lead to repeated error messages later on, though, if a
 | ||||||
|  | +	       * predicate requires stat information.
 | ||||||
|  | +	       *
 | ||||||
|  | +	       * Not printing an error message here would be even more wrong,
 | ||||||
|  | +	       * though, as this could cause the contents of a directory to be
 | ||||||
|  | +	       * silently ignored, as the directory wouldn't be identified as
 | ||||||
|  | +	       * such.
 | ||||||
|  | +	       */
 | ||||||
|  | +	    }
 | ||||||
|  | +
 | ||||||
|  |  	} | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | @@ -467,7 +460,7 @@ consider_visiting (FTS *p, FTSENT *ent)
 | ||||||
|  |        || ent->fts_info == FTS_NS /* e.g. symlink loop */) | ||||||
|  |      { | ||||||
|  |        assert (!state.have_stat); | ||||||
|  | -      assert (ent->fts_info == FTS_NSOK || state.type != 0);
 | ||||||
|  | +      assert (ent->fts_info == FTS_NSOK || state.type == 0);
 | ||||||
|  |        mode = state.type; | ||||||
|  |      } | ||||||
|  |    else | ||||||
|  | @@ -621,11 +614,13 @@ find (char *arg)
 | ||||||
|  |      { | ||||||
|  |        error (0, errno, _("cannot search %s"), | ||||||
|  |  	     safely_quote_err_filename (0, arg)); | ||||||
|  | +      error_severity (EXIT_FAILURE);
 | ||||||
|  |      } | ||||||
|  |    else | ||||||
|  |      { | ||||||
|  |        while ( (ent=fts_read (p)) != NULL ) | ||||||
|  |  	{ | ||||||
|  | +	  state.already_issued_stat_error_msg = false;
 | ||||||
|  |  	  state.have_stat = false; | ||||||
|  |  	  state.have_type = !!ent->fts_statp->st_mode; | ||||||
|  |  	  state.type = state.have_type ? ent->fts_statp->st_mode : 0; | ||||||
|  | @@ -640,6 +635,7 @@ find (char *arg)
 | ||||||
|  |  	  error (0, errno, | ||||||
|  |  		 _("failed to restore working directory after searching %s"), | ||||||
|  |  		 arg); | ||||||
|  | +	  error_severity (EXIT_FAILURE);
 | ||||||
|  |  	  return false; | ||||||
|  |  	} | ||||||
|  |        p = NULL; | ||||||
|  | @@ -689,6 +685,7 @@ main (int argc, char **argv)
 | ||||||
|  |    else | ||||||
|  |      set_program_name ("find"); | ||||||
|  |   | ||||||
|  | +  state.already_issued_stat_error_msg = false;
 | ||||||
|  |    state.exit_status = 0; | ||||||
|  |    state.execdirs_outstanding = false; | ||||||
|  |    state.cwd_dir_fd = AT_FDCWD; | ||||||
|  | diff --git a/find/parser.c b/find/parser.c
 | ||||||
|  | index 8238671..8668ce4 100644
 | ||||||
|  | --- a/find/parser.c
 | ||||||
|  | +++ b/find/parser.c
 | ||||||
|  | @@ -744,7 +744,7 @@ collect_arg_stat_info (char **argv, int *arg_ptr, struct stat *p,
 | ||||||
|  |  	} | ||||||
|  |        else | ||||||
|  |  	{ | ||||||
|  | -	  fatal_file_error (filename);
 | ||||||
|  | +	  fatal_target_file_error (errno, filename);
 | ||||||
|  |  	} | ||||||
|  |      } | ||||||
|  |    else | ||||||
|  | @@ -1685,7 +1685,7 @@ parse_newerXY (const struct parser_table* entry, char **argv, int *arg_ptr)
 | ||||||
|  |  	      /* Stat the named file. */ | ||||||
|  |  	      set_stat_placeholders (&stat_newer); | ||||||
|  |  	      if ((*options.xstat) (argv[*arg_ptr], &stat_newer)) | ||||||
|  | -		fatal_file_error (argv[*arg_ptr]);
 | ||||||
|  | +		fatal_target_file_error (errno, argv[*arg_ptr]);
 | ||||||
|  |   | ||||||
|  |  	      if (!get_stat_Ytime (&stat_newer, y, &our_pred->args.reftime.ts)) | ||||||
|  |  		{ | ||||||
|  | @@ -2425,7 +2425,7 @@ parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr)
 | ||||||
|  |  	   */ | ||||||
|  |  	  if (0 != fstat (fd, &fst)) | ||||||
|  |  	    { | ||||||
|  | -	      fatal_file_error (argv[*arg_ptr]);
 | ||||||
|  | +	      fatal_target_file_error (errno, argv[*arg_ptr]);
 | ||||||
|  |  	    } | ||||||
|  |  	  else | ||||||
|  |  	    { | ||||||
|  | @@ -2435,7 +2435,7 @@ parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr)
 | ||||||
|  |  	       * destination of the link, not the link itself. | ||||||
|  |  	       */ | ||||||
|  |  	      if ((*options.xstat) (argv[*arg_ptr], &st)) | ||||||
|  | -		fatal_file_error (argv[*arg_ptr]);
 | ||||||
|  | +		fatal_target_file_error (errno, argv[*arg_ptr]);
 | ||||||
|  |   | ||||||
|  |  	      if ((options.symlink_handling == SYMLINK_NEVER_DEREF) | ||||||
|  |  		  && (!options.open_nofollow_available)) | ||||||
|  | @@ -3799,7 +3799,7 @@ open_output_file (const char *path, struct format_val *p)
 | ||||||
|  |   | ||||||
|  |        if (p->stream == NULL) | ||||||
|  |  	{ | ||||||
|  | -	  fatal_file_error (path);
 | ||||||
|  | +	  fatal_nontarget_file_error (errno, path);
 | ||||||
|  |  	} | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | diff --git a/find/pred.c b/find/pred.c
 | ||||||
|  | index cb61ed2..44db6a6 100644
 | ||||||
|  | --- a/find/pred.c
 | ||||||
|  | +++ b/find/pred.c
 | ||||||
|  | @@ -696,7 +696,7 @@ checked_fprintf (struct format_val *dest, const char *fmt, ...)
 | ||||||
|  |    va_start (ap, fmt); | ||||||
|  |    rv = vfprintf (dest->stream, fmt, ap); | ||||||
|  |    if (rv < 0) | ||||||
|  | -    nonfatal_file_error (dest->filename);
 | ||||||
|  | +    nonfatal_nontarget_file_error (errno, dest->filename);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | @@ -707,7 +707,7 @@ checked_print_quoted (struct format_val *dest,
 | ||||||
|  |    int rv = print_quoted (dest->stream, dest->quote_opts, dest->dest_is_tty, | ||||||
|  |  			 format, s); | ||||||
|  |    if (rv < 0) | ||||||
|  | -    nonfatal_file_error (dest->filename);
 | ||||||
|  | +    nonfatal_nontarget_file_error (errno, dest->filename);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | @@ -716,7 +716,7 @@ checked_fwrite (void *p, size_t siz, size_t nmemb, struct format_val *dest)
 | ||||||
|  |  { | ||||||
|  |    int items_written = fwrite (p, siz, nmemb, dest->stream); | ||||||
|  |    if (items_written < nmemb) | ||||||
|  | -    nonfatal_file_error (dest->filename);
 | ||||||
|  | +    nonfatal_nontarget_file_error (errno, dest->filename);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  | @@ -724,7 +724,7 @@ checked_fflush (struct format_val *dest)
 | ||||||
|  |  { | ||||||
|  |    if (0 != fflush (dest->stream)) | ||||||
|  |      { | ||||||
|  | -      nonfatal_file_error (dest->filename);
 | ||||||
|  | +      nonfatal_nontarget_file_error (errno, dest->filename);
 | ||||||
|  |      } | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff --git a/find/sharefile.c b/find/sharefile.c
 | ||||||
|  | index 8e0f4cc..1442d7b 100644
 | ||||||
|  | --- a/find/sharefile.c
 | ||||||
|  | +++ b/find/sharefile.c
 | ||||||
|  | @@ -76,7 +76,7 @@ entry_free (void *pv)
 | ||||||
|  |    if (p->fp) | ||||||
|  |      { | ||||||
|  |        if (0 != fclose (p->fp)) | ||||||
|  | -	fatal_file_error (p->name);
 | ||||||
|  | +	fatal_nontarget_file_error (errno, p->name);
 | ||||||
|  |      } | ||||||
|  |    free (p->name); | ||||||
|  |    free (p); | ||||||
|  | diff --git a/find/tree.c b/find/tree.c
 | ||||||
|  | index 08f2f0a..d07b125 100644
 | ||||||
|  | --- a/find/tree.c
 | ||||||
|  | +++ b/find/tree.c
 | ||||||
|  | @@ -1283,6 +1283,7 @@ build_expression_tree (int argc, char *argv[], int end_of_leading_options)
 | ||||||
|  |    /* Build the input order list. */ | ||||||
|  |    while (i < argc ) | ||||||
|  |      { | ||||||
|  | +      state.already_issued_stat_error_msg = false;
 | ||||||
|  |        if (!looks_like_expression (argv[i], false)) | ||||||
|  |  	{ | ||||||
|  |  	  error (0, 0, _("paths must precede expression: %s"), argv[i]); | ||||||
|  | diff --git a/find/util.c b/find/util.c
 | ||||||
|  | index 3761a61..a789131 100644
 | ||||||
|  | --- a/find/util.c
 | ||||||
|  | +++ b/find/util.c
 | ||||||
|  | @@ -210,15 +210,14 @@ get_statinfo (const char *pathname, const char *name, struct stat *p)
 | ||||||
|  |  	      /* Savannah bug #16378. */ | ||||||
|  |  	      error (0, 0, _("WARNING: file %s appears to have mode 0000"), | ||||||
|  |  		     quotearg_n_style (0, options.err_quoting_style, name)); | ||||||
|  | +	      error_severity (1);
 | ||||||
|  |  	    } | ||||||
|  |  	} | ||||||
|  |        else | ||||||
|  |  	{ | ||||||
|  |  	  if (!options.ignore_readdir_race || (errno != ENOENT) ) | ||||||
|  |  	    { | ||||||
|  | -	      error (0, errno, "%s",
 | ||||||
|  | -		     safely_quote_err_filename (0, pathname));
 | ||||||
|  | -	      state.exit_status = 1;
 | ||||||
|  | +	      nonfatal_target_file_error (errno, pathname);
 | ||||||
|  |  	    } | ||||||
|  |  	  return -1; | ||||||
|  |  	} | ||||||
|  | @@ -272,6 +271,10 @@ get_info (const char *pathname,
 | ||||||
|  |        int result = get_statinfo (pathname, state.rel_pathname, p); | ||||||
|  |        if (result != 0) | ||||||
|  |  	{ | ||||||
|  | +	  return -1;		/* failure. */
 | ||||||
|  | +	}
 | ||||||
|  | +      else
 | ||||||
|  | +	{
 | ||||||
|  |  	  /* Verify some postconditions.  We can't check st_mode for | ||||||
|  |  	     non-zero-ness because of Savannah bug #16378 (which is | ||||||
|  |  	     that broken NFS servers can return st_mode==0). */ | ||||||
|  | @@ -283,10 +286,6 @@ get_info (const char *pathname,
 | ||||||
|  |  	    { | ||||||
|  |  	      assert (p->st_ino); | ||||||
|  |  	    } | ||||||
|  | -	  return -1;		/* failure. */
 | ||||||
|  | -	}
 | ||||||
|  | -      else
 | ||||||
|  | -	{
 | ||||||
|  |  	  return 0;		/* success. */ | ||||||
|  |  	} | ||||||
|  |      } | ||||||
|  | @@ -486,7 +485,7 @@ cleanup (void)
 | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    if (fflush (stdout) == EOF) | ||||||
|  | -    nonfatal_file_error ("standard output");
 | ||||||
|  | +    nonfatal_nontarget_file_error (errno, "standard output");
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* Savannah bug #16378 manifests as an assertion failure in pred_type() | ||||||
|  | @@ -1074,35 +1073,83 @@ safely_quote_err_filename (int n, char const *arg)
 | ||||||
|  |    return quotearg_n_style (n, options.err_quoting_style, arg); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* We have encountered an error which should affect the exit status.
 | ||||||
|  | + * This is normally used to change the exit status from 0 to 1.
 | ||||||
|  | + * However, if the exit status is already 2 for example, we don't want to
 | ||||||
|  | + * reduce it to 1.
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +error_severity (int level)
 | ||||||
|  | +{
 | ||||||
|  | +  if (state.exit_status < level)
 | ||||||
|  | +    state.exit_status = level;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  /* report_file_err | ||||||
|  |   */ | ||||||
|  |  static void | ||||||
|  | -report_file_err(int exitval, int errno_value, const char *name)
 | ||||||
|  | +report_file_err(int exitval, int errno_value,
 | ||||||
|  | +		boolean is_target_file, const char *name)
 | ||||||
|  |  { | ||||||
|  |    /* It is important that the errno value is passed in as a function | ||||||
|  |     * argument before we call safely_quote_err_filename(), because otherwise | ||||||
|  |     * we might find that safely_quote_err_filename() changes errno. | ||||||
|  |     */ | ||||||
|  | -  if (state.exit_status < 1)
 | ||||||
|  | -    state.exit_status = 1;
 | ||||||
|  | -
 | ||||||
|  | -  error (exitval, errno_value, "%s", safely_quote_err_filename (0, name));
 | ||||||
|  | +  if (!is_target_file || !state.already_issued_stat_error_msg)
 | ||||||
|  | +    {
 | ||||||
|  | +      error (exitval, errno_value, "%s", safely_quote_err_filename (0, name));
 | ||||||
|  | +      error_severity (1);
 | ||||||
|  | +    }
 | ||||||
|  | +  if (is_target_file)
 | ||||||
|  | +    {
 | ||||||
|  | +      state.already_issued_stat_error_msg = true;
 | ||||||
|  | +    }
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -/* fatal_file_error
 | ||||||
|  | +/* nonfatal_target_file_error
 | ||||||
|  |   * | ||||||
|  |   */ | ||||||
|  |  void | ||||||
|  | -fatal_file_error(const char *name)
 | ||||||
|  | +nonfatal_target_file_error (int errno_value, const char *name)
 | ||||||
|  |  { | ||||||
|  | -  report_file_err (1, errno, name);
 | ||||||
|  | +  report_file_err (0, errno_value, true, name);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/* fatal_target_file_error
 | ||||||
|  | + *
 | ||||||
|  | + * Report an error on a target file (i.e. a file we are searching).
 | ||||||
|  | + * Such errors are only reported once per searched file.
 | ||||||
|  | + *
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +fatal_target_file_error(int errno_value, const char *name)
 | ||||||
|  | +{
 | ||||||
|  | +  report_file_err (1, errno_value, true, name);
 | ||||||
|  |    /*NOTREACHED*/ | ||||||
|  |    abort (); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* nonfatal_nontarget_file_error
 | ||||||
|  | + *
 | ||||||
|  | + */
 | ||||||
|  |  void | ||||||
|  | -nonfatal_file_error (const char *name)
 | ||||||
|  | +nonfatal_nontarget_file_error (int errno_value, const char *name)
 | ||||||
|  |  { | ||||||
|  | -  report_file_err (0, errno, name);
 | ||||||
|  | +  report_file_err (0, errno_value, false, name);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* fatal_nontarget_file_error
 | ||||||
|  | + *
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +fatal_nontarget_file_error(int errno_value, const char *name)
 | ||||||
|  | +{
 | ||||||
|  | +  /* We're going to exit fatally, so make sure we always isssue the error
 | ||||||
|  | +   * message, even if it will be duplicate.   Motivation: otherwise it may
 | ||||||
|  | +   * not be clear what went wrong.
 | ||||||
|  | +   */
 | ||||||
|  | +  state.already_issued_stat_error_msg = false;
 | ||||||
|  | +  report_file_err (1, errno_value, false, name);
 | ||||||
|  | +  /*NOTREACHED*/
 | ||||||
|  | +  abort ();
 | ||||||
|  | +}
 | ||||||
| @ -1,7 +1,7 @@ | |||||||
| Summary: The GNU versions of find utilities (find and xargs) | Summary: The GNU versions of find utilities (find and xargs) | ||||||
| Name: findutils | Name: findutils | ||||||
| Version: 4.5.7 | Version: 4.5.7 | ||||||
| Release: 3%{?dist} | Release: 4%{?dist} | ||||||
| Epoch: 1 | Epoch: 1 | ||||||
| License: GPLv3+ | License: GPLv3+ | ||||||
| Group: Applications/File | Group: Applications/File | ||||||
| @ -26,6 +26,9 @@ Patch4: findutils-4.5.7-warnings.patch | |||||||
| # upstream commit a44cece | # upstream commit a44cece | ||||||
| Patch5: findutils-4.5.7-fdleak.patch | Patch5: findutils-4.5.7-fdleak.patch | ||||||
| 
 | 
 | ||||||
|  | # rhbz #579476 (upstream bug #27213) | ||||||
|  | Patch6: findutils-4.5.7-bz579476.patch | ||||||
|  | 
 | ||||||
| Requires(post): /sbin/install-info | Requires(post): /sbin/install-info | ||||||
| Requires(preun): /sbin/install-info | Requires(preun): /sbin/install-info | ||||||
| Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) | Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) | ||||||
| @ -53,6 +56,7 @@ useful for finding things on your system. | |||||||
| %patch3 -p1 | %patch3 -p1 | ||||||
| %patch4 -p1 | %patch4 -p1 | ||||||
| %patch5 -p1 | %patch5 -p1 | ||||||
|  | %patch6 -p1 | ||||||
| 
 | 
 | ||||||
| # needed because of findutils-4.4.0-no-locate.patch | # needed because of findutils-4.4.0-no-locate.patch | ||||||
| aclocal -I gnulib/m4 -I m4 | aclocal -I gnulib/m4 -I m4 | ||||||
| @ -110,6 +114,9 @@ rm -rf $RPM_BUILD_ROOT | |||||||
| %{_infodir}/find-maint.info.gz | %{_infodir}/find-maint.info.gz | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Tue Apr 06 2010 Kamil Dudka <kdudka@redhat.com> - 1:4.5.7-4 | ||||||
|  | - avoid assertion failure due to access permissions (#579476) | ||||||
|  | 
 | ||||||
| * Sun Apr 04 2010 Kamil Dudka <kdudka@redhat.com> - 1:4.5.7-3 | * Sun Apr 04 2010 Kamil Dudka <kdudka@redhat.com> - 1:4.5.7-3 | ||||||
| - upstream bugfix http://savannah.gnu.org/bugs/?29435 | - upstream bugfix http://savannah.gnu.org/bugs/?29435 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user