emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 6367368 1/2: Fix file name encodings in diagnostics


From: Paul Eggert
Subject: [Emacs-diffs] master 6367368 1/2: Fix file name encodings in diagnostics
Date: Tue, 18 Aug 2015 23:25:02 +0000

branch: master
commit 636736861688abe73cc5dd4181fdb66de3fd8cfd
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Fix file name encodings in diagnostics
    
    Also, close some minor races when opening image files, by opening
    them once instead of multiple times.
    * src/gtkutil.c (xg_get_image_for_pixmap):
    * src/image.c (xpm_load, tiff_load, gif_load, imagemagick_load)
    (svg_load):
    * src/nsimage.m (allocInitFromFile:):
    * src/xfns.c (xg_set_icon):
    Encode file name, since x_find_image_file no longer does that.
    * src/image.c (x_find_image_fd): New function.
    (x_find_image_file): Use it.  Do not encode resulting file name,
    since callers sometimes need it decoded.
    (slurp_file): File arg is now a fd, not a file name.
    All callers changed.  This saves us having to open the file twice.
    (xbm_load, xpm_load, pbm_load, png_load_body, jpeg_load_body)
    (svg_load):
    Use x_find_image_fd and fdopen to save a file-open.
    Report file name that failed.
    * src/lread.c (openp): If PREDICATE is t, open the file in binary mode.
---
 src/gtkutil.c |    5 +-
 src/image.c   |  133 ++++++++++++++++++++++++++++++--------------------------
 src/lread.c   |   13 +++--
 src/nsimage.m |    1 +
 src/xfns.c    |    2 +-
 5 files changed, 84 insertions(+), 70 deletions(-)

diff --git a/src/gtkutil.c b/src/gtkutil.c
index a4b4331..d684cd9 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -382,10 +382,11 @@ xg_get_image_for_pixmap (struct frame *f,
   if (STRINGP (specified_file)
       && STRINGP (file = x_find_image_file (specified_file)))
     {
+      char *encoded_file = SSDATA (ENCODE_FILE (file));
       if (! old_widget)
-        old_widget = GTK_IMAGE (gtk_image_new_from_file (SSDATA (file)));
+        old_widget = GTK_IMAGE (gtk_image_new_from_file (encoded_file));
       else
-        gtk_image_set_from_file (old_widget, SSDATA (file));
+        gtk_image_set_from_file (old_widget, encoded_file);
 
       return GTK_WIDGET (old_widget);
     }
diff --git a/src/image.c b/src/image.c
index fb8c6e7..8f9b06c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2270,11 +2270,13 @@ image_unget_x_image (struct image *img, bool mask_p, 
XImagePtr ximg)
  ***********************************************************************/
 
 /* Find image file FILE.  Look in data-directory/images, then
-   x-bitmap-file-path.  Value is the encoded full name of the file
-   found, or nil if not found.  */
+   x-bitmap-file-path.  Value is the full name of the file
+   found, or nil if not found.  If PFD is nonnull store into *PFD a
+   readable file descriptor for the file, opened in binary mode.  If
+   PFD is null, do not open the file.  */
 
-Lisp_Object
-x_find_image_file (Lisp_Object file)
+static Lisp_Object
+x_find_image_fd (Lisp_Object file, int *pfd)
 {
   Lisp_Object file_found, search_path;
   int fd;
@@ -2286,29 +2288,35 @@ x_find_image_file (Lisp_Object file)
                       Vx_bitmap_file_path);
 
   /* Try to find FILE in data-directory/images, then x-bitmap-file-path.  */
-  fd = openp (search_path, file, Qnil, &file_found, Qnil, false);
-
-  if (fd == -1)
-    file_found = Qnil;
-  else
-    {
-      file_found = ENCODE_FILE (file_found);
-      if (fd != -2)
-       emacs_close (fd);
-    }
-
+  fd = openp (search_path, file, Qnil, &file_found,
+             pfd ? Qt : make_number (R_OK), false);
+  if (fd < 0)
+    return Qnil;
+  if (pfd)
+    *pfd = fd;
   return file_found;
 }
 
