]> code.delx.au - gnu-emacs/commitdiff
Fix etags reading of compressed files
authorEli Zaretskii <eliz@gnu.org>
Sat, 23 May 2015 08:35:45 +0000 (11:35 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 23 May 2015 08:35:45 +0000 (11:35 +0300)
* lib-src/etags.c (O_CLOEXEC) [WINDOWSNT]: Define.
Include fcntl.h, for O_CLOEXEC.
(process_file_name): Don't use 'popen', whose streams cannot be
rewound.  Instead, uncompress the file to a temporary file,
created by 'etags_mktmp', and read from that as usual.
(etags_mktmp): New function.

* test/etags/ETAGS.good_1:
* test/etags/ETAGS.good_2:
* test/etags/ETAGS.good_3:
* test/etags/ETAGS.good_4:
* test/etags/ETAGS.good_5: Update to be consistent with latest
changes in etags.c regarding reading compressed files.

lib-src/etags.c
test/etags/ETAGS.good_1
test/etags/ETAGS.good_2
test/etags/ETAGS.good_3
test/etags/ETAGS.good_4
test/etags/ETAGS.good_5

index 0a308c1984fd219a234a0a7f976372154526591a..28729da87200a86aeb3e040984909c0f642b90d7 100644 (file)
@@ -116,6 +116,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
 # undef HAVE_NTGUI
 # undef  DOS_NT
 # define DOS_NT
+# define O_CLOEXEC O_NOINHERIT
 #endif /* WINDOWSNT */
 
 #include <unistd.h>
@@ -125,6 +126,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
 #include <sysstdio.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <binary-io.h>
@@ -336,6 +338,7 @@ static char *absolute_filename (char *, char *);
 static char *absolute_dirname (char *, char *);
 static bool filename_is_absolute (char *f);
 static void canonicalize_filename (char *);
+static char *etags_mktmp (void);
 static void linebuffer_init (linebuffer *);
 static void linebuffer_setlen (linebuffer *, int);
 static void *xmalloc (size_t);
@@ -1437,7 +1440,7 @@ process_file_name (char *file, language *lang)
   fdesc *fdp;
   compressor *compr;
   char *compressed_name, *uncompressed_name;
-  char *ext, *real_name;
+  char *ext, *real_name, *tmp_name;
   int retval;
 
   canonicalize_filename (file);
@@ -1522,9 +1525,20 @@ process_file_name (char *file, language *lang)
     }
   if (real_name == compressed_name)
     {
-      char *cmd = concat (compr->command, " ", real_name);
-      inf = popen (cmd, "r" FOPEN_BINARY);
-      free (cmd);
+      tmp_name = etags_mktmp ();
+      if (!tmp_name)
+       inf = NULL;
+      else
+       {
+         char *cmd1 = concat (compr->command, " ", real_name);
+         char *cmd = concat (cmd1, " > ", tmp_name);
+         free (cmd1);
+         if (system (cmd) == -1)
+           inf = NULL;
+         else
+           inf = fopen (tmp_name, "r" FOPEN_BINARY);
+         free (cmd);
+       }
     }
   else
     inf = fopen (real_name, "r" FOPEN_BINARY);
@@ -1536,10 +1550,12 @@ process_file_name (char *file, language *lang)
 
   process_file (inf, uncompressed_name, lang);
 
+  retval = fclose (inf);
   if (real_name == compressed_name)
-    retval = pclose (inf);
-  else
-    retval = fclose (inf);
+    {
+      remove (tmp_name);
+      free (tmp_name);
+    }
   if (retval < 0)
     pfatal (file);
 
@@ -1707,9 +1723,6 @@ find_entries (FILE *inf)
        }
     }
 
-  /* We rewind here, even if inf may be a pipe.  We fail if the
-     length of the first line is longer than the pipe block size,
-     which is unlikely. */
   rewind (inf);
 
   /* Else try to guess the language given the case insensitive file name. */
@@ -1734,8 +1747,6 @@ find_entries (FILE *inf)
       if (old_last_node == last_node)
        /* No Fortran entries found.  Try C. */
        {
-         /* We do not tag if rewind fails.
-            Only the file name will be recorded in the tags file. */
          rewind (inf);
          curfdp->lang = get_language_from_langname (cplusplus ? "c++" : "c");
          find_entries (inf);
@@ -5015,8 +5026,6 @@ TEX_mode (FILE *inf)
       TEX_opgrp = '<';
       TEX_clgrp = '>';
     }
-  /* If the input file is compressed, inf is a pipe, and rewind may fail.
-     No attempt is made to correct the situation. */
   rewind (inf);
 }
 
@@ -6344,6 +6353,51 @@ etags_getcwd (void)
   return path;
 }
 
+/* Return a newly allocated string containing a name of a temporary file.  */
+static char *
+etags_mktmp (void)
+{
+  const char *tmpdir = getenv ("TMPDIR");
+  const char *slash = "/";
+
+#if MSDOS || defined (DOS_NT)
+  if (!tmpdir)
+    tmpdir = getenv ("TEMP");
+  if (!tmpdir)
+    tmpdir = getenv ("TMP");
+  if (!tmpdir)
+    tmpdir = ".";
+  if (tmpdir[strlen (tmpdir) - 1] == '/'
+      || tmpdir[strlen (tmpdir) - 1] == '\\')
+    slash = "";
+#else
+  if (!tmpdir)
+    tmpdir = "/tmp";
+  if (tmpdir[strlen (tmpdir) - 1] == '/')
+    slash = "";
+#endif
+
+  char *templt = concat (tmpdir, slash, "etXXXXXX");
+  int fd = mkostemp (templt, O_CLOEXEC);
+  if (fd < 0)
+    {
+      free (templt);
+      templt = NULL;
+    }
+  else
+    close (fd);
+
+#if defined (DOS_NT)
+  /* The file name will be used in shell redirection, so it needs to have
+     DOS-style backslashes, or else the Windows shell will barf.  */
+  char *p;
+  for (p = templt; *p; p++)
+    if (*p == '/')
+      *p = '\\';
+#endif
+  return templt;
+}
+
 /* Return a newly allocated string containing the file name of FILE
    relative to the absolute directory DIR (which should end with a slash). */
 static char *
