bug-tar
[Top][All Lists]
Advanced

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

Re: [Bug-tar] --exclude-from using process substitution fails


From: Paul Eggert
Subject: Re: [Bug-tar] --exclude-from using process substitution fails
Date: Tue, 03 Apr 2007 13:46:09 -0700
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

"Sergey Poznyakoff" <address@hidden> writes:

> (http://lists.gnu.org/archive/html/bug-tar/2006-07/msg00000.html) 

Ah, thanks, I see.  Here's a patch to solve that problem in a different
way, which doesn't involve closing everything in sight.  Does this
look reasonable?

2007-04-03  Paul Eggert  <address@hidden>

        * src/common.h (closeopen): Remove decl.
        * src/misc.c: Don't include <sys/time.h>, <sys/resource.h>; no longer
        needed.
        (get_max_open_files, closeopen): Remove.  All callers removed.
        (chdir_dir): Use a different technique, which doesn't rely on closing
        all open files.
        * src/tar.c (main): Don't call closeopen.

Index: src/common.h
===================================================================
RCS file: /cvsroot/tar/tar/src/common.h,v
retrieving revision 1.95
diff -p -u -r1.95 common.h
--- src/common.h        30 Mar 2007 19:17:44 -0000      1.95
+++ src/common.h        3 Apr 2007 20:45:52 -0000
@@ -160,7 +160,7 @@ enum exclusion_tag_type
        itself */
     exclusion_tag_under,
     /* Exclude entire directory  */
-    exclusion_tag_all,   
+    exclusion_tag_all,
   };
 
 /* Specified value to be put into tar file in place of stat () results, or
@@ -592,7 +592,6 @@ void undo_last_backup (void);
 
 int deref_stat (bool deref, char const *name, struct stat *buf);
 
-void closeopen (void);
 int chdir_arg (char const *dir);
 void chdir_do (int dir);
 
Index: src/misc.c
===================================================================
RCS file: /cvsroot/tar/tar/src/misc.c,v
retrieving revision 1.37
diff -p -u -r1.37 misc.c
--- src/misc.c  12 Dec 2006 23:56:24 -0000      1.37
+++ src/misc.c  3 Apr 2007 20:45:52 -0000
@@ -18,8 +18,6 @@
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include <system.h>
-#include <sys/time.h>
-#include <sys/resource.h>
 #include <rmt.h>
 #include "common.h"
 #include <quotearg.h>
@@ -577,42 +575,12 @@ chdir_arg (char const *dir)
   return wds++;
 }
 
-/* Return maximum number of open files */
-int
-get_max_open_files ()
-{
-#if defined _SC_OPEN_MAX
-  return sysconf (_SC_OPEN_MAX);
-#elif defined RLIMIT_NOFILE
-  struct rlimit rlim;
-
-  if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
-    return rlim.rlim_max;
-  return -1;
-#elif defined HAVE_GETDTABLESIZE
-  return getdtablesize ();
-#else
-  return -1;
-#endif
-}
-
-/* Close all descriptors, except the first three */
-void
-closeopen ()
-{
-  int i;
-
-  for (i = get_max_open_files () - 1; i > 2; i--)
-    close (i);
-}
-
 /* Change to directory I.  If I is 0, change to the initial working
    directory; otherwise, I must be a value returned by chdir_arg.  */
 void
 chdir_do (int i)
 {
   static int previous;
-  static int saved_count;
 
   if (previous != i)
     {
@@ -621,17 +589,30 @@ chdir_do (int i)
 
       if (! prev->saved)
        {
+         int err = 0;
          prev->saved = 1;
-         saved_count++;
-         /* Make sure we still have at least one descriptor available */
-         if (saved_count >= get_max_open_files () - 4)
+         if (save_cwd (&prev->saved_cwd) != 0)
+           err = errno;
+         else if (0 <= prev->saved_cwd.desc)
            {
-             /* Force restore_cwd to use chdir_long */
-             prev->saved_cwd.desc = -1;
-             prev->saved_cwd.name = xgetcwd ();
+             /* Make sure we still have at least one descriptor available.  */
+             int fd1 = prev->saved_cwd.desc;
+             int fd2 = dup (fd1);
+             if (0 <= fd2)
+               close (fd2);
+             else if (errno == EMFILE)
+               {
+                 /* Force restore_cwd to use chdir_long.  */
+                 close (fd1);
+                 prev->saved_cwd.desc = -1;
+                 prev->saved_cwd.name = xgetcwd ();
+               }
+             else
+               err = errno;
            }
-         else if (save_cwd (&prev->saved_cwd) != 0)
-           FATAL_ERROR ((0, 0, _("Cannot save working directory")));
+
+         if (err)
+           FATAL_ERROR ((0, err, _("Cannot save working directory")));
        }
 
       if (curr->saved)
Index: src/tar.c
===================================================================
RCS file: /cvsroot/tar/tar/src/tar.c,v
retrieving revision 1.166
diff -p -u -r1.166 tar.c
--- src/tar.c   3 Apr 2007 12:18:40 -0000       1.166
+++ src/tar.c   3 Apr 2007 20:45:52 -0000
@@ -617,7 +617,7 @@ static struct argp_option options[] = {
    N_("exclude directories containing CACHEDIR.TAG"), GRID+1 },
   {"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
    N_("exclude contents of directories containing FILE, except"
-      " for FILE itself"), GRID+1 }, 
+      " for FILE itself"), GRID+1 },
   {"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
    N_("exclude everything under directories containing FILE"), GRID+1 },
   {"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
@@ -1539,15 +1539,15 @@ parse_opt (int key, char *arg, struct ar
     case EXCLUDE_TAG_OPTION:
       add_exclusion_tag (arg, exclusion_tag_contents, NULL);
       break;
-      
+
     case EXCLUDE_TAG_UNDER_OPTION:
       add_exclusion_tag (arg, exclusion_tag_under, NULL);
       break;
-      
+
     case EXCLUDE_TAG_ALL_OPTION:
       add_exclusion_tag (arg, exclusion_tag_all, NULL);
       break;
-      
+
     case FORCE_LOCAL_OPTION:
       force_local_option = true;
       break;
@@ -2320,9 +2320,6 @@ main (int argc, char **argv)
 
   decode_options (argc, argv);
 
-  /* Close all inherited open descriptors, except for the first three */
-  closeopen ();
-
   name_init ();
 
   /* Main command execution.  */




reply via email to

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