+/* Find image file FILE.  Look in data-directory/images, then
+   x-bitmap-file-path.  Value is the encoded full name of the file
+   found, or nil if not found.  */
+
+Lisp_Object
+x_find_image_file (Lisp_Object file)
+{
+  return x_find_image_fd (file, 0);
+}
 
 /* Read FILE into memory.  Value is a pointer to a buffer allocated
    with xmalloc holding FILE's contents.  Value is null if an error
-   occurred.  *SIZE is set to the size of the file.  */
+   occurred.  FD is a file descriptor open for reading FILE.  Set
+   *SIZE to the size of the file.  */
 
 static unsigned char *
-slurp_file (char *file, ptrdiff_t *size)
+slurp_file (int fd, ptrdiff_t *size)
 {
-  FILE *fp = emacs_fopen (file, "rb");
+  FILE *fp = fdopen (fd, "rb");
+
   unsigned char *buf = NULL;
   struct stat st;
 
@@ -2980,21 +2988,19 @@ xbm_load (struct frame *f, struct image *img)
   file_name = image_spec_value (img->spec, QCfile, NULL);
   if (STRINGP (file_name))
     {
-      Lisp_Object file;
-      unsigned char *contents;
-      ptrdiff_t size;
-
-      file = x_find_image_file (file_name);
+      int fd;
+      Lisp_Object file = x_find_image_fd (file_name, &fd);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
          return 0;
        }
 
-      contents = slurp_file (SSDATA (file), &size);
+      ptrdiff_t size;
+      unsigned char *contents = slurp_file (fd, &size);
       if (contents == NULL)
        {
-         image_error ("Error loading XBM image "uLSQM"%s"uRSQM, img->spec);
+         image_error ("Error loading XBM image "uLSQM"%s"uRSQM, file);
          return 0;
        }
 
@@ -3640,6 +3646,7 @@ xpm_load (struct frame *f, struct image *img)
          return 0;
        }
 
+      file = ENCODE_FILE (file);
 #ifdef HAVE_NTGUI
 #ifdef WINDOWSNT
       /* FILE is encoded in UTF-8, but image libraries on Windows
@@ -4290,21 +4297,19 @@ xpm_load (struct frame *f,
   file_name = image_spec_value (img->spec, QCfile, NULL);
   if (STRINGP (file_name))
     {
-      Lisp_Object file;
-      unsigned char *contents;
-      ptrdiff_t size;
-
-      file = x_find_image_file (file_name);
+      int fd;
+      Lisp_Object file = x_find_image_fd (file_name, &fd);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
          return 0;
        }
 
-      contents = slurp_file (SSDATA (file), &size);
+      ptrdiff_t size;
+      unsigned char *contents = slurp_file (fd, &size);
       if (contents == NULL)
        {
-         image_error ("Error loading XPM image "uLSQM"%s"uRSQM, img->spec);
+         image_error ("Error loading XPM image "uLSQM"%s"uRSQM, file);
          return 0;
        }
 
@@ -5253,11 +5258,10 @@ pbm_load (struct frame *f, struct image *img)
   bool raw_p;
   int x, y;
   int width, height, max_color_idx = 0;
-  Lisp_Object file, specified_file;
+  Lisp_Object specified_file;
   enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
   unsigned char *contents = NULL;
   unsigned char *end, *p;
-  ptrdiff_t size;
 #ifdef USE_CAIRO
   unsigned char *data = 0;
   uint32_t *dataptr;
@@ -5269,7 +5273,8 @@ pbm_load (struct frame *f, struct image *img)
 
   if (STRINGP (specified_file))
     {
-      file = x_find_image_file (specified_file);
+      int fd;
+      Lisp_Object file = x_find_image_fd (specified_file, &fd);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@@ -5277,7 +5282,8 @@ pbm_load (struct frame *f, struct image *img)
          return 0;
        }
 
-      contents = slurp_file (SSDATA (file), &size);
+      ptrdiff_t size;
+      contents = slurp_file (fd, &size);
       if (contents == NULL)
        {
          image_error ("Error reading "uLSQM"%s"uRSQM, file);
@@ -5878,7 +5884,7 @@ struct png_load_context
 static bool
 png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 {
-  Lisp_Object file, specified_file;
+  Lisp_Object specified_file;
   Lisp_Object specified_data;
   int x, y;
   ptrdiff_t i;
@@ -5909,7 +5915,8 @@ png_load_body (struct frame *f, struct image *img, struct 
png_load_context *c)
 
   if (NILP (specified_data))
     {
-      file = x_find_image_file (specified_file);
+      int fd;
+      Lisp_Object file = x_find_image_fd (specified_file, &fd);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@@ -5918,7 +5925,7 @@ png_load_body (struct frame *f, struct image *img, struct 
png_load_context *c)
        }
 
       /* Open the image file.  */
