Detect directories where an ordinary file is expected.
+2003-11-07  Jonathan R. Grant  <jg-binutils@jguk.org>
+
+       * bucomm,c (get_file_size): New function.  Returns the size of a
+         file.
+       * bucomm.h: Add prototype for get_file_size.
+       * addr2line.c (process_file): Use new function.
+       * ar.c (main, ranlib_only, ranlib_touch): Likewise.
+       * nm.c (display_file): Likewise.
+       * objcopy.c (add_specific_symbols, copy_file, strip_main,
+         copy_main): Likewise.
+       * objdump.c (display_file): Likewise.
+       * size.c (display_file): Likewise.
+       * strings.c (strings_file): Likewise.
+       * readelf.c (process_file): Use similar code to get_file_size.
+
 2003-11-06  Bruno Rohee  <bruno@rohee.com>
 
        * ieee.c: Fix "the the" typo.
 
   bfd *abfd;
   char **matching;
 
+  if (get_file_size (file_name) < 1)
+    return;
+
   abfd = bfd_openr (file_name, target);
   if (abfd == NULL)
     bfd_fatal (file_name);
 
 
       /* Add to the end of the archive.  */
       after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
-      if (ar_emul_append (after_bfd, *files_to_move, verbose))
+
+      if (get_file_size (* files_to_move) > 0
+         && ar_emul_append (after_bfd, *files_to_move, verbose))
        changed = TRUE;
 
     next_file:;
 {
   bfd *arch;
 
+  if (get_file_size (archname) < 1)
+    return;
   write_armap = 1;
   arch = open_inarch (archname, (char *) NULL);
   if (arch == NULL)
   bfd *arch;
   char **matching;
 
+  if (get_file_size (archname) < 1)
+    return;
   f = open (archname, O_RDWR | O_BINARY, 0);
   if (f < 0)
     {
 
 
   return ret;
 }
+
+/* Returns the size of the named file.  If the file does not
+   exist, or if it is not a real file, then a suitable non-fatal
+   error message is printed and zero is returned.  */
+
+off_t
+get_file_size (const char * file_name)
+{
+  struct stat statbuf;
+  
+  if (stat (file_name, &statbuf) < 0)
+    {
+      if (errno == ENOENT)
+       non_fatal (_("'%s': No such file"), file_name);
+      else
+       non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
+                  file_name, strerror (errno));
+    }  
+  else if (! S_ISREG (statbuf.st_mode))
+    non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
+  else
+    return statbuf.st_size;
+
+  return 0;
+}
 
 
 bfd_vma parse_vma (const char *, const char *);
 
+off_t get_file_size (const char *);
+
 extern char *program_name;
 
 /* filemode.c */
 
   bfd *file;
   char **matching;
 