index 370d057478140b55afb584f1b59cdd3773e017a3..cabcd2c41a146afba75cc64d9f111e98d22bec16 100644 (file)
@@ -2243,12 +2243,12 @@ f-src/entry.strange_suffix,172
      & intensity1(\7f577,12231
        character*(*) function foo(\7f579,12307
 \f
-f-src/entry.strange,171
-      LOGICAL FUNCTION PRTPKG \7f2,2
-       ENTRY  SETPRT \7f193,3793
-       ENTRY  MSGSEL \7f394,8405
-     & intensity1(\7f576,12158
-       character*(*) function foo(\7f578,12234
+f-src/entry.strange,172
+      LOGICAL FUNCTION PRTPKG \7f3,75
+       ENTRY  SETPRT \7f194,3866
+       ENTRY  MSGSEL \7f395,8478
+     & intensity1(\7f577,12231
+       character*(*) function foo(\7f579,12307
 \f
 forth-src/test-forth.fth,408
 : a-forth-word \7f20,301
index b09e61e5628bcecd7a9ae50d4a168dddc826cbf9..5d4f7061e0a585f08f7fe9792a3876dcc8b4284f 100644 (file)
@@ -2810,12 +2810,12 @@ f-src/entry.strange_suffix,172
      & intensity1(\7f577,12231
        character*(*) function foo(\7f579,12307
 \f
-f-src/entry.strange,171
-      LOGICAL FUNCTION PRTPKG \7f2,2
-       ENTRY  SETPRT \7f193,3793
-       ENTRY  MSGSEL \7f394,8405
-     & intensity1(\7f576,12158
-       character*(*) function foo(\7f578,12234
+f-src/entry.strange,172
+      LOGICAL FUNCTION PRTPKG \7f3,75
+       ENTRY  SETPRT \7f194,3866
+       ENTRY  MSGSEL \7f395,8478
+     & intensity1(\7f577,12231
+       character*(*) function foo(\7f579,12307
 \f
 forth-src/test-forth.fth,408
 : a-forth-word \7f20,301
index 5a9a2bfc25b2bcc2b516665ebe2f7cd38c1a9670..1d8e34ad3e7fdaafdbaa16db6dbe4ef15f3fe782 100644 (file)
@@ -2560,12 +2560,12 @@ f-src/entry.strange_suffix,172
      & intensity1(\7f577,12231
        character*(*) function foo(\7f579,12307
 \f
-f-src/entry.strange,171
-      LOGICAL FUNCTION PRTPKG \7f2,2
-       ENTRY  SETPRT \7f193,3793
-       ENTRY  MSGSEL \7f394,8405
-     & intensity1(\7f576,12158
-       character*(*) function foo(\7f578,12234
+f-src/entry.strange,172
+      LOGICAL FUNCTION PRTPKG \7f3,75
+       ENTRY  SETPRT \7f194,3866
+       ENTRY  MSGSEL \7f395,8478
+     & intensity1(\7f577,12231
+       character*(*) function foo(\7f579,12307
 \f
 forth-src/test-forth.fth,408
 : a-forth-word \7f20,301
index f6023ea7b3d8dd128c3cb004414e3e139e741230..30ea7dcb6f7a5bc3059f5a81af3d85c28665cc7d 100644 (file)
@@ -2407,12 +2407,12 @@ f-src/entry.strange_suffix,172
      & intensity1(\7f577,12231
        character*(*) function foo(\7f579,12307
 \f
-f-src/entry.strange,171
-      LOGICAL FUNCTION PRTPKG \7f2,2
-       ENTRY  SETPRT \7f193,3793
-       ENTRY  MSGSEL \7f394,8405
-     & intensity1(\7f576,12158
-       character*(*) function foo(\7f578,12234
+f-src/entry.strange,172
+      LOGICAL FUNCTION PRTPKG \7f3,75
+       ENTRY  SETPRT \7f194,3866
+       ENTRY  MSGSEL \7f395,8478
+     & intensity1(\7f577,12231
+       character*(*) function foo(\7f579,12307
 \f
 forth-src/test-forth.fth,408
 : a-forth-word \7f20,301
index b6bb6260c757ff7af6a656b22aac2b21a48e5460..dfa261b44fb59eedfabf98ec6daf553954643222 100644 (file)
@@ -3291,12 +3291,12 @@ f-src/entry.strange_suffix,172
      & intensity1(\7f577,12231
        character*(*) function foo(\7f579,12307
 \f
-f-src/entry.strange,171
-      LOGICAL FUNCTION PRTPKG \7f2,2
-       ENTRY  SETPRT \7f193,3793
-       ENTRY  MSGSEL \7f394,8405
-     & intensity1(\7f576,12158
-       character*(*) function foo(\7f578,12234
+f-src/entry.strange,172
+      LOGICAL FUNCTION PRTPKG \7f3,75
+       ENTRY  SETPRT \7f194,3866
+       ENTRY  MSGSEL \7f395,8478
+     & intensity1(\7f577,12231
+       character*(*) function foo(\7f579,12307
 \f
 forth-src/test-forth.fth,408
 : a-forth-word \7f20,301