-      fp = emacs_fopen (SSDATA (file), "rb");
+      fp = fdopen (fd, "rb");
       if (!fp)
        {
          image_error ("Cannot open image file "uLSQM"%s"uRSQM, file);
@@ -6654,7 +6661,7 @@ static bool
 jpeg_load_body (struct frame *f, struct image *img,
                struct my_jpeg_error_mgr *mgr)
 {
-  Lisp_Object file, specified_file;
+  Lisp_Object specified_file;
   Lisp_Object specified_data;
   /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561.  */
   FILE * IF_LINT (volatile) fp = NULL;
@@ -6674,7 +6681,8 @@ jpeg_load_body (struct frame *f, struct image *img,
 
   if (NILP (specified_data))
     {
-      file = x_find_image_file (specified_file);
+      int fd;
+      Lisp_Object file = x_find_image_fd (specified_file, &fd);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@@ -6682,7 +6690,7 @@ jpeg_load_body (struct frame *f, struct image *img,
          return 0;
        }
 
-      fp = emacs_fopen (SSDATA (file), "rb");
+      fp = fdopen (fd, "rb");
       if (fp == NULL)
        {
          image_error ("Cannot open "uLSQM"%s"uRSQM, file);
@@ -7172,7 +7180,7 @@ tiff_warning_handler (const char *title, const char 
*format, va_list ap)
 static bool
 tiff_load (struct frame *f, struct image *img)
 {
-  Lisp_Object file, specified_file;
+  Lisp_Object specified_file;
   Lisp_Object specified_data;
   TIFF *tiff;
   int width, height, x, y, count;
@@ -7191,19 +7199,21 @@ tiff_load (struct frame *f, struct image *img)
   if (NILP (specified_data))
     {
       /* Read from a file */
-      file = x_find_image_file (specified_file);
+      Lisp_Object file = x_find_image_file (specified_file);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM,
                       specified_file);
          return 0;
        }
+
+      Lisp_Object encoded_file = ENCODE_FILE (file);
 # ifdef WINDOWSNT
-      file = ansi_encode_filename (file);
+      encoded_file = ansi_encode_filename (encoded_file);
 # endif
 
       /* Try to open the image file.  */
-      tiff = TIFFOpen (SSDATA (file), "r");
+      tiff = TIFFOpen (SSDATA (encoded_file), "r");
       if (tiff == NULL)
        {
          image_error ("Cannot open "uLSQM"%s"uRSQM, file);
@@ -7605,7 +7615,6 @@ static const int interlace_increment[] = {8, 8, 4, 2};
 static bool
 gif_load (struct frame *f, struct image *img)
 {
-  Lisp_Object file;
   int rc, width, height, x, y, i, j;
   ColorMapObject *gif_color_map;
   unsigned long pixel_colors[256];
@@ -7626,27 +7635,29 @@ gif_load (struct frame *f, struct image *img)
 
   if (NILP (specified_data))
     {
-      file = x_find_image_file (specified_file);
+      Lisp_Object file = x_find_image_file (specified_file);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM,
                       specified_file);
          return 0;
        }
+
+      Lisp_Object encoded_file = ENCODE_FILE (file);
 #ifdef WINDOWSNT
-      file = ansi_encode_filename (file);
+      encoded_file = ansi_encode_filename (encoded_file);
 #endif
 
       /* Open the GIF file.  */
 #if GIFLIB_MAJOR < 5
-      gif = DGifOpenFileName (SSDATA (file));
+      gif = DGifOpenFileName (SSDATA (encoded_file));
       if (gif == NULL)
        {
          image_error ("Cannot open "uLSQM"%s"uRSQM, file);
          return 0;
        }
 #else
-      gif = DGifOpenFileName (SSDATA (file), &gif_err);
+      gif = DGifOpenFileName (SSDATA (encoded_file), &gif_err);
       if (gif == NULL)
        {
          image_error ("Cannot open "uLSQM"%s"uRSQM": %s",
@@ -8818,14 +8829,13 @@ imagemagick_load (struct frame *f, struct image *img)
   file_name = image_spec_value (img->spec, QCfile, NULL);
   if (STRINGP (file_name))
     {
-      Lisp_Object file;
-
-      file = x_find_image_file (file_name);
+      Lisp_Object file = x_find_image_file (file_name);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
          return 0;
        }
+      file = ENCODE_FILE (file);
 #ifdef WINDOWSNT
       file = ansi_encode_filename (file);
 #endif
@@ -9097,11 +9107,8 @@ svg_load (struct frame *f, struct image *img)
   file_name = image_spec_value (img->spec, QCfile, NULL);
   if (STRINGP (file_name))
     {
-      Lisp_Object file;
-      unsigned char *contents;
-      ptrdiff_t size;
-
-      file = x_find_image_file (file_name);
+      int fd;
+      Lisp_Object file = x_find_image_fd (file_name, &fd);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
@@ -9109,14 +9116,16 @@ svg_load (struct frame *f, struct image *img)
        }
 
       /* Read the entire file into memory.  */
-      contents = slurp_file (SSDATA (file), &size);
+      ptrdiff_t size;
+      unsigned char *contents = slurp_file (fd, &size);
       if (contents == NULL)
        {
-         image_error ("Error loading SVG image "uLSQM"%s"uRSQM, img->spec);
+         image_error ("Error loading SVG image "uLSQM"%s"uRSQM, file);
          return 0;
        }
       /* If the file was slurped into memory properly, parse it.  */
-      success_p = svg_load_image (f, img, contents, size, SSDATA (file));
+      success_p = svg_load_image (f, img, contents, size,
+                                 SSDATA (ENCODE_FILE (file)));
       xfree (contents);
     }
   /* Else its not a file, its a lisp object.  Load the image from a
diff --git a/src/lread.c b/src/lread.c
index ebd594c..77a6211 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1403,7 +1403,8 @@ directories, make sure the PREDICATE function returns 
`dir-ok' for them.  */)
    SUFFIXES is a list of strings containing possible suffixes.
    The empty suffix is automatically added if the list is empty.
 
-   PREDICATE non-nil means don't open the files,
+   PREDICATE t means the files are binary.
+   PREDICATE non-nil and non-t means don't open the files,
    just look for one that satisfies the predicate.  In this case,
    return 1 on success.  The predicate can be a lisp function or
    an integer to pass to `access' (in which case file-name-handlers
@@ -1418,7 +1419,7 @@ directories, make sure the PREDICATE function returns 
`dir-ok' for them.  */)
 
    If NEWER is true, try all SUFFIXes and return the result for the
    newest file that exists.  Does not apply to remote files,
-   or if PREDICATE is specified.  */
+   or if a non-nil and non-t PREDICATE is specified.  */
 
 int
 openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
@@ -1520,10 +1521,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
          else
            string = make_string (fn, fnlen);
          handler = Ffind_file_name_handler (string, Qfile_exists_p);
-         if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
+         if ((!NILP (handler) || (!NILP (predicate) && !EQ (predicate, Qt)))
+             && !NATNUMP (predicate))
             {
              bool exists;
-             if (NILP (predicate))
+             if (NILP (predicate) || EQ (predicate, Qt))
                exists = !NILP (Ffile_readable_p (string));
              else
                {
@@ -1577,7 +1579,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
                }
              else
                {
-                 fd = emacs_open (pfn, O_RDONLY, 0);
+                 int oflags = O_RDONLY + (NILP (predicate) ? 0 : O_BINARY);
+                 fd = emacs_open (pfn, oflags, 0);
                  if (fd < 0)
                    {
                      if (errno != ENOENT)
diff --git a/src/nsimage.m b/src/nsimage.m
index 13e8504..5d0871b 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -169,6 +169,7 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
   found = x_find_image_file (file);
   if (!STRINGP (found))
     return nil;
+  found = ENCODE_FILE (found);
 
   image = [[EmacsImage alloc] initByReferencingFile:
                      [NSString stringWithUTF8String: SSDATA (found)]];
diff --git a/src/xfns.c b/src/xfns.c
index 18fb343..3ef6762 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -548,7 +548,7 @@ xg_set_icon (struct frame *f, Lisp_Object file)
     {
       GdkPixbuf *pixbuf;
       GError *err = NULL;
-      char *filename = SSDATA (found);
+      char *filename = SSDATA (ENCODE_FILE (found));
       block_input ();
 
       pixbuf = gdk_pixbuf_new_from_file (filename, &err);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]