+  if (get_file_size (filename) < 1)
+    return FALSE;
+
   file = bfd_openr (filename, target);
   if (file == NULL)
     {
 
 static void
 add_specific_symbols (const char *filename, struct symlist **list)
 {
-  struct stat st;
+  off_t  size;
   FILE * f;
   char * line;
   char * buffer;
   unsigned int line_count;
 
-  if (stat (filename, & st) < 0)
-    fatal (_("cannot stat: %s: %s"), filename, strerror (errno));
-  if (st.st_size == 0)
+  size = get_file_size (filename);
+  if (size == 0)
     return;
 
-  buffer = xmalloc (st.st_size + 2);
+  buffer = xmalloc (size + 2);
   f = fopen (filename, FOPEN_RT);
   if (f == NULL)
-    fatal (_("cannot open: %s: %s"), filename, strerror (errno));
+    fatal (_("cannot open '%s': %s"), filename, strerror (errno));
 
-  if (fread (buffer, 1, st.st_size, f) == 0 || ferror (f))
+  if (fread (buffer, 1, size, f) == 0 || ferror (f))
     fatal (_("%s: fread failed"), filename);
 
   fclose (f);
-  buffer [st.st_size] = '\n';
-  buffer [st.st_size + 1] = '\0';
+  buffer [size] = '\n';
+  buffer [size + 1] = '\0';
 
   line_count = 1;
 
   char **obj_matching;
   char **core_matching;
 
+  if (get_file_size (input_filename) < 1)
+    {
+      status = 1;
+      return;
+    }
+
   /* To allow us to do "strip *" without dying on the first
      non-object file, failures are nonfatal.  */
   ibfd = bfd_openr (input_filename, input_target);
       struct stat statbuf;
       char *tmpname;
 
+      if (get_file_size (argv[i]) < 1)
+       continue;
+
       if (preserve_dates)
-       {
-         if (stat (argv[i], &statbuf) < 0)
-           {
-             non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
-             continue;
-           }
-       }
+       /* No need to check the return value of stat().
+          It has already been checked in get_file_size().  */
+       stat (argv[i], &statbuf);
 
       if (output_file != NULL)
        tmpname = output_file;
        case OPTION_ADD_SECTION:
          {
            const char *s;
-           struct stat st;
+           off_t size;
            struct section_add *pa;
            int len;
            char *name;
            if (s == NULL)
              fatal (_("bad format for %s"), "--add-section");
 
-           if (stat (s + 1, & st) < 0)
-             fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
+           size = get_file_size (s + 1);
+           if (size < 1)
+             break;
 
            pa = xmalloc (sizeof (struct section_add));
 
            pa->name = name;
 
            pa->filename = s + 1;
+           pa->size = size;
+           pa->contents = xmalloc (size);
 
-           pa->size = st.st_size;
-
-           pa->contents = xmalloc (pa->size);
            f = fopen (pa->filename, FOPEN_RB);
 
            if (f == NULL)
 
   if (preserve_dates)
     if (stat (input_filename, & statbuf) < 0)
-      fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
+      fatal (_("warning: could not locate '%s'.  System error message: %s"),
+            input_filename, strerror (errno));
 
   /* If there is no destination file, or the source and destination files
      are the same, then create a temp and rename the result into the input.  */
 
 static void
 display_file (char *filename, char *target)
 {
-  bfd *file, *arfile = NULL;
+  bfd *file;
+  bfd *arfile = NULL;
+
+  if (get_file_size (filename) < 1)
+    return;
 
   file = bfd_openr (filename, target);
   if (file == NULL)
 
 
   if (stat (file_name, &statbuf) < 0)
     {
-      error (_("Cannot stat input file %s.\n"), file_name);
+      if (errno == ENOENT)
+       error (_("'%s': No such file\n"), file_name);
+      else
+       error (_("Could not locate '%s'.  System error message: %s\n"),
+              file_name, strerror (errno));
+      return 1;
+    }
+
+  if (! S_ISREG (statbuf.st_mode))
+    {
+      error (_("'%s' is not an ordinary file\n"), file_name);
       return 1;
     }
 
   file = fopen (file_name, "rb");
   if (file == NULL)
     {
-      error (_("Input file %s not found.\n"), file_name);
+      error (_("Input file '%s' is not readable.\n"), file_name);
       return 1;
     }
 
 
 static void
 display_file (char *filename)
 {
-  bfd *file = bfd_openr (filename, target);
+  bfd *file;
 
+  if (get_file_size (filename) < 1)
+    return;
+
+  file = bfd_openr (filename, target);
   if (file == NULL)
     {
       bfd_nonfatal (filename);
 
 static bfd_boolean
 strings_file (char *file)
 {
+  if (get_file_size (file) < 1)
+    return FALSE;
+
   /* If we weren't told to scan the whole file,
      try to open it as an object file and only look at
      initialized data sections.  If that fails, fall back to the
 
+2003-11-07  Jonathan R. Grant  <jg-binutils@jguk.org>
+
+       * input-file.c (input_file_open): Use "No such file" error
+       message.
+
 2003-11-06  Pete Gonzalez  <pgonzalez@bluel.com>
 
        * config/tc-arm.texi (struct reg_entry): Add new field 'builtin'.
 
 /* input_file.c - Deal with Input Files -
-   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001
+   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 #include <stdio.h>
 #include <string.h>
+#include <sys/stat.h>
 #include "as.h"
 #include "input-file.h"
 #include "safe-ctype.h"
 
   assert (filename != 0);      /* Filename may not be NULL.  */
   if (filename[0])
-    {                          /* We have a file name. Suck it and see.  */
+    {
+      struct stat statbuf;
+
+      if (stat (filename, &statbuf) < 0)
+       {
+         as_bad (_("%s: No such file"), filename);
+         return;
+       }
+      else if (! S_ISREG (statbuf.st_mode))
+       {
+         as_bad (_("'%s' is not an ordinary file"), filename);
+         return;
+       }
+
       f_in = fopen (filename, FOPEN_RT);
       file_name = filename;
     }
   else
-    {                          /* use stdin for the input file.  */
+    {
+      /* Use stdin for the input file.  */
       f_in = stdin;
-      file_name = _("{standard input}");       /* For error messages.  */
+      /* For error messages.  */
+      file_name = _("{standard input}");
     }
+
   if (f_in == (FILE *) 0)
     {
       as_bad (_("can't open %s for reading"), file_name);
 
+2003-11-07  Jonathan R. Grant  <jg-binutils@jguk.org>
+       
+       * ldfile.c (ldfile_open_file): Use "No such file" error message.
+
 2003-11-06  Bruno Rohee  <bruno@rohee.com>
 
        * ls.texinfo: Fix "the the" typo.
 
       if (ldfile_try_open_bfd (entry->filename, entry))
        return;
       if (strcmp (entry->filename, entry->local_sym_name) != 0)
-       einfo (_("%F%P: cannot open %s for %s: %E\n"),
+       einfo (_("%F%P: %s (%s): No such file: %E\n"),
               entry->filename, entry->local_sym_name);
       else
-       einfo (_("%F%P: cannot open %s: %E\n"), entry->local_sym_name);
+       einfo (_("%F%P: %s: No such file: %E\n"), entry->local_sym_name);
     }
   else
     {